From de1368275381c8a1511574759113d5813990ba64 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Apr 2022 12:53:28 +0200 Subject: [PATCH 01/38] [core] Support #text and #comment nodes --- .../pmd/lang/ast/xpath/saxon/ElementNode.java | 22 ++++++++++++-- .../pmd/lang/html/HtmlXPathRuleTest.java | 30 +++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java index e9341542ea..ce9604fe79 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java @@ -61,7 +61,7 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { Node node, int siblingPosition, NamePool namePool) { - super(Type.ELEMENT, namePool, node.getXPathNodeName(), parent); + super(determineType(node), namePool, node.getXPathNodeName(), parent); this.document = document; this.parent = parent; @@ -80,6 +80,16 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { document.nodeToElementNode.put(node, this); } + private static short determineType(Node node) { + String name = node.getXPathNodeName(); + if ("#text".equals(name)) { + return Type.TEXT; + } else if ("#comment".equals(name)) { + return Type.COMMENT; + } + return Type.ELEMENT; + } + private Map getAttributes() { if (attributes == null) { attributes = new HashMap<>(); @@ -147,10 +157,18 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { } @Override - public CharSequence getStringValueCS() { + public String getStringValue() { + if (determineType(getUnderlyingNode()) == Type.TEXT) { + return getUnderlyingNode().getImage(); + } return ""; } + @Override + public CharSequence getStringValueCS() { + return getStringValue(); + } + @Override public int compareOrder(NodeInfo other) { int result; diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java index 6c2c53e2f9..1a70e5c0fc 100644 --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java @@ -24,19 +24,22 @@ public class HtmlXPathRuleTest { private static final String LIGHTNING_WEB_COMPONENT = "\n" + ""; @Test public void selectTextNode() { // from https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.js_props_getter // "Don’t add spaces around the property, for example, { data } is not valid HTML." - String xpath = "//*[local-name() = '#text'][contains(@Text, '{ ')]"; + String xpath = "//text()[contains(., '{ ')]"; Report report = runXPath(LIGHTNING_WEB_COMPONENT, xpath); Assert.assertEquals(1, report.getViolations().size()); @@ -54,6 +57,27 @@ public class HtmlXPathRuleTest { Assert.assertEquals(4, report.getViolations().get(0).getBeginLine()); } + @Test + public void selectAttributesMultiple() { + // from https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.js_props_getter + // "Don’t add spaces around the property, for example, { data } is not valid HTML." + String xpath = "//*[@*[local-name() = ('value', 'onchange')] = '{']"; + + Report report = runXPath(LIGHTNING_WEB_COMPONENT, xpath); + Assert.assertEquals(2, report.getViolations().size()); + Assert.assertEquals(4, report.getViolations().get(0).getBeginLine()); + Assert.assertEquals(6, report.getViolations().get(1).getBeginLine()); + } + + @Test + public void selectAttributeByName() { + String xpath = "//*[@*[local-name() = 'if:true']]"; + + Report report = runXPath(LIGHTNING_WEB_COMPONENT, xpath); + Assert.assertEquals(1, report.getViolations().size()); + Assert.assertEquals(10, report.getViolations().get(0).getBeginLine()); + } + private Report runXPath(String html, String xpath) { LanguageVersion htmlLanguage = LanguageRegistry.findLanguageByTerseName(HtmlLanguageModule.TERSE_NAME).getDefaultVersion(); Parser parser = htmlLanguage.getLanguageVersionHandler().getParser(htmlLanguage.getLanguageVersionHandler().getDefaultParserOptions()); From 98f44b7e3f4abe75112361b5aa92a5db76db7603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 16:00:25 +0200 Subject: [PATCH 02/38] Allow Phonetic Extensions block in java Fix #3423 --- pmd-java/etc/grammar/Java.jjt | 4 ++-- .../pmd/lang/java/ast/ParserCornersTest.java | 6 ++++++ .../pmd/lang/java/ast/UnicodeIndent.java | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index e9eaacf5e5..f455a765e6 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -953,7 +953,7 @@ TOKEN : "\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a", "\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea", "\u1780"-"\u17b3","\u17db","\u1820"-"\u1877","\u1880"-"\u18a8","\u1e00"-"\u1e9b", - "\u1ea0"-"\u1ef9","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", + "\u1ea0"-"\u1ef9","\u1d00"-"\u1d7f","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", "\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3", "\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u203f"-"\u2040", @@ -1022,7 +1022,7 @@ TOKEN : "\u12f0"-"\u130e","\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346", "\u1348"-"\u135a","\u1369"-"\u1371","\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676", "\u1681"-"\u169a","\u16a0"-"\u16ea","\u1780"-"\u17d3","\u17db","\u17e0"-"\u17e9", - "\u180b"-"\u180e","\u1810"-"\u1819","\u1820"-"\u1877","\u1880"-"\u18a9","\u1e00"-"\u1e9b", + "\u180b"-"\u180e","\u1810"-"\u1819","\u1820"-"\u1877","\u1880"-"\u18a9","\u1d00"-"\u1d7f","\u1e00"-"\u1e9b", "\u1ea0"-"\u1ef9","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", "\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3", 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 ef40440835..8f513b2690 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 @@ -128,6 +128,12 @@ public class ParserCornersTest { java7.parse(GENERICS_PROBLEM); } + @Test + public void testUnicodeIndent() { + // https://github.com/pmd/pmd/issues/3423 + java7.parseResource("UnicodeIndent.java"); + } + @Test public void testParsersCases15() { java5.parseResource("ParserCornerCases.java"); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java new file mode 100644 index 0000000000..d6cbab3b84 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java @@ -0,0 +1,18 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +// https://github.com/pmd/pmd/issues/3423 + +package com.example.pmdtest; + +public class PmdTest { + + private static final int lᵤ = 1; + private static final int μᵤ = 2; + + public static void main(String[] args) { + System.out.println(lᵤ + μᵤ); + } + +} From b328bc5fdc543f8605a99b8fc65251006bd7639f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 17:47:06 +0200 Subject: [PATCH 03/38] Add more cjk and exotic scripts, also to JS Fix #2605 --- pmd-java/etc/grammar/Java.jjt | 3 ++- pmd-javascript/etc/grammar/es5.jj | 7 +++---- .../pmd/lang/ecmascript/ast/EcmascriptParserTest.java | 10 ++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index f455a765e6..004a571453 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -961,7 +961,7 @@ TOKEN : "\u2124","\u2126","\u2128","\u212a"-"\u212d","\u212f"-"\u2131","\u2133"-"\u2139", "\u2160"-"\u2183","\u3005"-"\u3007","\u3021"-"\u3029","\u3031"-"\u3035","\u3038"-"\u303a", "\u3041"-"\u3094","\u309d"-"\u309e","\u30a1"-"\u30fe","\u3105"-"\u312c","\u3131"-"\u318e", - "\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c","\uac00"-"\ud7a3", + "\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c","\ua490"-"\uabff","\uac00"-"\ud7a3", "\uf900"-"\ufa2d","\ufb00"-"\ufb06","\ufb13"-"\ufb17","\ufb1d","\ufb1f"-"\ufb28", "\ufb2a"-"\ufb36","\ufb38"-"\ufb3c","\ufb3e","\ufb40"-"\ufb41","\ufb43"-"\ufb44", "\ufb46"-"\ufbb1","\ufbd3"-"\ufd3d","\ufd50"-"\ufd8f","\ufd92"-"\ufdc7","\ufdf0"-"\ufdfb", @@ -1033,6 +1033,7 @@ TOKEN : "\u2160"-"\u2183","\u3005"-"\u3007","\u3021"-"\u302f","\u3031"-"\u3035","\u3038"-"\u303a", "\u3041"-"\u3094","\u3099"-"\u309a","\u309d"-"\u309e","\u30a1"-"\u30fe","\u3105"-"\u312c", "\u3131"-"\u318e","\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c", + "\ua490"-"\uabff", "\uac00"-"\ud7a3","\uf900"-"\ufa2d","\ufb00"-"\ufb06","\ufb13"-"\ufb17","\ufb1d"-"\ufb28", "\ufb2a"-"\ufb36","\ufb38"-"\ufb3c","\ufb3e","\ufb40"-"\ufb41","\ufb43"-"\ufb44", "\ufb46"-"\ufbb1","\ufbd3"-"\ufd3d","\ufd50"-"\ufd8f","\ufd92"-"\ufdc7","\ufdf0"-"\ufdfb", diff --git a/pmd-javascript/etc/grammar/es5.jj b/pmd-javascript/etc/grammar/es5.jj index 688692d61d..9e2b28be82 100644 --- a/pmd-javascript/etc/grammar/es5.jj +++ b/pmd-javascript/etc/grammar/es5.jj @@ -534,11 +534,10 @@ TOKEN : "\u31A0"-"\u31B7", "\u3400", "\u4DB5", - "\u4E00", - "\u9FA5", + "\u4E00"-"\u9EA5", "\uA000"-"\uA48C", - "\uAC00", - "\uD7A3", + "\uA490"-"\uABFF", + "\uAC00"-"\ud7AF", "\uF900"-"\uFA2D", "\uFB00"-"\uFB06", "\uFB13"-"\uFB17", 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 f6fe15ce3f..73a066e41a 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 @@ -183,6 +183,16 @@ public class EcmascriptParserTest extends EcmascriptParserTestBase { assertEquals("^=", infix.getImage()); } + @Test + public void testUnicodeCjk() { + // the first is u+4F60 + js.parse("import { Test } from 'test2'\n" + + "define('element', class extends Test {\n" + + " \n" + + " }\n" + + "})"); + } + /** * [javascript] Failing with OutOfMemoryError parsing a Javascript file #2081 */ From 71b936282854eacc008a4e2dfffea28bace0935a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 17:51:38 +0200 Subject: [PATCH 04/38] [python] unicode support Fix #2604 --- pmd-python/etc/grammar/python.jj | 52 ++++++++++++++++++- .../pmd/cpd/PythonTokenizerTest.java | 5 ++ .../python/cpd/testdata/sample_unicode.py | 4 ++ .../python/cpd/testdata/sample_unicode.txt | 13 +++++ 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.py create mode 100644 pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt diff --git a/pmd-python/etc/grammar/python.jj b/pmd-python/etc/grammar/python.jj index 1f97f9d948..5ca99e7331 100644 --- a/pmd-python/etc/grammar/python.jj +++ b/pmd-python/etc/grammar/python.jj @@ -133,7 +133,57 @@ TOKEN : /* KEYWORDS */ TOKEN : /* Python identifiers */ { < NAME: ( | )* > -| < #LETTER: ["_","a"-"z","A"-"Z"] > +| < #LETTER : ["$","A"-"Z","_","a"-"z","\u00a2"-"\u00a5","\u00aa","\u00b5","\u00ba", + "\u00c0"-"\u00d6","\u00d8"-"\u00f6","\u00f8"-"\u021f","\u0222"-"\u0233","\u0250"-"\u02ad", + "\u02b0"-"\u02b8","\u02bb"-"\u02c1","\u02d0"-"\u02d1","\u02e0"-"\u02e4","\u02ee","\u037a", + "\u0386","\u0388"-"\u038a","\u038c","\u038e"-"\u03a1","\u03a3"-"\u03ce","\u03d0"-"\u03d7", + "\u03da"-"\u03f3","\u0400"-"\u0481","\u048c"-"\u04c4","\u04c7"-"\u04c8","\u04cb"-"\u04cc", + "\u04d0"-"\u04f5","\u04f8"-"\u04f9","\u0531"-"\u0556","\u0559","\u0561"-"\u0587", + "\u05d0"-"\u05ea","\u05f0"-"\u05f2","\u0621"-"\u063a","\u0640"-"\u064a","\u0671"-"\u06d3", + "\u06d5","\u06e5"-"\u06e6","\u06fa"-"\u06fc","\u0710","\u0712"-"\u072c","\u0780"-"\u07a5", + "\u0905"-"\u0939","\u093d","\u0950","\u0958"-"\u0961","\u0985"-"\u098c","\u098f"-"\u0990", + "\u0993"-"\u09a8","\u09aa"-"\u09b0","\u09b2","\u09b6"-"\u09b9","\u09dc"-"\u09dd", + "\u09df"-"\u09e1","\u09f0"-"\u09f3","\u0a05"-"\u0a0a","\u0a0f"-"\u0a10","\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30","\u0a32"-"\u0a33","\u0a35"-"\u0a36","\u0a38"-"\u0a39","\u0a59"-"\u0a5c", + "\u0a5e","\u0a72"-"\u0a74","\u0a85"-"\u0a8b","\u0a8d","\u0a8f"-"\u0a91","\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0","\u0ab2"-"\u0ab3","\u0ab5"-"\u0ab9","\u0abd","\u0ad0","\u0ae0", + "\u0b05"-"\u0b0c","\u0b0f"-"\u0b10","\u0b13"-"\u0b28","\u0b2a"-"\u0b30","\u0b32"-"\u0b33", + "\u0b36"-"\u0b39","\u0b3d","\u0b5c"-"\u0b5d","\u0b5f"-"\u0b61","\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90","\u0b92"-"\u0b95","\u0b99"-"\u0b9a","\u0b9c","\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4","\u0ba8"-"\u0baa","\u0bae"-"\u0bb5","\u0bb7"-"\u0bb9","\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10","\u0c12"-"\u0c28","\u0c2a"-"\u0c33","\u0c35"-"\u0c39","\u0c60"-"\u0c61", + "\u0c85"-"\u0c8c","\u0c8e"-"\u0c90","\u0c92"-"\u0ca8","\u0caa"-"\u0cb3","\u0cb5"-"\u0cb9", + "\u0cde","\u0ce0"-"\u0ce1","\u0d05"-"\u0d0c","\u0d0e"-"\u0d10","\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39","\u0d60"-"\u0d61","\u0d85"-"\u0d96","\u0d9a"-"\u0db1","\u0db3"-"\u0dbb", + "\u0dbd","\u0dc0"-"\u0dc6","\u0e01"-"\u0e30","\u0e32"-"\u0e33","\u0e3f"-"\u0e46", + "\u0e81"-"\u0e82","\u0e84","\u0e87"-"\u0e88","\u0e8a","\u0e8d","\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f","\u0ea1"-"\u0ea3","\u0ea5","\u0ea7","\u0eaa"-"\u0eab","\u0ead"-"\u0eb0", + "\u0eb2"-"\u0eb3","\u0ebd","\u0ec0"-"\u0ec4","\u0ec6","\u0edc"-"\u0edd","\u0f00", + "\u0f40"-"\u0f47","\u0f49"-"\u0f6a","\u0f88"-"\u0f8b","\u1000"-"\u1021","\u1023"-"\u1027", + "\u1029"-"\u102a","\u1050"-"\u1055","\u10a0"-"\u10c5","\u10d0"-"\u10f6","\u1100"-"\u1159", + "\u115f"-"\u11a2","\u11a8"-"\u11f9","\u1200"-"\u1206","\u1208"-"\u1246","\u1248", + "\u124a"-"\u124d","\u1250"-"\u1256","\u1258","\u125a"-"\u125d","\u1260"-"\u1286","\u1288", + "\u128a"-"\u128d","\u1290"-"\u12ae","\u12b0","\u12b2"-"\u12b5","\u12b8"-"\u12be","\u12c0", + "\u12c2"-"\u12c5","\u12c8"-"\u12ce","\u12d0"-"\u12d6","\u12d8"-"\u12ee","\u12f0"-"\u130e", + "\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a", + "\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea", + "\u1780"-"\u17b3","\u17db","\u1820"-"\u1877","\u1880"-"\u18a8","\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9","\u1d00"-"\u1d7f","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u203f"-"\u2040", + "\u207f","\u20a0"-"\u20af","\u2102","\u2107","\u210a"-"\u2113","\u2115","\u2119"-"\u211d", + "\u2124","\u2126","\u2128","\u212a"-"\u212d","\u212f"-"\u2131","\u2133"-"\u2139", + "\u2160"-"\u2183","\u3005"-"\u3007","\u3021"-"\u3029","\u3031"-"\u3035","\u3038"-"\u303a", + "\u3041"-"\u3094","\u309d"-"\u309e","\u30a1"-"\u30fe","\u3105"-"\u312c","\u3131"-"\u318e", + "\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c","\ua490"-"\uabff","\uac00"-"\ud7a3", + "\uf900"-"\ufa2d","\ufb00"-"\ufb06","\ufb13"-"\ufb17","\ufb1d","\ufb1f"-"\ufb28", + "\ufb2a"-"\ufb36","\ufb38"-"\ufb3c","\ufb3e","\ufb40"-"\ufb41","\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1","\ufbd3"-"\ufd3d","\ufd50"-"\ufd8f","\ufd92"-"\ufdc7","\ufdf0"-"\ufdfb", + "\ufe33"-"\ufe34","\ufe4d"-"\ufe4f","\ufe69","\ufe70"-"\ufe72","\ufe74","\ufe76"-"\ufefc", + "\uff04","\uff21"-"\uff3a","\uff3f","\uff41"-"\uff5a","\uff65"-"\uffbe","\uffc2"-"\uffc7", + "\uffca"-"\uffcf","\uffd2"-"\uffd7","\uffda"-"\uffdc","\uffe0"-"\uffe1","\uffe5"-"\uffe6"]> + } diff --git a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java index 254b8cdbe8..ad15fbe661 100644 --- a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java +++ b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java @@ -42,6 +42,11 @@ public class PythonTokenizerTest extends CpdTextComparisonTest { doTest("backticks"); } + @Test + public void testUnicode() { + doTest("sample_unicode"); + } + @Test public void testTabWidth() { doTest("tabWidth"); diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.py b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.py new file mode 100644 index 0000000000..b0143e7e1a --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.py @@ -0,0 +1,4 @@ +# note: add more examples here when bugs arise + +def check(): + total_cost_μs = [] # https://github.com/pmd/pmd/issues/2604 diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt new file mode 100644 index 0000000000..9476d45ba4 --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L3 + [def] 1 3 + [check] 5 9 + [(] 10 10 + [)] 11 11 + [:] 12 12 +L4 + [total_cost_μs] 5 17 + [=] 19 19 + [\[] 21 21 + [\]] 22 22 +EOF From 669f2fecbd36025ddba0661ccd6378f4d56e4cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 17:58:52 +0200 Subject: [PATCH 05/38] Same for go Fix #2752 --- .../sourceforge/pmd/lang/go/antlr4/Golang.g4 | 7 +- .../sourceforge/pmd/cpd/GoTokenizerTest.java | 7 ++ .../lang/go/cpd/testdata/sample_unicode.go | 20 +++++ .../lang/go/cpd/testdata/sample_unicode.txt | 89 +++++++++++++++++++ 4 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.go create mode 100644 pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt diff --git a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 index 673c0b6682..4f68b09231 100644 --- a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 +++ b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 @@ -1264,11 +1264,10 @@ fragment UNICODE_LETTER | [\u31A0-\u31B7] | [\u3400] | [\u4DB5] - | [\u4E00] - | [\u9FA5] + | [\u4E00-\u9EA5] | [\uA000-\uA48C] - | [\uAC00] - | [\uD7A3] + | [\uA490-\uABFF] + | [\uAC00-\uD7AF] | [\uF900-\uFA2D] | [\uFB00-\uFB06] | [\uFB13-\uFB17] diff --git a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java index 309867e995..0a21eb2e1b 100644 --- a/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java +++ b/pmd-go/src/test/java/net/sourceforge/pmd/cpd/GoTokenizerTest.java @@ -40,4 +40,11 @@ public class GoTokenizerTest extends CpdTextComparisonTest { public void testIssue1751() { doTest("issue-1751"); } + + @Test + public void testUnicode() { + // https://github.com/pmd/pmd/issues/2752 + doTest("sample_unicode"); + } + } diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.go b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.go new file mode 100644 index 0000000000..02325f94df --- /dev/null +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.go @@ -0,0 +1,20 @@ +func main() { + //string底层是一个byte数组,因此string也可以进行切片操作 + str := "hello world"//string是不可变的 + slice := str[4:] + fmt.Println(slice) + + //若要对string进行修改需要将string修改为byte或rune的切片在操作 + //但是转为byte无法进行中文操作 + bytes := []byte(str) + bytes[2] = 'x' + str = string(bytes) + fmt.Println(str) + + //转换成rune可以对中文进行操作 + runes := []rune(str) + runes[0] = '哈' + str = string(runes) + fmt.Println(str) + +} diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt new file mode 100644 index 0000000000..f1b02aef86 --- /dev/null +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt @@ -0,0 +1,89 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [func] 1 4 + [main] 6 9 + [(] 10 10 + [)] 11 11 + [{] 13 13 +L3 + [str] 2 4 + [:=] 6 7 + ["hello world"] 9 21 +L4 + [slice] 2 6 + [:=] 8 9 + [str] 11 13 + [\[] 14 14 + [4] 15 15 + [:] 16 16 + [\]] 17 17 +L5 + [fmt] 2 4 + [.] 5 5 + [Println] 6 12 + [(] 13 13 + [slice] 14 18 + [)] 19 19 +L9 + [bytes] 2 6 + [:=] 8 9 + [\[] 11 11 + [\]] 12 12 + [byte] 13 16 + [(] 17 17 + [str] 18 20 + [)] 21 21 +L10 + [bytes] 2 6 + [\[] 7 7 + [2] 8 8 + [\]] 9 9 + [=] 11 11 + ['x'] 13 15 +L11 + [str] 2 4 + [=] 6 6 + [string] 8 13 + [(] 14 14 + [bytes] 15 19 + [)] 20 20 +L12 + [fmt] 2 4 + [.] 5 5 + [Println] 6 12 + [(] 13 13 + [str] 14 16 + [)] 17 17 +L15 + [runes] 2 6 + [:=] 8 9 + [\[] 11 11 + [\]] 12 12 + [rune] 13 16 + [(] 17 17 + [str] 18 20 + [)] 21 21 +L16 + [runes] 2 6 + [\[] 7 7 + [0] 8 8 + [\]] 9 9 + [=] 11 11 + ['哈'] 13 15 +L17 + [str] 2 4 + [=] 6 6 + [string] 8 13 + [(] 14 14 + [runes] 15 19 + [)] 20 20 +L18 + [fmt] 2 4 + [.] 5 5 + [Println] 6 12 + [(] 13 13 + [str] 14 16 + [)] 17 17 +L20 + [}] 1 1 +EOF From e6054e4b653f9f3e2fa77c27623f1a3cdbc82c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 18:09:04 +0200 Subject: [PATCH 06/38] Add another test case for java --- .../pmd/lang/java/ast/ParserCornersTest.java | 2 +- ...codeIndent.java => UnicodeIdentifier.java} | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) rename pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/{UnicodeIndent.java => UnicodeIdentifier.java} (53%) 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 8f513b2690..686e9f3c6c 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 @@ -131,7 +131,7 @@ public class ParserCornersTest { @Test public void testUnicodeIndent() { // https://github.com/pmd/pmd/issues/3423 - java7.parseResource("UnicodeIndent.java"); + java7.parseResource("UnicodeIdentifier.java"); } @Test diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIdentifier.java similarity index 53% rename from pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java rename to pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIdentifier.java index d6cbab3b84..3eae15d2a9 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIndent.java +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/UnicodeIdentifier.java @@ -16,3 +16,22 @@ public class PmdTest { } } + +enum CodeSet { + + START_CODE_A('Ë'), + START_CODE_B('Ì'), + START_CODE_C('Í'), + A_TILDE('\u00c3'), + STOP_CODE('Î'); + + private final char encoding; + + CodeSet(final char encoding) { + this.encoding = encoding; + } + + public char getEncoding() { + return encoding; + } +} From 078345fbca6970113b5b7ed17523980b30c76789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 18:16:39 +0200 Subject: [PATCH 07/38] Add phonetic extensions to other langs --- .../main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 | 1 + pmd-java/etc/grammar/Java.jjt | 2 +- pmd-javascript/etc/grammar/es5.jj | 1 + pmd-python/etc/grammar/python.jj | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 index 4f68b09231..c54605fc85 100644 --- a/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 +++ b/pmd-go/src/main/antlr4/net/sourceforge/pmd/lang/go/antlr4/Golang.g4 @@ -1215,6 +1215,7 @@ fragment UNICODE_LETTER | [\u1780-\u17B3] | [\u1820-\u1877] | [\u1880-\u18A8] + | [\u1D00-\u1DFF] | [\u1E00-\u1E9B] | [\u1EA0-\u1EE0] | [\u1EE1-\u1EF9] diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 004a571453..4e655ead41 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -953,7 +953,7 @@ TOKEN : "\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a", "\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea", "\u1780"-"\u17b3","\u17db","\u1820"-"\u1877","\u1880"-"\u18a8","\u1e00"-"\u1e9b", - "\u1ea0"-"\u1ef9","\u1d00"-"\u1d7f","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", + "\u1ea0"-"\u1ef9","\u1d00"-"\u1eef","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", "\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3", "\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u203f"-"\u2040", diff --git a/pmd-javascript/etc/grammar/es5.jj b/pmd-javascript/etc/grammar/es5.jj index 9e2b28be82..a237b0899e 100644 --- a/pmd-javascript/etc/grammar/es5.jj +++ b/pmd-javascript/etc/grammar/es5.jj @@ -488,6 +488,7 @@ TOKEN : "\u1E00"-"\u1E9B", "\u1EA0"-"\u1EE0", "\u1EE1"-"\u1EF9", + "\u1EE1"-"\u1EEF", "\u1F00"-"\u1F15", "\u1F18"-"\u1F1D", "\u1F20"-"\u1F39", diff --git a/pmd-python/etc/grammar/python.jj b/pmd-python/etc/grammar/python.jj index 5ca99e7331..41640cd724 100644 --- a/pmd-python/etc/grammar/python.jj +++ b/pmd-python/etc/grammar/python.jj @@ -168,7 +168,7 @@ TOKEN : /* Python identifiers */ "\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a", "\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea", "\u1780"-"\u17b3","\u17db","\u1820"-"\u1877","\u1880"-"\u18a8","\u1e00"-"\u1e9b", - "\u1ea0"-"\u1ef9","\u1d00"-"\u1d7f","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", + "\u1ea0"-"\u1ef9","\u1d00"-"\u1eef","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d", "\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3", "\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u203f"-"\u2040", From f80c73e44f813d300252a389546ec14e58787a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 1 May 2022 18:21:43 +0200 Subject: [PATCH 08/38] Test dollar in ident in python --- .../sourceforge/pmd/cpd/PythonTokenizerTest.java | 6 ++++++ .../pmd/lang/python/cpd/testdata/var_with_dollar.py | 2 ++ .../lang/python/cpd/testdata/var_with_dollar.txt | 13 +++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.py create mode 100644 pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt diff --git a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java index ad15fbe661..e72eb3e489 100644 --- a/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java +++ b/pmd-python/src/test/java/net/sourceforge/pmd/cpd/PythonTokenizerTest.java @@ -51,4 +51,10 @@ public class PythonTokenizerTest extends CpdTextComparisonTest { public void testTabWidth() { doTest("tabWidth"); } + + @Test + public void testVarWithDollar() { + doTest("var_with_dollar"); + } + } diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.py b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.py new file mode 100644 index 0000000000..5c42520282 --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.py @@ -0,0 +1,2 @@ +def check(): + a$a = [] diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt new file mode 100644 index 0000000000..39607ea38f --- /dev/null +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt @@ -0,0 +1,13 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [def] 1 3 + [check] 5 9 + [(] 10 10 + [)] 11 11 + [:] 12 12 +L2 + [a$a] 5 7 + [=] 9 9 + [\[] 11 11 + [\]] 12 12 +EOF From 3538c6d3bd8d7c9a74df96399219277342ecbfbc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 May 2022 15:52:12 +0200 Subject: [PATCH 09/38] [core] Improve support for #text and #comment node types --- .../pmd/lang/ast/xpath/saxon/ElementNode.java | 2 +- .../rule/xpath/saxon/ElementNodeTest.java | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java index ce9604fe79..702e6605d4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java @@ -80,7 +80,7 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { document.nodeToElementNode.put(node, this); } - private static short determineType(Node node) { + private static int determineType(Node node) { String name = node.getXPathNodeName(); if ("#text".equals(name)) { return Type.TEXT; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java index ead5c73553..756e41eb46 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/saxon/ElementNodeTest.java @@ -11,6 +11,8 @@ import net.sourceforge.pmd.lang.ast.DummyNode; import net.sourceforge.pmd.lang.ast.xpath.saxon.DocumentNode; import net.sourceforge.pmd.lang.ast.xpath.saxon.ElementNode; +import net.sf.saxon.type.Type; + public class ElementNodeTest { @Test @@ -56,4 +58,32 @@ public class ElementNodeTest { Assert.assertTrue(elementFoo1.compareOrder(elementFoo2) < 0); Assert.assertTrue(elementFoo2.compareOrder(elementFoo1) > 0); } + + @Test + public void verifyTextNodeType() { + DummyNode node = new DummyNode(1, false, "dummy"); + DummyNode foo1 = new DummyNode(2, false, "foo"); + DummyNode foo2 = new DummyNode(2, false, "#text"); + node.jjtAddChild(foo1, 0); + node.jjtAddChild(foo2, 1); + + DocumentNode document = new DocumentNode(node); + ElementNode elementFoo1 = document.nodeToElementNode.get(foo1); + ElementNode elementFoo2 = document.nodeToElementNode.get(foo2); + + Assert.assertEquals(Type.ELEMENT, elementFoo1.getNodeKind()); + Assert.assertEquals(Type.TEXT, elementFoo2.getNodeKind()); + } + + @Test + public void verifyCommentNodeType() { + DummyNode node = new DummyNode(1, false, "dummy"); + DummyNode foo = new DummyNode(2, false, "#comment"); + node.jjtAddChild(foo, 0); + + DocumentNode document = new DocumentNode(node); + ElementNode elementFoo = document.nodeToElementNode.get(foo); + + Assert.assertEquals(Type.COMMENT, elementFoo.getNodeKind()); + } } From 46727eb5d72e8dfff3d947aa1156e109ad28e8bd Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 6 May 2022 15:52:59 +0200 Subject: [PATCH 10/38] [html] Document XPath 2.0 only and text nodes handling --- docs/pages/pmd/languages/html.md | 10 ++++- .../pmd/lang/html/HtmlXPathRuleTest.java | 37 ++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/docs/pages/pmd/languages/html.md b/docs/pages/pmd/languages/html.md index acb96fc416..9c905571e1 100644 --- a/docs/pages/pmd/languages/html.md +++ b/docs/pages/pmd/languages/html.md @@ -14,5 +14,11 @@ last_updated: April 2022 (6.45.0) The HTML language module uses [jsoup](https://jsoup.org/) for parsing. -XPath rules are supported, but the DOM is not a typical XML/XPath DOM. E.g. -text nodes are normal nodes. This might change in the future. +XPath 2.0 rules are supported, but the DOM is not always a typical XML/XPath DOM. +In the Designer, text nodes appear as nodes with name "#text", but they can +be selected as usual using `text()`. + +XML Namespaces are not supported. The local name of attributes include the prefix, +so that you have to select attributes by e.g. `//*[@*[local-name() = 'if:true']]`. + +Only XPath 1.0 rules are not supported. diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java index 1a70e5c0fc..1a6272dab8 100644 --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java @@ -4,18 +4,14 @@ package net.sourceforge.pmd.lang.html; -import java.io.StringReader; -import java.util.Arrays; - import org.junit.Assert; import org.junit.Test; import net.sourceforge.pmd.Report; -import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; -import net.sourceforge.pmd.lang.Parser; -import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.html.ast.ASTHtmlComment; +import net.sourceforge.pmd.lang.html.ast.ASTHtmlDocument; +import net.sourceforge.pmd.lang.html.ast.ASTHtmlTextNode; +import net.sourceforge.pmd.lang.html.ast.HtmlParsingHelper; import net.sourceforge.pmd.lang.rule.XPathRule; import net.sourceforge.pmd.lang.rule.xpath.XPathVersion; @@ -46,6 +42,20 @@ public class HtmlXPathRuleTest { Assert.assertEquals(3, report.getViolations().get(0).getBeginLine()); } + @Test + public void verifyTextNodeName() { + ASTHtmlDocument document = HtmlParsingHelper.DEFAULT.parse("

foobar

"); + ASTHtmlTextNode textNode = document.getFirstDescendantOfType(ASTHtmlTextNode.class); + Assert.assertEquals("#text", textNode.getXPathNodeName()); + } + + @Test + public void verifyCommentNodeName() { + ASTHtmlDocument document = HtmlParsingHelper.DEFAULT.parse("

"); + ASTHtmlComment comment = document.getFirstDescendantOfType(ASTHtmlComment.class); + Assert.assertEquals("#comment", comment.getXPathNodeName()); + } + @Test public void selectAttributes() { // from https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.js_props_getter @@ -79,16 +89,9 @@ public class HtmlXPathRuleTest { } private Report runXPath(String html, String xpath) { - LanguageVersion htmlLanguage = LanguageRegistry.findLanguageByTerseName(HtmlLanguageModule.TERSE_NAME).getDefaultVersion(); - Parser parser = htmlLanguage.getLanguageVersionHandler().getParser(htmlLanguage.getLanguageVersionHandler().getDefaultParserOptions()); - XPathRule rule = new XPathRule(XPathVersion.XPATH_2_0, xpath); rule.setMessage("test"); - Node node = parser.parse("n/a", new StringReader(html)); - RuleContext context = new RuleContext(); - context.setLanguageVersion(htmlLanguage); - context.setCurrentRule(rule); - rule.apply(Arrays.asList(node), context); - return context.getReport(); + rule.setLanguage(HtmlParsingHelper.DEFAULT.getLanguage()); + return HtmlParsingHelper.DEFAULT.executeRule(rule, html); } } From 686e878caf2ccf67e998697cd06193c0fd640083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 7 May 2022 18:42:45 +0200 Subject: [PATCH 11/38] Fix #1445 - Allow CLI to take globs as parameters This doesn't interpret globs or anything, only makes the parameter parsing compatible with shell expansion. Globs are therefore available provided you use a shell with that feature --- .../net/sourceforge/pmd/PMDConfiguration.java | 48 ++++++++++++++++--- .../sourceforge/pmd/cli/PMDParameters.java | 27 +++++++---- .../pmd/cli/PmdParametersParseResult.java | 15 +++++- .../net/sourceforge/pmd/cli/CoreCliTest.java | 23 ++++++++- .../net/sourceforge/pmd/cli/FakeRuleset2.xml | 20 ++++++++ 5 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml 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 9d3c67aead..a44ec4b421 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -8,6 +8,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Properties; @@ -102,7 +103,7 @@ public class PMDConfiguration extends AbstractConfiguration { // Rule and source file options private List ruleSets = new ArrayList<>(); private RulePriority minimumPriority = RulePriority.LOW; - private String inputPaths; + private List inputPaths; private String inputUri; private String inputFilePath; private String ignoreFilePath; @@ -420,19 +421,54 @@ public class PMDConfiguration extends AbstractConfiguration { * Get the comma separated list of input paths to process for source files. * * @return A comma separated list. + * + * @deprecated Use {@link #getAllInputPaths()} */ + @Deprecated public String getInputPaths() { - return inputPaths; + return inputPaths.isEmpty() ? null : StringUtils.join(inputPaths, ","); + } + + /** + * Returns an unmodifiable list. + * + * @throws NullPointerException If the parameter is null + */ + public List getAllInputPaths() { + return Collections.unmodifiableList(inputPaths); } /** * Set the comma separated list of input paths to process for source files. * - * @param inputPaths - * The comma separated list. + * @param inputPaths The comma separated list. + * + * @throws NullPointerException If the parameter is null + * @deprecated Use {@link #setInputPaths(List)} or {@link #addInputPath(String)} */ + @Deprecated public void setInputPaths(String inputPaths) { - this.inputPaths = inputPaths; + List paths = new ArrayList<>(); + Collections.addAll(paths, inputPaths.split(",")); + this.inputPaths = paths; + } + + /** + * Set the input paths to the given list of paths. + * @throws NullPointerException If the parameter is null + */ + public void setInputPaths(List inputPaths) { + this.inputPaths = new ArrayList<>(inputPaths); + } + + /** + * Add an input path. It is not split on commas. + * + * @throws NullPointerException If the parameter is null + */ + public void addInputPath(String inputPath) { + Objects.requireNonNull(inputPath); + this.inputPaths.add(inputPath); } public String getInputFilePath() { @@ -526,7 +562,7 @@ public class PMDConfiguration extends AbstractConfiguration { Renderer renderer = RendererFactory.createRenderer(reportFormat, reportProperties); renderer.setShowSuppressedViolations(showSuppressedViolations); if (reportShortNames && inputPaths != null) { - renderer.setUseShortNames(Arrays.asList(inputPaths.split(","))); + renderer.setUseShortNames(Collections.unmodifiableList(new ArrayList<>(inputPaths))); } if (withReportWriter) { renderer.setReportFile(reportFile); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index f80dad49bd..129483ee81 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -8,6 +8,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; +import org.apache.commons.lang3.StringUtils; + import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.RulePriority; @@ -29,14 +31,15 @@ import com.beust.jcommander.validators.PositiveInteger; public class PMDParameters { @Parameter(names = { "--rulesets", "-rulesets", "-R" }, description = "Comma separated list of ruleset names to use.", - required = true) - private String rulesets; + required = true, + variableArity = true) + private List rulesets; @Parameter(names = { "--uri", "-uri", "-u" }, description = "Database URI for sources.") private String uri; - @Parameter(names = { "--dir", "-dir", "-d" }, description = "Root directory for sources.") - private String sourceDir; + @Parameter(names = { "--dir", "-dir", "-d" }, description = "Root directory for sources.", variableArity = true) + private List inputPaths; @Parameter(names = { "--file-list", "-filelist" }, description = "Path to a file containing a list of files to analyze.") private String fileListPath; @@ -192,10 +195,6 @@ public class PMDParameters { * @throws IllegalArgumentException if the parameters are inconsistent or incomplete */ public PMDConfiguration toConfiguration() { - if (null == this.getSourceDir() && null == this.getUri() && null == this.getFileListPath()) { - throw new IllegalArgumentException( - "Please provide a parameter for source root directory (-dir or -d), database URI (-uri or -u), or file list path (-filelist)."); - } PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputPaths(this.getSourceDir()); configuration.setInputFilePath(this.getFileListPath()); @@ -329,12 +328,22 @@ public class PMDParameters { return auxclasspath; } + @Deprecated public String getRulesets() { + return StringUtils.join(rulesets, ","); + } + + public List getRulesetRefs() { return rulesets; } + public List getInputPaths() { + return inputPaths; + } + + @Deprecated public String getSourceDir() { - return sourceDir; + return StringUtils.join(inputPaths, ","); } public String getFileListPath() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java index 0ffc8465d0..9f33d4e470 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java @@ -105,13 +105,26 @@ public final class PmdParametersParseResult { jcommander.setProgramName("pmd"); try { - jcommander.parse(args); + parseAndValidate(jcommander, result, args); return new PmdParametersParseResult(result, filterDeprecatedOptions(args)); } catch (ParameterException e) { return new PmdParametersParseResult(e, filterDeprecatedOptions(args)); } } + private static void parseAndValidate(JCommander jcommander, PMDParameters result, String[] args) { + jcommander.parse(args); + // jcommander has no special support for global parameter validation like this + // For consistency we report this with a ParameterException + if (null == result.getSourceDir() + && null == result.getUri() + && null == result.getFileListPath()) { + throw new ParameterException( + "Please provide a parameter for source root directory (-dir or -d), database URI (-uri or -u), or file list path (-filelist)."); + } + + } + private static Map filterDeprecatedOptions(String... args) { Map argSet = new LinkedHashMap<>(SUGGESTED_REPLACEMENT); argSet.keySet().retainAll(new HashSet<>(Arrays.asList(args))); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 157caf975d..56e7337fdf 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -40,6 +40,7 @@ import net.sourceforge.pmd.junit.JavaUtilLoggingRule; public class CoreCliTest { private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml"; + private static final String DUMMY_RULESET2 = "net/sourceforge/pmd/cli/FakeRuleset2.xml"; private static final String STRING_TO_REPLACE = "__should_be_replaced__"; @Rule @@ -54,6 +55,7 @@ public class CoreCliTest { public final SystemErrRule errStreamCaptor = new SystemErrRule(); private Path srcDir; + private Path srcDir2; @Before public void setup() throws IOException { @@ -63,8 +65,10 @@ public class CoreCliTest { // create a few files srcDir = Files.createDirectories(root.resolve("src")); + srcDir2 = Files.createDirectories(root.resolve("src2")); writeString(srcDir.resolve("someSource.dummy"), "dummy text"); - + writeString(srcDir2.resolve("someSource.dummy"), "dummy text"); + // reset logger? Logger.getLogger("net.sourceforge.pmd"); } @@ -201,6 +205,23 @@ public class CoreCliTest { assertThatErrAndOut(not(containsStringIgnoringCase("Available report formats and"))); } + @Test + public void testMultipleRulesets() { + startCapturingErrAndOut(); + runPmdSuccessfully("--no-cache", "-d", srcDir, "-R", DUMMY_RULESET, DUMMY_RULESET2); + runPmdSuccessfully("--no-cache", "-d", srcDir, "-R", DUMMY_RULESET, DUMMY_RULESET2, "--"); + // ensure -d is not considered a ruleset + runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, DUMMY_RULESET2, "-d", srcDir); + } + + @Test + public void testMultipleDirectories() { + startCapturingErrAndOut(); + runPmdSuccessfully("--no-cache", "-d", srcDir, srcDir2, "-R", DUMMY_RULESET); + runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, "-d", srcDir, srcDir2); + runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, "-d", srcDir, srcDir2, "--"); + } + private void assertThatErrAndOut(Matcher matcher) { assertThat("stdout", outStreamCaptor.getLog(), matcher); assertThat("stderr", errStreamCaptor.getLog(), matcher); diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml new file mode 100644 index 0000000000..eebe094a76 --- /dev/null +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml @@ -0,0 +1,20 @@ + + + + + Ruleset used by test RuleSetFactoryTest + + + + +Just for test + + 3 + + + + + From 06d0d6b0fba0a0fcec3b323f5da008fa1f6bc966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 7 May 2022 18:54:49 +0200 Subject: [PATCH 12/38] More tests, release notes --- docs/pages/release_notes.md | 19 ++++++ .../net/sourceforge/pmd/cli/CoreCliTest.java | 21 ------- .../pmd/cli/PMDParametersTest.java | 63 +++++++++++++++++++ .../net/sourceforge/pmd/cli/FakeRuleset2.xml | 20 ------ 4 files changed, 82 insertions(+), 41 deletions(-) delete mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c31a705241..647a57daf2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,19 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy +#### CLI improvements + +The PMD CLI now allows repeating the `--dir` (`-d`) and `--rulesets` (`-R`) options, + as well as providing several space-separated arguments to either of them. For instance: +```shell +pmd -d src/main/java src/test/java -R rset1.xml -R rset2.xml +``` +This also allows globs to be used on the CLI if your shell supports shell expansion. +For instance, the above can be written +```shell +pmd -d src/*/java -R rset*.xml +``` + ### Fixed Issues * javascript @@ -21,6 +34,12 @@ This is a {{ site.pmd.release_type }} release. ### API Changes +#### Deprecated API + +- {% jdoc core::PMDConfiguration#getInputPaths() %} and +{% jdoc core::PMDConfiguration#setInputPaths(java.lang.String) %} are now deprecated. +A new set of methods have been added, which use lists and do not rely on comma splitting. + ### External Contributions {% endtocmaker %} diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 56e7337fdf..70c140023e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -40,7 +40,6 @@ import net.sourceforge.pmd.junit.JavaUtilLoggingRule; public class CoreCliTest { private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml"; - private static final String DUMMY_RULESET2 = "net/sourceforge/pmd/cli/FakeRuleset2.xml"; private static final String STRING_TO_REPLACE = "__should_be_replaced__"; @Rule @@ -55,7 +54,6 @@ public class CoreCliTest { public final SystemErrRule errStreamCaptor = new SystemErrRule(); private Path srcDir; - private Path srcDir2; @Before public void setup() throws IOException { @@ -65,9 +63,7 @@ public class CoreCliTest { // create a few files srcDir = Files.createDirectories(root.resolve("src")); - srcDir2 = Files.createDirectories(root.resolve("src2")); writeString(srcDir.resolve("someSource.dummy"), "dummy text"); - writeString(srcDir2.resolve("someSource.dummy"), "dummy text"); // reset logger? Logger.getLogger("net.sourceforge.pmd"); } @@ -205,23 +201,6 @@ public class CoreCliTest { assertThatErrAndOut(not(containsStringIgnoringCase("Available report formats and"))); } - @Test - public void testMultipleRulesets() { - startCapturingErrAndOut(); - runPmdSuccessfully("--no-cache", "-d", srcDir, "-R", DUMMY_RULESET, DUMMY_RULESET2); - runPmdSuccessfully("--no-cache", "-d", srcDir, "-R", DUMMY_RULESET, DUMMY_RULESET2, "--"); - // ensure -d is not considered a ruleset - runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, DUMMY_RULESET2, "-d", srcDir); - } - - @Test - public void testMultipleDirectories() { - startCapturingErrAndOut(); - runPmdSuccessfully("--no-cache", "-d", srcDir, srcDir2, "-R", DUMMY_RULESET); - runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, "-d", srcDir, srcDir2); - runPmdSuccessfully("--no-cache", "-R", DUMMY_RULESET, "-d", srcDir, srcDir2, "--"); - } - private void assertThatErrAndOut(Matcher matcher) { assertThat("stdout", outStreamCaptor.getLog(), matcher); assertThat("stderr", errStreamCaptor.getLog(), matcher); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDParametersTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDParametersTest.java index 22ca614a06..40ff67955e 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDParametersTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDParametersTest.java @@ -4,10 +4,17 @@ package net.sourceforge.pmd.cli; +import static net.sourceforge.pmd.util.CollectionUtil.listOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Assert; import org.junit.Test; +import net.sourceforge.pmd.PMDConfiguration; + public class PMDParametersTest { @Test @@ -20,4 +27,60 @@ public class PMDParametersTest { FieldUtils.writeDeclaredField(parameters, "language", "dummy2", true); Assert.assertEquals("1.0", parameters.getVersion()); } + + @Test + public void testMultipleDirsAndRuleSets() { + PmdParametersParseResult result = PmdParametersParseResult.extractParameters( + "-d", "a", "b", "-R", "x.xml", "y.xml" + ); + assertMultipleDirsAndRulesets(result); + } + + @Test + public void testMultipleDirsAndRuleSetsWithCommas() { + PmdParametersParseResult result = PmdParametersParseResult.extractParameters( + "-d", "a,b", "-R", "x.xml,y.xml" + ); + assertMultipleDirsAndRulesets(result); + } + + @Test + public void testMultipleDirsAndRuleSetsWithRepeatedOption() { + PmdParametersParseResult result = PmdParametersParseResult.extractParameters( + "-d", "a", "-d", "b", "-R", "x.xml", "-R", "y.xml" + ); + assertMultipleDirsAndRulesets(result); + } + + @Test + public void testNoPositionalParametersAllowed() { + assertError( + // vvvv + "-R", "x.xml", "-d", "a", "--", "-d", "b" + ); + } + + + private void assertMultipleDirsAndRulesets(PmdParametersParseResult result) { + assertFalse(result.isError()); + PMDConfiguration config = result.toConfiguration(); + assertEquals(config.getAllInputPaths(), listOf("a", "b")); + assertEquals(config.getRuleSetPaths(), listOf("x.xml", "y.xml")); + } + + @Test + public void testEmptyDirOption() { + assertError("-d", "-R", "y.xml"); + } + + @Test + public void testEmptyRulesetOption() { + assertError("-R", "-d", "something"); + } + + private void assertError(String... params) { + PmdParametersParseResult result = PmdParametersParseResult.extractParameters(params); + assertTrue(result.isError()); + } + } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml deleted file mode 100644 index eebe094a76..0000000000 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Ruleset used by test RuleSetFactoryTest - - - - -Just for test - - 3 - - - - - From e7229407d4ed061910a84633a09057f4b73f1e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 7 May 2022 19:29:00 +0200 Subject: [PATCH 13/38] Fix tests --- .../net/sourceforge/pmd/PMDConfiguration.java | 2 +- .../sourceforge/pmd/cli/PMDParameters.java | 2 +- .../pmd/cli/PmdParametersParseResult.java | 7 ++- .../pmd/it/BinaryDistributionIT.java | 43 +++++++++++-------- 4 files changed, 33 insertions(+), 21 deletions(-) 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 a44ec4b421..ad3b9603c1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -103,7 +103,7 @@ public class PMDConfiguration extends AbstractConfiguration { // Rule and source file options private List ruleSets = new ArrayList<>(); private RulePriority minimumPriority = RulePriority.LOW; - private List inputPaths; + private List inputPaths = new ArrayList<>(); private String inputUri; private String inputFilePath; private String ignoreFilePath; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 129483ee81..fd4c8408e1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -39,7 +39,7 @@ public class PMDParameters { private String uri; @Parameter(names = { "--dir", "-dir", "-d" }, description = "Root directory for sources.", variableArity = true) - private List inputPaths; + private List inputPaths = new ArrayList<>(); @Parameter(names = { "--file-list", "-filelist" }, description = "Path to a file containing a list of files to analyze.") private String fileListPath; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java index 9f33d4e470..2f863ba4d9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java @@ -114,13 +114,16 @@ public final class PmdParametersParseResult { private static void parseAndValidate(JCommander jcommander, PMDParameters result, String[] args) { jcommander.parse(args); + if (result.isHelp() || result.isVersion()) { + return; + } // jcommander has no special support for global parameter validation like this // For consistency we report this with a ParameterException - if (null == result.getSourceDir() + if (result.getInputPaths().isEmpty() && null == result.getUri() && null == result.getFileListPath()) { throw new ParameterException( - "Please provide a parameter for source root directory (-dir or -d), database URI (-uri or -u), or file list path (-filelist)."); + "Please provide a parameter for source root directory (--dir or -d), database URI (--uri or -u), or file list path (--file-list)."); } } diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java index 48c9bc3ee3..fdb2a97706 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java @@ -36,6 +36,8 @@ public class BinaryDistributionIT extends AbstractBinaryDistributionTest { } } + private final String srcDir = new File(".", "src/test/resources/sample-source/java/").getAbsolutePath(); + @Test public void testFileExistence() { assertTrue(getBinaryDistribution().exists()); @@ -75,27 +77,34 @@ public class BinaryDistributionIT extends AbstractBinaryDistributionTest { } @Test - public void runPMD() throws Exception { - String srcDir = new File(".", "src/test/resources/sample-source/java/").getAbsolutePath(); + public void testPmdJavaQuickstart() throws Exception { + ExecutionResult result = PMDExecutor.runPMDRules(folder.newFile().toPath(), tempDir, srcDir, "rulesets/java/quickstart.xml"); + result.assertExecutionResult(4, ""); + } - ExecutionResult result; - - result = PMDExecutor.runPMD(tempDir); // without any argument, display usage help and error - result.assertExecutionResultErrOutput(1, CliMessages.runWithHelpFlagMessage()); - - result = PMDExecutor.runPMD(tempDir, "-h"); - result.assertExecutionResult(0, SUPPORTED_LANGUAGES_PMD); - - result = PMDExecutor.runPMDRules(folder.newFile().toPath(), tempDir, srcDir, "src/test/resources/rulesets/sample-ruleset.xml"); - result.assertExecutionResult(4, "", "JumbledIncrementer.java:8:"); - - // also test XML format - result = PMDExecutor.runPMDRules(folder.newFile().toPath(), tempDir, srcDir, "src/test/resources/rulesets/sample-ruleset.xml", "xml"); + @Test + public void testPmdXmlFormat() throws Exception { + ExecutionResult result = PMDExecutor.runPMDRules(folder.newFile().toPath(), tempDir, srcDir, "src/test/resources/rulesets/sample-ruleset.xml", "xml"); result.assertExecutionResult(4, "", "JumbledIncrementer.java\">"); result.assertExecutionResult(4, "", " Date: Sat, 7 May 2022 19:33:29 +0200 Subject: [PATCH 14/38] 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 647a57daf2..9c87026392 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -29,6 +29,8 @@ pmd -d src/*/java -R rset*.xml ### Fixed Issues +* cli + * [#1445](https://github.com/pmd/pmd/issues/1445): \[core] Allow CLI to take globs as parameters * javascript * [#3948](https://github.com/pmd/pmd/issues/3948): \[js] Invalid operator error for method property in object literal From 5657559026f5d7584b35172b87b9eff4d860c89a Mon Sep 17 00:00:00 2001 From: Per Abich Date: Sun, 8 May 2022 11:55:20 +0200 Subject: [PATCH 15/38] Fixed #3954 and wrote test confirming it. --- .../bestpractices/UseCollectionIsEmptyRule.java | 15 ++++----------- .../bestpractices/xml/UseCollectionIsEmpty.xml | 13 +++++++++++++ 2 files changed, 17 insertions(+), 11 deletions(-) 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 27974ec845..5ddf60c787 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 @@ -12,17 +12,7 @@ import java.util.List; import java.util.Map; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody; -import net.sourceforge.pmd.lang.java.ast.ASTEnumBody; -import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; -import net.sourceforge.pmd.lang.java.ast.ASTName; -import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; -import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; -import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; -import net.sourceforge.pmd.lang.java.ast.ASTResultType; -import net.sourceforge.pmd.lang.java.ast.ASTType; -import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; -import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; +import net.sourceforge.pmd.lang.java.ast.*; import net.sourceforge.pmd.lang.java.rule.AbstractInefficientZeroCheck; import net.sourceforge.pmd.lang.java.symboltable.ClassScope; import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence; @@ -124,6 +114,9 @@ public class UseCollectionIsEmptyRule extends AbstractInefficientZeroCheck { if (classOrEnumBody == null) { classOrEnumBody = expr.getFirstParentOfType(ASTEnumBody.class); } + if (classOrEnumBody == null) { + classOrEnumBody = expr.getFirstParentOfType(ASTRecordBody.class); + } List varDeclarators = classOrEnumBody.findDescendantsOfType(ASTVariableDeclarator.class); for (ASTVariableDeclarator varDeclarator : varDeclarators) { if (varDeclarator.getName().equals(varName)) { 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 77e39ab95d..5e5439f3ff 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 @@ -489,4 +489,17 @@ public class Foo { } ]]> + + With records + 0 + stringSet) { + + public boolean hasMoreThanOneItem() { + return this.stringSet.size() > 1; + } +} ]]> + From 418fe220b9ab541ba06a2b7b0fec3f7d25602e70 Mon Sep 17 00:00:00 2001 From: Per Abich Date: Sun, 8 May 2022 12:45:40 +0200 Subject: [PATCH 16/38] Fixed #3954 missing reporting of issue on records. --- .../bestpractices/UseCollectionIsEmptyRule.java | 8 +++++++- .../bestpractices/xml/UseCollectionIsEmpty.xml | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) 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 5ddf60c787..d0abde1db2 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 @@ -115,7 +115,13 @@ public class UseCollectionIsEmptyRule extends AbstractInefficientZeroCheck { classOrEnumBody = expr.getFirstParentOfType(ASTEnumBody.class); } if (classOrEnumBody == null) { - classOrEnumBody = expr.getFirstParentOfType(ASTRecordBody.class); + classOrEnumBody = expr.getFirstParentOfType(ASTRecordDeclaration.class); + List descendantsOfType = classOrEnumBody.findDescendantsOfType(ASTVariableDeclaratorId.class); + for (ASTVariableDeclaratorId variableDeclaratorId : descendantsOfType) { + if (variableDeclaratorId.getName().equals(varName)) { + return variableDeclaratorId.getTypeNode().getTypeDefinition(); + } + } } List varDeclarators = classOrEnumBody.findDescendantsOfType(ASTVariableDeclarator.class); for (ASTVariableDeclarator varDeclarator : varDeclarators) { 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 5e5439f3ff..d296c995dc 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 @@ -500,6 +500,20 @@ public record Record(Set stringSet) { public boolean hasMoreThanOneItem() { return this.stringSet.size() > 1; } +} ]]> + + + With records and size check + 1 + 6 + stringSet) { + + public boolean hasMoreThanOneItem() { + return this.stringSet.size() == 0; + } } ]]> From f85a635669de95234f027ea1b6a1681d91abd529 Mon Sep 17 00:00:00 2001 From: Per Abich Date: Sun, 8 May 2022 13:02:15 +0200 Subject: [PATCH 17/38] Fixed checkstyle violations --- .../bestpractices/UseCollectionIsEmptyRule.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 d0abde1db2..c1cc304e6a 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 @@ -12,7 +12,18 @@ import java.util.List; import java.util.Map; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.java.ast.*; +import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody; +import net.sourceforge.pmd.lang.java.ast.ASTEnumBody; +import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTName; +import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; +import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; +import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; +import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTResultType; +import net.sourceforge.pmd.lang.java.ast.ASTType; +import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; +import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.lang.java.rule.AbstractInefficientZeroCheck; import net.sourceforge.pmd.lang.java.symboltable.ClassScope; import net.sourceforge.pmd.lang.java.symboltable.JavaNameOccurrence; From 8d7074dbaa5d2ce5d921788a5cdac401f01e3161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 8 May 2022 15:17:40 +0200 Subject: [PATCH 18/38] Improve doc for parameters --- docs/pages/pmd/userdocs/cli_reference.md | 10 ++--- docs/pages/release_notes.md | 1 + .../sourceforge/pmd/cli/PMDParameters.java | 42 +++++++++++++++---- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 0a27287864..69a29d966d 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -76,14 +76,14 @@ The tool comes with a rather extensive help text, simply running with `--help`! %} {% include custom/cli_option_row.html options="--file-list" option_arg="filepath" - description="Path to file containing a comma delimited list of files to analyze. + description="Path to file containing a list of files to analyze, one path per line. If this is given, then you don't need to provide `--dir`." %} {% 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 - filenames. When using this option, the automatic language selection - by extension is disabled and all files are tried to be parsed with + file names. When using this option, the automatic language selection + by extension is disabled and PMD tries to parse all files with the given language `<lang>`. Parsing errors are ignored and unparsable files are skipped. @@ -92,9 +92,9 @@ The tool comes with a rather extensive help text, simply running with `--help`! %} {% include custom/cli_option_row.html options="--ignore-list" option_arg="filepath" - description="Path to file containing a comma delimited list of files to ignore. + description="Path to file containing a list of files to ignore, one path per line. This option can be combined with `--dir` and `--file-list`. - This ignore list takes precedence over any files in the filelist." + This ignore list takes precedence over any files in the file-list." %} {% include custom/cli_option_row.html options="--help,-h,-H" description="Display help on usage." diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 9c87026392..dea79b1d19 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,6 +26,7 @@ For instance, the above can be written ```shell pmd -d src/*/java -R rset*.xml ``` +Please use theses new forms instead of using comma-separated list as argument to these options. ### Fixed Issues diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index fd4c8408e1..18c1da8a28 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -30,21 +30,44 @@ import com.beust.jcommander.validators.PositiveInteger; @InternalApi public class PMDParameters { - @Parameter(names = { "--rulesets", "-rulesets", "-R" }, description = "Comma separated list of ruleset names to use.", + @Parameter(names = { "--rulesets", "-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. " + + "The option can be repeated, and multiple arguments can be provided to a single occurrence of the option.", required = true, variableArity = true) private List rulesets; - @Parameter(names = { "--uri", "-uri", "-u" }, description = "Database URI for sources.") + @Parameter(names = { "--uri", "-uri", "-u" }, + description = "Database URI for sources. " + + "One of --dir, --file-list or --uri must be provided. " + ) private String uri; - @Parameter(names = { "--dir", "-dir", "-d" }, description = "Root directory for sources.", variableArity = true) + @Parameter(names = { "--dir", "-dir", "-d" }, + description = "Path to a source file, or directory containing source files to analyze. " + // About the following line: + // In PMD 6, this is only the case for files found in directories. If you + // specify a file directly, and it is unknown, then the Java parser is used. + + "Note that a file is only effectively added if it matches a language known by PMD. " + + "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. ", + variableArity = true) private List inputPaths = new ArrayList<>(); - @Parameter(names = { "--file-list", "-filelist" }, description = "Path to a file containing a list of files to analyze.") + @Parameter(names = { "--file-list", "-filelist" }, + 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 String fileListPath; - @Parameter(names = { "--ignore-list", "-ignorelist" }, description = "Path to a file containing a list of files to ignore.") + @Parameter(names = { "--ignore-list", "-ignorelist" }, + 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 and --file-list. " + ) private String ignoreListPath; @Parameter(names = { "--format", "-format", "-f" }, description = "Report format type.") @@ -106,12 +129,17 @@ public class PMDParameters { @Parameter(names = { "-language", "-l" }, description = "Specify a language PMD should use.") private String language = null; - @Parameter(names = { "--force-language", "-force-language" }, description = "Force a language to be used for all input files, irrespective of filenames.") + @Parameter(names = { "--force-language", "-force-language" }, + description = "Force a language to be used for all input files, irrespective of file names. " + + "When using this option, the automatic language selection by extension is disabled, and PMD " + + "tries to parse all input files with the given language's parser. " + + "Parsing errors are ignored." + ) private String forceLanguage = null; @Parameter(names = { "--aux-classpath", "-auxclasspath" }, description = "Specifies the classpath for libraries used by the source code. " - + "This is used by the type resolution. The platform specific path delimiter " + + "This is used to resolve types in Java source files. The platform specific path delimiter " + "(\":\" on Linux, \";\" on Windows) is used to separate the entries. " + "Alternatively, a single 'file:' URL to a text file containing path elements on consecutive lines " + "can be specified.") From d0ed105b9060aaa59a87e59d5bc7cef03bd5acf8 Mon Sep 17 00:00:00 2001 From: Per Abich Date: Mon, 9 May 2022 09:12:33 +0200 Subject: [PATCH 19/38] Slight refactoring of my changes to reduce complexity --- .../bestpractices/UseCollectionIsEmptyRule.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) 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 c1cc304e6a..b780c22291 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 @@ -22,7 +22,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTResultType; import net.sourceforge.pmd.lang.java.ast.ASTType; -import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.lang.java.rule.AbstractInefficientZeroCheck; import net.sourceforge.pmd.lang.java.symboltable.ClassScope; @@ -124,20 +123,14 @@ public class UseCollectionIsEmptyRule extends AbstractInefficientZeroCheck { Node classOrEnumBody = expr.getFirstParentOfType(ASTClassOrInterfaceBody.class); if (classOrEnumBody == null) { classOrEnumBody = expr.getFirstParentOfType(ASTEnumBody.class); - } + } if (classOrEnumBody == null) { classOrEnumBody = expr.getFirstParentOfType(ASTRecordDeclaration.class); - List descendantsOfType = classOrEnumBody.findDescendantsOfType(ASTVariableDeclaratorId.class); - for (ASTVariableDeclaratorId variableDeclaratorId : descendantsOfType) { - if (variableDeclaratorId.getName().equals(varName)) { - return variableDeclaratorId.getTypeNode().getTypeDefinition(); - } - } } - List varDeclarators = classOrEnumBody.findDescendantsOfType(ASTVariableDeclarator.class); - for (ASTVariableDeclarator varDeclarator : varDeclarators) { - if (varDeclarator.getName().equals(varName)) { - return varDeclarator.getVariableId().getTypeNode().getTypeDefinition(); + List varDeclaratorIds = classOrEnumBody.findDescendantsOfType(ASTVariableDeclaratorId.class); + for (ASTVariableDeclaratorId variableDeclaratorId : varDeclaratorIds) { + if (variableDeclaratorId.getName().equals(varName)) { + return variableDeclaratorId.getTypeNode().getTypeDefinition(); } } return null; From 402939f9cc928fddab8a72df85993718cc610cd8 Mon Sep 17 00:00:00 2001 From: Luke Lukes <45536418+lukelukes@users.noreply.github.com> Date: Tue, 10 May 2022 10:13:30 +0300 Subject: [PATCH 20/38] [java] ImmutableField: fix mockito/spring false positives --- .../java/rule/design/ImmutableFieldRule.java | 13 ++++++++++ .../java/rule/design/xml/ImmutableField.xml | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+) 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 76fb6639f1..69baff8219 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 @@ -4,6 +4,8 @@ package net.sourceforge.pmd.lang.java.rule.design; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -41,6 +43,17 @@ public class ImmutableFieldRule extends AbstractLombokAwareRule { CHECKDECL } + @Override + protected Collection defaultSuppressionAnnotations() { + Collection defaultValues = new ArrayList<>(super.defaultSuppressionAnnotations()); + defaultValues.add("org.mockito.Mock"); + defaultValues.add("org.mockito.InjectMocks"); + defaultValues.add("org.springframework.beans.factory.annotation.Autowired"); + defaultValues.add("org.springframework.boot.test.mock.mockito.MockBean"); + + return defaultValues; + } + @Override public Object visit(ASTClassOrInterfaceDeclaration node, Object data) { Object result = super.visit(node, data); 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 359a1ce214..2b645e9839 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 @@ -569,6 +569,32 @@ public class ExampleImmutableField { this.str = strLocal+"123"; } } +} + ]]> + + + + #3874 [java] ImmutableField - false positive when using field setter annotations + 0 + From 7921e836b193df860a1866ac0415497711c4e531 Mon Sep 17 00:00:00 2001 From: Maikel Steneker Date: Mon, 16 May 2022 16:42:01 +0200 Subject: [PATCH 21/38] Add option to ignore C# attributes (annotations) --- .../java/net/sourceforge/pmd/cpd/GUI.java | 11 +- .../net/sourceforge/pmd/cpd/CsTokenizer.java | 45 +++- .../sourceforge/pmd/cpd/CsTokenizerTest.java | 21 +- .../pmd/lang/cs/cpd/testdata/attributes.cs | 42 ++++ .../pmd/lang/cs/cpd/testdata/attributes.txt | 229 ++++++++++++++++++ .../cs/cpd/testdata/attributes_ignored.txt | 109 +++++++++ 6 files changed, 441 insertions(+), 16 deletions(-) create mode 100644 pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.cs create mode 100644 pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt create mode 100644 pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt 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 540e972759..b970880aa0 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 @@ -147,7 +147,16 @@ public class GUI implements CPDListener { @Override public boolean canIgnoreAnnotations() { - return "java".equals(terseName); + if (terseName == null) { + return false; + } + switch (terseName) { + case "cs": + case "java": + return true; + default: + return false; + } } @Override diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java index a48212290a..7a8cfd09f6 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java @@ -20,6 +20,7 @@ public class CsTokenizer extends AntlrTokenizer { private boolean ignoreUsings = false; private boolean ignoreLiteralSequences = false; + private boolean ignoreAttributes = false; /** * Sets the possible options for the C# tokenizer. @@ -27,19 +28,16 @@ public class CsTokenizer extends AntlrTokenizer { * @param properties the properties * @see #IGNORE_USINGS * @see #OPTION_IGNORE_LITERAL_SEQUENCES + * @see #IGNORE_ANNOTATIONS */ public void setProperties(Properties properties) { - ignoreUsings = Boolean.parseBoolean(properties.getProperty(IGNORE_USINGS, Boolean.FALSE.toString())); - ignoreLiteralSequences = Boolean.parseBoolean(properties.getProperty(OPTION_IGNORE_LITERAL_SEQUENCES, - Boolean.FALSE.toString())); + ignoreUsings = getBooleanProperty(properties, IGNORE_USINGS); + ignoreLiteralSequences = getBooleanProperty(properties, OPTION_IGNORE_LITERAL_SEQUENCES); + ignoreAttributes = getBooleanProperty(properties, IGNORE_ANNOTATIONS); } - public void setIgnoreUsings(boolean ignoreUsings) { - this.ignoreUsings = ignoreUsings; - } - - public void setIgnoreLiteralSequences(boolean ignoreLiteralSequences) { - this.ignoreLiteralSequences = ignoreLiteralSequences; + private boolean getBooleanProperty(final Properties properties, final String property) { + return Boolean.parseBoolean(properties.getProperty(property, Boolean.FALSE.toString())); } @Override @@ -50,7 +48,7 @@ public class CsTokenizer extends AntlrTokenizer { @Override protected AntlrTokenFilter getTokenFilter(final AntlrTokenManager tokenManager) { - return new CsTokenFilter(tokenManager, ignoreUsings, ignoreLiteralSequences); + return new CsTokenFilter(tokenManager, ignoreUsings, ignoreLiteralSequences, ignoreAttributes); } /** @@ -69,15 +67,18 @@ public class CsTokenizer extends AntlrTokenizer { private final boolean ignoreUsings; private final boolean ignoreLiteralSequences; + private final boolean ignoreAttributes; private boolean discardingUsings = false; private boolean discardingNL = false; + private boolean isDiscardingAttribute = false; private AntlrToken discardingLiteralsUntil = null; private boolean discardCurrent = false; - CsTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreUsings, boolean ignoreLiteralSequences) { + CsTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreUsings, boolean ignoreLiteralSequences, boolean ignoreAttributes) { super(tokenManager); this.ignoreUsings = ignoreUsings; this.ignoreLiteralSequences = ignoreLiteralSequences; + this.ignoreAttributes = ignoreAttributes; } @Override @@ -90,6 +91,7 @@ public class CsTokenizer extends AntlrTokenizer { discardCurrent = false; skipUsingDirectives(currentToken, remainingTokens); skipLiteralSequences(currentToken, remainingTokens); + skipAttributes(currentToken); } private void skipUsingDirectives(final AntlrToken currentToken, final Iterable remainingTokens) { @@ -166,6 +168,25 @@ public class CsTokenizer extends AntlrTokenizer { discardingNL = currentToken.getKind() == CSharpLexer.NL; } + private void skipAttributes(final AntlrToken currentToken) { + if (ignoreAttributes) { + switch (currentToken.getKind()) { + case CSharpLexer.OPEN_BRACKET: + // Start of an attribute. + isDiscardingAttribute = true; + break; + case CSharpLexer.CLOSE_BRACKET: + // End of an attribute. + isDiscardingAttribute = false; + discardCurrent = true; + break; + default: + // Skip any other token. + break; + } + } + } + private void skipLiteralSequences(final AntlrToken currentToken, final Iterable remainingTokens) { if (ignoreLiteralSequences) { final int type = currentToken.getKind(); @@ -221,7 +242,7 @@ public class CsTokenizer extends AntlrTokenizer { @Override protected boolean isLanguageSpecificDiscarding() { - return discardingUsings || discardingNL || isDiscardingLiterals() || discardCurrent; + return discardingUsings || discardingNL || isDiscardingAttribute || isDiscardingLiterals() || discardCurrent; } } } diff --git a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java index 63c9cd5aee..d05797d726 100644 --- a/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java +++ b/pmd-cs/src/test/java/net/sourceforge/pmd/cpd/CsTokenizerTest.java @@ -105,18 +105,33 @@ public class CsTokenizerTest extends CpdTextComparisonTest { doTest("csharp7And8Additions"); } + @Test + public void testAttributesAreNotIgnored() { + doTest("attributes"); + } + + @Test + public void testAttributesAreIgnored() { + doTest("attributes", "_ignored", skipAttributes()); + } + private Properties ignoreUsings() { - return properties(true, false); + return properties(true, false, false); } private Properties skipLiteralSequences() { - return properties(false, true); + return properties(false, true, false); } - private Properties properties(boolean ignoreUsings, boolean ignoreLiteralSequences) { + private Properties skipAttributes() { + return properties(false, false, true); + } + + private Properties properties(boolean ignoreUsings, boolean ignoreLiteralSequences, boolean ignoreAttributes) { Properties properties = new Properties(); properties.setProperty(Tokenizer.IGNORE_USINGS, Boolean.toString(ignoreUsings)); properties.setProperty(Tokenizer.OPTION_IGNORE_LITERAL_SEQUENCES, Boolean.toString(ignoreLiteralSequences)); + properties.setProperty(Tokenizer.IGNORE_ANNOTATIONS, Boolean.toString(ignoreAttributes)); return properties; } } diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.cs b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.cs new file mode 100644 index 0000000000..811e151362 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.cs @@ -0,0 +1,42 @@ +[Serializable] +public class SampleClass +{ + // Objects of this type can be serialized. +} + +[System.Runtime.InteropServices.DllImport("user32.dll")] +extern static void SampleMethod(); + +void MethodA([In][Out] ref double x) { } +void MethodB([Out][In] ref double x) { } +void MethodC([In, Out] ref double x) { } + +[Conditional("DEBUG"), Conditional("TEST1")] +void TraceMethod() +{ + // ... +} + +[DllImport("user32.dll")] +[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)] +[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)] + +using System; +using System.Reflection; +[assembly: AssemblyTitleAttribute("Production assembly 4")] +[module: CLSCompliant(true)] + +// default: applies to method +[ValidatedContract] +int Method1() { return 0; } + +// applies to method +[method: ValidatedContract] +int Method2() { return 0; } + +// applies to parameter +int Method3([ValidatedContract] string contract) { return 0; } + +// applies to return value +[return: ValidatedContract] +int Method4() { return 0; } \ No newline at end of file diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt new file mode 100644 index 0000000000..403064af38 --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt @@ -0,0 +1,229 @@ + [Image] or [Truncated image[ Bcol Ecol +L1 + [\[] 1 1 + [Serializable] 2 13 + [\]] 14 14 +L2 + [public] 1 6 + [class] 8 12 + [SampleClass] 14 24 +L3 + [{] 1 1 +L5 + [}] 1 1 +L7 + [\[] 1 1 + [System] 2 7 + [.] 8 8 + [Runtime] 9 15 + [.] 16 16 + [InteropServices] 17 31 + [.] 32 32 + [DllImport] 33 41 + [(] 42 42 + ["user32.dll"] 43 54 + [)] 55 55 + [\]] 56 56 +L8 + [extern] 1 6 + [static] 8 13 + [void] 15 18 + [SampleMethod] 20 31 + [(] 32 32 + [)] 33 33 + [;] 34 34 +L10 + [void] 1 4 + [MethodA] 6 12 + [(] 13 13 + [\[] 14 14 + [In] 15 16 + [\]] 17 17 + [\[] 18 18 + [Out] 19 21 + [\]] 22 22 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L11 + [void] 1 4 + [MethodB] 6 12 + [(] 13 13 + [\[] 14 14 + [Out] 15 17 + [\]] 18 18 + [\[] 19 19 + [In] 20 21 + [\]] 22 22 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L12 + [void] 1 4 + [MethodC] 6 12 + [(] 13 13 + [\[] 14 14 + [In] 15 16 + [,] 17 17 + [Out] 19 21 + [\]] 22 22 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L14 + [\[] 1 1 + [Conditional] 2 12 + [(] 13 13 + ["DEBUG"] 14 20 + [)] 21 21 + [,] 22 22 + [Conditional] 24 34 + [(] 35 35 + ["TEST1"] 36 42 + [)] 43 43 + [\]] 44 44 +L15 + [void] 1 4 + [TraceMethod] 6 16 + [(] 17 17 + [)] 18 18 +L16 + [{] 1 1 +L18 + [}] 1 1 +L20 + [\[] 1 1 + [DllImport] 2 10 + [(] 11 11 + ["user32.dll"] 12 23 + [)] 24 24 + [\]] 25 25 +L21 + [\[] 1 1 + [DllImport] 2 10 + [(] 11 11 + ["user32.dll"] 12 23 + [,] 24 24 + [SetLastError] 26 37 + [=] 38 38 + [false] 39 43 + [,] 44 44 + [ExactSpelling] 46 58 + [=] 59 59 + [false] 60 64 + [)] 65 65 + [\]] 66 66 +L22 + [\[] 1 1 + [DllImport] 2 10 + [(] 11 11 + ["user32.dll"] 12 23 + [,] 24 24 + [ExactSpelling] 26 38 + [=] 39 39 + [false] 40 44 + [,] 45 45 + [SetLastError] 47 58 + [=] 59 59 + [false] 60 64 + [)] 65 65 + [\]] 66 66 +L24 + [using] 1 5 + [System] 7 12 + [;] 13 13 +L25 + [using] 1 5 + [System] 7 12 + [.] 13 13 + [Reflection] 14 23 + [;] 24 24 +L26 + [\[] 1 1 + [assembly] 2 9 + [:] 10 10 + [AssemblyTitleAttribute] 12 33 + [(] 34 34 + ["Production assembly 4"] 35 57 + [)] 58 58 + [\]] 59 59 +L27 + [\[] 1 1 + [module] 2 7 + [:] 8 8 + [CLSCompliant] 10 21 + [(] 22 22 + [true] 23 26 + [)] 27 27 + [\]] 28 28 +L30 + [\[] 1 1 + [ValidatedContract] 2 18 + [\]] 19 19 +L31 + [int] 1 3 + [Method1] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +L34 + [\[] 1 1 + [method] 2 7 + [:] 8 8 + [ValidatedContract] 10 26 + [\]] 27 27 +L35 + [int] 1 3 + [Method2] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +L38 + [int] 1 3 + [Method3] 5 11 + [(] 12 12 + [\[] 13 13 + [ValidatedContract] 14 30 + [\]] 31 31 + [string] 33 38 + [contract] 40 47 + [)] 48 48 + [{] 50 50 + [return] 52 57 + [0] 59 59 + [;] 60 60 + [}] 62 62 +L41 + [\[] 1 1 + [return] 2 7 + [:] 8 8 + [ValidatedContract] 10 26 + [\]] 27 27 +L42 + [int] 1 3 + [Method4] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt new file mode 100644 index 0000000000..0796c4384c --- /dev/null +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt @@ -0,0 +1,109 @@ + [Image] or [Truncated image[ Bcol Ecol +L2 + [public] 1 6 + [class] 8 12 + [SampleClass] 14 24 +L3 + [{] 1 1 +L5 + [}] 1 1 +L8 + [extern] 1 6 + [static] 8 13 + [void] 15 18 + [SampleMethod] 20 31 + [(] 32 32 + [)] 33 33 + [;] 34 34 +L10 + [void] 1 4 + [MethodA] 6 12 + [(] 13 13 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L11 + [void] 1 4 + [MethodB] 6 12 + [(] 13 13 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L12 + [void] 1 4 + [MethodC] 6 12 + [(] 13 13 + [ref] 24 26 + [double] 28 33 + [x] 35 35 + [)] 36 36 + [{] 38 38 + [}] 40 40 +L15 + [void] 1 4 + [TraceMethod] 6 16 + [(] 17 17 + [)] 18 18 +L16 + [{] 1 1 +L18 + [}] 1 1 +L24 + [using] 1 5 + [System] 7 12 + [;] 13 13 +L25 + [using] 1 5 + [System] 7 12 + [.] 13 13 + [Reflection] 14 23 + [;] 24 24 +L31 + [int] 1 3 + [Method1] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +L35 + [int] 1 3 + [Method2] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +L38 + [int] 1 3 + [Method3] 5 11 + [(] 12 12 + [string] 33 38 + [contract] 40 47 + [)] 48 48 + [{] 50 50 + [return] 52 57 + [0] 59 59 + [;] 60 60 + [}] 62 62 +L42 + [int] 1 3 + [Method4] 5 11 + [(] 12 12 + [)] 13 13 + [{] 15 15 + [return] 17 22 + [0] 24 24 + [;] 25 25 + [}] 27 27 +EOF From 2daa3381b4f646ca0b862998d12bb598ebe62a34 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:06:29 +0200 Subject: [PATCH 22/38] [doc] Update release notes (#3874, #3964) --- docs/pages/release_notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index c31a705241..b8bd840b4c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,8 @@ This is a {{ site.pmd.release_type }} release. ### Fixed Issues +* java-design + * [#3874](https://github.com/pmd/pmd/issues/3874): \[java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito) * javascript * [#3948](https://github.com/pmd/pmd/issues/3948): \[js] Invalid operator error for method property in object literal @@ -23,5 +25,7 @@ This is a {{ site.pmd.release_type }} release. ### External Contributions +* [#3964](https://github.com/pmd/pmd/pull/3964): \[java] Fix #3874 - ImmutableField: fix mockito/spring false positives - [@lukelukes](https://github.com/lukelukes) + {% endtocmaker %} From 8a99dee9117769486c71c4f05e7beda8f865b488 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:08:05 +0200 Subject: [PATCH 23/38] [java] Update test case (ImmutableField) --- .../pmd/lang/java/rule/design/xml/ImmutableField.xml | 7 ++++++- 1 file changed, 6 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 2b645e9839..b6f6bfb687 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 @@ -574,7 +574,7 @@ public class ExampleImmutableField { - #3874 [java] ImmutableField - false positive when using field setter annotations + #3874 [java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito) 0 From d9fce6107e8228fd022e495bb61f67fc36245f75 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:26:11 +0200 Subject: [PATCH 24/38] Add @lukelukes as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 25 +++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index dcac68bf60..f5d880797e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -6639,6 +6639,15 @@ "contributions": [ "code" ] + }, + { + "login": "lukelukes", + "name": "lukelukes", + "avatar_url": "https://avatars.githubusercontent.com/u/45536418?v=4", + "profile": "https://github.com/lukelukes", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 3f6b6213cf..b2efb5841c 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -835,112 +835,113 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
lpeddy

🐛
lujiefsi

💻 +
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛
matchbox

🐛
matthiaskraaz

🐛 -
meandonlyme

🐛 +
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mriddell95

🐛
mrlzh

🐛
msloan

🐛
mucharlaravalika

🐛 -
mvenneman

🐛 +
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛
oggboy

🐛
oinume

🐛 -
orimarko

💻 🐛 +
orimarko

💻 🐛
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛
pbrajesh1

🐛
phoenix384

🐛 -
piotrszymanski-sc

💻 +
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛
r-r-a-j

🐛
raghujayjunk

🐛 -
rajeshveera

🐛 +
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛
rillig-tk

🐛
rmohan20

💻 🐛 -
rxmicro

🐛 +
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛 -
simeonKondr

🐛 +
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻
sratz

🐛
stonio

🐛
sturton

💻 🐛 -
sudharmohan

🐛 +
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛 -
tiandiyixian

🐛 +
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛
trentchilders

🐛
triandicAnt

🐛
trishul14

🐛
tsui

🐛 -
winhkey

🐛 +
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛 -
xuanuy

🐛 +
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛 -
zt_soft

🐛 +
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛
Árpád Magosányi

🐛 From 91328436a01f33decb822f0bff10a0ef9ca19d31 Mon Sep 17 00:00:00 2001 From: Maikel Steneker Date: Fri, 20 May 2022 09:35:53 +0200 Subject: [PATCH 25/38] Clarify documentation on `--ignore-annotations` CLI option --- docs/pages/pmd/userdocs/cpd/cpd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index dc4577e41d..d909eb4f2f 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -112,9 +112,9 @@ Novice as much as advanced readers may want to [read on on Refactoring Guru](htt languages="Java" %} {% include custom/cli_option_row.html options="--ignore-annotations" - description="Ignore language annotations when comparing text" + description="Ignore language annotations (Java) or attributes (C#) when comparing text" default="false" - languages="Java" + languages="C#, Java" %} {% include custom/cli_option_row.html options="--ignore-literal-sequences" description="Ignore sequences of literals (common e.g. in list initializers)" From 77369804755c5e328c4082744c755391c58fc0c4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:51:45 +0200 Subject: [PATCH 26/38] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Fournier --- .../sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java index 702e6605d4..4568a28d35 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/xpath/saxon/ElementNode.java @@ -81,6 +81,9 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { } private static int determineType(Node node) { + // As of PMD 6.48.0, only the experimental HTML module uses this naming + // convention to identify non-element nodes. + // TODO PMD 7: maybe generalize this to other languages String name = node.getXPathNodeName(); if ("#text".equals(name)) { return Type.TEXT; @@ -158,7 +161,7 @@ public class ElementNode extends BaseNodeInfo implements AstNodeOwner { @Override public String getStringValue() { - if (determineType(getUnderlyingNode()) == Type.TEXT) { + if (getNodeKind() == Type.TEXT || getNodeKind() == Type.COMMENT) { return getUnderlyingNode().getImage(); } return ""; From 85095f19d3a60f233d4313059d7a8c0aebd5ad0b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:54:48 +0200 Subject: [PATCH 27/38] [html] Added test case to verify #text doesn't find text nodes anymore --- .../net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java index 1a6272dab8..404b110251 100644 --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java @@ -42,6 +42,14 @@ public class HtmlXPathRuleTest { Assert.assertEquals(3, report.getViolations().get(0).getBeginLine()); } + @Test + public void selectTextNodeByNodeNameShouldNotWork() { + String xpath = "//*[local-name() = '#text'][contains(@Text, '{ ')]"; + + Report report = runXPath(LIGHTNING_WEB_COMPONENT, xpath); + Assert.assertEquals(0, report.getViolations().size()); + } + @Test public void verifyTextNodeName() { ASTHtmlDocument document = HtmlParsingHelper.DEFAULT.parse("

foobar

"); From 1a596693fdf37b7289bc085c332c822c299db115 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 09:56:49 +0200 Subject: [PATCH 28/38] [html] Added test case to verify #text doesn't find text nodes anymore --- .../java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java index 404b110251..1c9f81b1ca 100644 --- a/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java +++ b/pmd-html/src/test/java/net/sourceforge/pmd/lang/html/HtmlXPathRuleTest.java @@ -44,8 +44,7 @@ public class HtmlXPathRuleTest { @Test public void selectTextNodeByNodeNameShouldNotWork() { - String xpath = "//*[local-name() = '#text'][contains(@Text, '{ ')]"; - + String xpath = "//*[local-name() = '#text']"; Report report = runXPath(LIGHTNING_WEB_COMPONENT, xpath); Assert.assertEquals(0, report.getViolations().size()); } From fd7cae278e35a36719ae867d3e065b18a50c1336 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 14:24:42 +0200 Subject: [PATCH 29/38] [doc] Update release notes (#3955) --- 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 c31a705241..d565716926 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -16,6 +16,8 @@ This is a {{ site.pmd.release_type }} release. ### Fixed Issues +* html + * [#3955](https://github.com/pmd/pmd/pull/3955): \[html] Improvements for handling text and comment nodes * javascript * [#3948](https://github.com/pmd/pmd/issues/3948): \[js] Invalid operator error for method property in object literal From 26f6682a8b467ec766fb7b1710ab2a9f4cec114a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 20 May 2022 14:58:56 +0200 Subject: [PATCH 30/38] Fix build --- pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java | 1 + 1 file changed, 1 insertion(+) 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 d53bff721d..13e1a87606 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Objects; import java.util.Properties; +import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; From 01c48e1ca7686fec520a687d30b8bb2e74b09ce6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 10:26:03 +0200 Subject: [PATCH 31/38] [doc] Update release notes (#3960) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Fournier --- 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 fb3f28f11f..2c7c511a92 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -26,7 +26,7 @@ For instance, the above can be written ```shell pmd -d src/*/java -R rset*.xml ``` -Please use theses new forms instead of using comma-separated list as argument to these options. +Please use theses new forms instead of using comma-separated lists as argument to these options. ### Fixed Issues From aef06d4b3a763d3a41f56111c2055554a464003b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 10:28:18 +0200 Subject: [PATCH 32/38] Add @vibhory2j as a contributor --- .all-contributorsrc | 9 ++++ docs/pages/pmd/projectdocs/credits.md | 59 ++++++++++++++------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f5d880797e..240441581c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -6648,6 +6648,15 @@ "contributions": [ "code" ] + }, + { + "login": "vibhory2j", + "name": "Vibhor Goyal", + "avatar_url": "https://avatars.githubusercontent.com/u/15845016?v=4", + "profile": "https://github.com/vibhory2j", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index b2efb5841c..e243b5c134 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -685,262 +685,263 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Valentin Brandl

🐛
Valeria

🐛
Vasily Anisimov

🐛 +
Vibhor Goyal

🐛
Vickenty Fesunov

🐛 -
Victor Noël

🐛 +
Victor Noël

🐛
Vincent Galloy

💻
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛
Vitaly

🐛 -
Vitaly Polonetsky

🐛 +
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛
Wayne J. Earl

🐛 -
Wchenghui

🐛 +
Wchenghui

🐛
Will Winder

🐛
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛
XenoAmess

💻 🐛 -
Yang

💻 +
Yang

💻
YaroslavTER

🐛
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛
Yurii Dubinka

🐛
Zoltan Farkas

🐛 -
Zustin

🐛 +
Zustin

🐛
aaronhurst-google

🐛
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛
anicoara

🐛
arunprasathav

🐛 -
asiercamara

🐛 +
asiercamara

🐛
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛
axelbarfod1

🐛
b-3-n

🐛 -
balbhadra9

🐛 +
balbhadra9

🐛
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛
caesarkim

🐛
carolyujing

🐛 -
cesares-basilico

🐛 +
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛
cristalp

🐛
crunsk

🐛 -
cwholmes

🐛 +
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛
d1ss0nanz

🐛
danbrycefairsailcom

🐛
dariansanity

🐛
darrenmiliband

🐛 -
davidburstrom

🐛 +
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛
dinesh150

🐛
diziaq

🐛
dreaminpast123

🐛 -
duanyanan

🐛 +
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛
ekkirala

🐛
emersonmoura

🐛
fairy

🐛 -
filiprafalowicz

💻 +
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛
freafrea

🐛
fsapatin

🐛
gracia19

🐛 -
guo fei

🐛 +
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛
henrik242

🐛
hongpuwu

🐛 -
hvbtup

💻 🐛 +
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛
jbennett2091

🐛
jcamerin

🐛 -
jkeener1

🐛 +
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛
karwer

🐛
kaulonline

🐛 -
kdaemonv

🐛 +
kdaemonv

🐛
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛
krzyk

🐛
lasselindqvist

🐛
lihuaib

🐛 -
lonelyma1021

🐛 +
lonelyma1021

🐛
lpeddy

🐛
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛
matchbox

🐛 -
matthiaskraaz

🐛 +
matthiaskraaz

🐛
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mriddell95

🐛
mrlzh

🐛
msloan

🐛 -
mucharlaravalika

🐛 +
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛
oggboy

🐛 -
oinume

🐛 +
oinume

🐛
orimarko

💻 🐛
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛
pbrajesh1

🐛 -
phoenix384

🐛 +
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛
r-r-a-j

🐛 -
raghujayjunk

🐛 +
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛
rillig-tk

🐛 -
rmohan20

💻 🐛 +
rmohan20

💻 🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛
sebbASF

🐛
sergeygorbaty

💻 -
shilko2013

🐛 +
shilko2013

🐛
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻
sratz

🐛
stonio

🐛 -
sturton

💻 🐛 +
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛
testation21

💻 🐛 -
thanosa

🐛 +
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛
trentchilders

🐛
triandicAnt

🐛
trishul14

🐛 -
tsui

🐛 +
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛
xioayuge

🐛 -
xnYi9wRezm

💻 🐛 +
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛
zgrzyt93

💻 🐛 -
zh3ng

🐛 +
zh3ng

🐛
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛 From aae06c45ac2d2e07804dc7ab79fb26c55a51c091 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 10:36:55 +0200 Subject: [PATCH 33/38] [doc] Update release notes (#3946, #3423, #2605, #2604, #2752) --- 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 2c7c511a92..e4855f3b66 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -32,12 +32,19 @@ Please use theses new forms instead of using comma-separated lists as argument t * cli * [#1445](https://github.com/pmd/pmd/issues/1445): \[core] Allow CLI to take globs as parameters +* go + * [#2752](https://github.com/pmd/pmd/issues/2752): \[go] Error parsing unicode values * html * [#3955](https://github.com/pmd/pmd/pull/3955): \[html] Improvements for handling text and comment nodes +* java + * [#3423](https://github.com/pmd/pmd/issues/3423): \[java] Error processing identifiers with Unicode * java-design * [#3874](https://github.com/pmd/pmd/issues/3874): \[java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito) * javascript + * [#2605](https://github.com/pmd/pmd/issues/2605): \[js] Support unicode characters * [#3948](https://github.com/pmd/pmd/issues/3948): \[js] Invalid operator error for method property in object literal +* python + * [#2604](https://github.com/pmd/pmd/issues/2604): \[python] Support unicode identifiers ### API Changes From d0873ff6fafa68a49910107426664eaf8caa8bfa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 10:57:08 +0200 Subject: [PATCH 34/38] [doc] Update release notes (#3974) --- 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 e4855f3b66..44874a9097 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -28,10 +28,18 @@ pmd -d src/*/java -R rset*.xml ``` Please use theses new forms instead of using comma-separated lists as argument to these options. +#### C# Improvements + +When executing CPD on C# sources, the option `--ignore-annotations` is now supported as well. +It ignores C# attributes when detecting duplicated code. This option can also be enabled via +the CPD GUI. See [#3974](https://github.com/pmd/pmd/pull/3974) for details. + ### Fixed Issues * cli * [#1445](https://github.com/pmd/pmd/issues/1445): \[core] Allow CLI to take globs as parameters +* cs (c#) + * [#3974](https://github.com/pmd/pmd/pull/3974): \[cs] Add option to ignore C# attributes (annotations) * go * [#2752](https://github.com/pmd/pmd/issues/2752): \[go] Error parsing unicode values * html @@ -57,6 +65,7 @@ A new set of methods have been added, which use lists and do not rely on comma s ### External Contributions * [#3964](https://github.com/pmd/pmd/pull/3964): \[java] Fix #3874 - ImmutableField: fix mockito/spring false positives - [@lukelukes](https://github.com/lukelukes) +* [#3974](https://github.com/pmd/pmd/pull/3974): \[cs] Add option to ignore C# attributes (annotations) - [@maikelsteneker](https://github.com/maikelsteneker) {% endtocmaker %} From 11cda428f1092530408896d5d587ac20509ab152 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 11:03:01 +0200 Subject: [PATCH 35/38] [doc] Update release notes (#3954, #3961) --- 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 44874a9097..eca65c0e36 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -46,6 +46,8 @@ the CPD GUI. See [#3974](https://github.com/pmd/pmd/pull/3974) for details. * [#3955](https://github.com/pmd/pmd/pull/3955): \[html] Improvements for handling text and comment nodes * java * [#3423](https://github.com/pmd/pmd/issues/3423): \[java] Error processing identifiers with Unicode +* java-bestpractices + * [#3954](https://github.com/pmd/pmd/issues/3954): \[java] NPE in UseCollectionIsEmptyRule when .size() is called in a record * java-design * [#3874](https://github.com/pmd/pmd/issues/3874): \[java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito) * javascript @@ -64,6 +66,7 @@ A new set of methods have been added, which use lists and do not rely on comma s ### External Contributions +* [#3961](https://github.com/pmd/pmd/pull/3961): \[java] Fix #3954 - NPE in UseCollectionIsEmptyRule with record - [@flyhard](https://github.com/flyhard) * [#3964](https://github.com/pmd/pmd/pull/3964): \[java] Fix #3874 - ImmutableField: fix mockito/spring false positives - [@lukelukes](https://github.com/lukelukes) * [#3974](https://github.com/pmd/pmd/pull/3974): \[cs] Add option to ignore C# attributes (annotations) - [@maikelsteneker](https://github.com/maikelsteneker) From 95d6619a6b28a0bbf42c762aacb02f4e8a3c683e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 11:03:20 +0200 Subject: [PATCH 36/38] Add @Ramel0921 as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 85 ++++++++++++++------------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 240441581c..7a4c53bfd6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -6657,6 +6657,15 @@ "contributions": [ "bug" ] + }, + { + "login": "Ramel0921", + "name": "Ramel0921", + "avatar_url": "https://avatars.githubusercontent.com/u/104978096?v=4", + "profile": "https://github.com/Ramel0921", + "contributions": [ + "bug" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index e243b5c134..71ac04355b 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -569,378 +569,379 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
RaheemShaik999

🐛
RajeshR

💻 🐛
Ramachandra Mohan

🐛 -
Raquel Pau

🐛 +
Ramel0921

🐛 +
Raquel Pau

🐛
Ravikiran Janardhana

🐛
Reda Benhemmouche

🐛
Renato Oliveira

💻 🐛
Rich DiCroce

🐛
Riot R1cket

🐛
Rishabh Jain

🐛 -
RishabhDeep Singh

🐛 +
RishabhDeep Singh

🐛
Robbie Martinus

💻 🐛
Robert Henry

🐛
Robert Painsi

🐛
Robert Russell

🐛
Robert Sösemann

💻 📖 📢 🐛
Robert Whitebit

🐛 -
Robin Richtsfeld

🐛 +
Robin Richtsfeld

🐛
Robin Stocker

💻 🐛
Robin Wils

🐛
RochusOest

🐛
Rodolfo Noviski

🐛
Rodrigo Casara

🐛
Rodrigo Fernandes

🐛 -
Roman Salvador

💻 🐛 +
Roman Salvador

💻 🐛
Ronald Blaschke

🐛
Róbert Papp

🐛
Saikat Sengupta

🐛
Saksham Handu

🐛
Saladoc

🐛
Salesforce Bob Lightning

🐛 -
Sam Carlberg

🐛 +
Sam Carlberg

🐛
Satoshi Kubo

🐛
Scott Kennedy

🐛
Scott Wells

🐛 💻
Scrsloota

💻
Sebastian Bögl

🐛
Sebastian Schuberth

🐛 -
Sebastian Schwarz

🐛 +
Sebastian Schwarz

🐛
Sergey Gorbaty

🐛
Sergey Kozlov

🐛
Sergey Yanzin

💻 🐛
Seth Wilcox

💻
Shubham

💻 🐛
Simon Xiao

🐛 -
Srinivasan Venkatachalam

🐛 +
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛
Stanislav Myachenkov

💻
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛
Stefan Klöss-Schuster

🐛 -
Stefan Wolf

🐛 +
Stefan Wolf

🐛
Stephan H. Wissel

🐛
Stephen

🐛
Stephen Friedrich

🐛
Steve Babula

💻
Stexxe

🐛
Stian Lågstad

🐛 -
StuartClayton5

🐛 +
StuartClayton5

🐛
Supun Arunoda

🐛
Suren Abrahamyan

🐛
SwatiBGupta1110

🐛
SyedThoufich

🐛
Szymon Sasin

🐛
T-chuangxin

🐛 -
TERAI Atsuhiro

🐛 +
TERAI Atsuhiro

🐛
TIOBE Software

💻 🐛
Taylor Smock

🐛
Techeira Damián

💻 🐛
Ted Husted

🐛
TehBakker

🐛
The Gitter Badger

🐛 -
Theodoor

🐛 +
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛
ThrawnCA

🐛 -
Thunderforge

💻 🐛 +
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Daly

🐛
Tomer Figenblat

🐛
Tomi De Lucca

💻 🐛
Torsten Kleiber

🐛 -
TrackerSB

🐛 +
TrackerSB

🐛
Ullrich Hafner

🐛
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛
Valeria

🐛
Vasily Anisimov

🐛
Vibhor Goyal

🐛 -
Vickenty Fesunov

🐛 +
Vickenty Fesunov

🐛
Victor Noël

🐛
Vincent Galloy

💻
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛 -
Vitaly

🐛 +
Vitaly

🐛
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛 -
Wayne J. Earl

🐛 +
Wayne J. Earl

🐛
Wchenghui

🐛
Will Winder

🐛
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛 -
XenoAmess

💻 🐛 +
XenoAmess

💻 🐛
Yang

💻
YaroslavTER

🐛
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛
Yurii Dubinka

🐛 -
Zoltan Farkas

🐛 +
Zoltan Farkas

🐛
Zustin

🐛
aaronhurst-google

🐛
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛
anicoara

🐛 -
arunprasathav

🐛 +
arunprasathav

🐛
asiercamara

🐛
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛
axelbarfod1

🐛 -
b-3-n

🐛 +
b-3-n

🐛
balbhadra9

🐛
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛
caesarkim

🐛 -
carolyujing

🐛 +
carolyujing

🐛
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛
cristalp

🐛 -
crunsk

🐛 +
crunsk

🐛
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛
d1ss0nanz

🐛
danbrycefairsailcom

🐛
dariansanity

🐛 -
darrenmiliband

🐛 +
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛
dinesh150

🐛
diziaq

🐛 -
dreaminpast123

🐛 +
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛
ekkirala

🐛
emersonmoura

🐛 -
fairy

🐛 +
fairy

🐛
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛
freafrea

🐛
fsapatin

🐛 -
gracia19

🐛 +
gracia19

🐛
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛
henrik242

🐛 -
hongpuwu

🐛 +
hongpuwu

🐛
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛
jbennett2091

🐛 -
jcamerin

🐛 +
jcamerin

🐛
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛
karwer

🐛 -
kaulonline

🐛 +
kaulonline

🐛
kdaemonv

🐛
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛
krzyk

🐛
lasselindqvist

🐛 -
lihuaib

🐛 +
lihuaib

🐛
lonelyma1021

🐛
lpeddy

🐛
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛 -
matchbox

🐛 +
matchbox

🐛
matthiaskraaz

🐛
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mriddell95

🐛
mrlzh

🐛 -
msloan

🐛 +
msloan

🐛
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛 -
oggboy

🐛 +
oggboy

🐛
oinume

🐛
orimarko

💻 🐛
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛 -
pbrajesh1

🐛 +
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛 -
r-r-a-j

🐛 +
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛 -
rillig-tk

🐛 +
rillig-tk

🐛
rmohan20

💻 🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛
sebbASF

🐛 -
sergeygorbaty

💻 +
sergeygorbaty

💻
shilko2013

🐛
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻
sratz

🐛 -
stonio

🐛 +
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛 -
testation21

💻 🐛 +
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛
trentchilders

🐛
triandicAnt

🐛 -
trishul14

🐛 +
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛 -
xioayuge

🐛 +
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛 -
zgrzyt93

💻 🐛 +
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛 From 6f234bab8dc174925d66423021ca44c2f455d679 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 11:03:34 +0200 Subject: [PATCH 37/38] Add @flyhard as a contributor --- .all-contributorsrc | 9 +++ docs/pages/pmd/projectdocs/credits.md | 93 ++++++++++++++------------- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7a4c53bfd6..6efd00a779 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -6666,6 +6666,15 @@ "contributions": [ "bug" ] + }, + { + "login": "flyhard", + "name": "Per Abich", + "avatar_url": "https://avatars.githubusercontent.com/u/409466?v=4", + "profile": "https://github.com/flyhard", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 71ac04355b..b00de0e0d8 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -540,413 +540,416 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Pedro Nuno Santos

🐛
Pedro Rijo

🐛
Pelisse Romain

💻 📖 🐛 +
Per Abich

💻
Pete Davids

🐛
Peter Bruin

🐛 -
Peter Chittum

💻 🐛 +
Peter Chittum

💻 🐛
Peter Cudmore

🐛
Peter Kasson

🐛
Peter Kofler

🐛
Pham Hai Trung

🐛
Philip Graf

💻 🐛
Philip Hachey

🐛 -
Philippe Ozil

🐛 +
Philippe Ozil

🐛
Phinehas Artemix

🐛
Phokham Nonava

🐛
Piotr Szymański

🐛
Piotrek Żygieło

💻 🐛
Pranay Jaiswal

🐛
Prasad Kamath

🐛 -
Prasanna

🐛 +
Prasanna

🐛
Presh-AR

🐛
Puneet1726

🐛
Rafael Cortês

🐛
RaheemShaik999

🐛
RajeshR

💻 🐛
Ramachandra Mohan

🐛 -
Ramel0921

🐛 +
Ramel0921

🐛
Raquel Pau

🐛
Ravikiran Janardhana

🐛
Reda Benhemmouche

🐛
Renato Oliveira

💻 🐛
Rich DiCroce

🐛
Riot R1cket

🐛 -
Rishabh Jain

🐛 +
Rishabh Jain

🐛
RishabhDeep Singh

🐛
Robbie Martinus

💻 🐛
Robert Henry

🐛
Robert Painsi

🐛
Robert Russell

🐛
Robert Sösemann

💻 📖 📢 🐛 -
Robert Whitebit

🐛 +
Robert Whitebit

🐛
Robin Richtsfeld

🐛
Robin Stocker

💻 🐛
Robin Wils

🐛
RochusOest

🐛
Rodolfo Noviski

🐛
Rodrigo Casara

🐛 -
Rodrigo Fernandes

🐛 +
Rodrigo Fernandes

🐛
Roman Salvador

💻 🐛
Ronald Blaschke

🐛
Róbert Papp

🐛
Saikat Sengupta

🐛
Saksham Handu

🐛
Saladoc

🐛 -
Salesforce Bob Lightning

🐛 +
Salesforce Bob Lightning

🐛
Sam Carlberg

🐛
Satoshi Kubo

🐛
Scott Kennedy

🐛
Scott Wells

🐛 💻
Scrsloota

💻
Sebastian Bögl

🐛 -
Sebastian Schuberth

🐛 +
Sebastian Schuberth

🐛
Sebastian Schwarz

🐛
Sergey Gorbaty

🐛
Sergey Kozlov

🐛
Sergey Yanzin

💻 🐛
Seth Wilcox

💻
Shubham

💻 🐛 -
Simon Xiao

🐛 +
Simon Xiao

🐛
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛
Stanislav Myachenkov

💻
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛 -
Stefan Klöss-Schuster

🐛 +
Stefan Klöss-Schuster

🐛
Stefan Wolf

🐛
Stephan H. Wissel

🐛
Stephen

🐛
Stephen Friedrich

🐛
Steve Babula

💻
Stexxe

🐛 -
Stian Lågstad

🐛 +
Stian Lågstad

🐛
StuartClayton5

🐛
Supun Arunoda

🐛
Suren Abrahamyan

🐛
SwatiBGupta1110

🐛
SyedThoufich

🐛
Szymon Sasin

🐛 -
T-chuangxin

🐛 +
T-chuangxin

🐛
TERAI Atsuhiro

🐛
TIOBE Software

💻 🐛
Taylor Smock

🐛
Techeira Damián

💻 🐛
Ted Husted

🐛
TehBakker

🐛 -
The Gitter Badger

🐛 +
The Gitter Badger

🐛
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛 -
ThrawnCA

🐛 +
ThrawnCA

🐛
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Daly

🐛
Tomer Figenblat

🐛
Tomi De Lucca

💻 🐛 -
Torsten Kleiber

🐛 +
Torsten Kleiber

🐛
TrackerSB

🐛
Ullrich Hafner

🐛
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛
Valeria

🐛
Vasily Anisimov

🐛 -
Vibhor Goyal

🐛 +
Vibhor Goyal

🐛
Vickenty Fesunov

🐛
Victor Noël

🐛
Vincent Galloy

💻
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛 -
Vishhwas

🐛 +
Vishhwas

🐛
Vitaly

🐛
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛 -
Waqas Ahmed

🐛 +
Waqas Ahmed

🐛
Wayne J. Earl

🐛
Wchenghui

🐛
Will Winder

🐛
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛 -
Woongsik Choi

🐛 +
Woongsik Choi

🐛
XenoAmess

💻 🐛
Yang

💻
YaroslavTER

🐛
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛 -
Yurii Dubinka

🐛 +
Yurii Dubinka

🐛
Zoltan Farkas

🐛
Zustin

🐛
aaronhurst-google

🐛
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛 -
anicoara

🐛 +
anicoara

🐛
arunprasathav

🐛
asiercamara

🐛
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛 -
axelbarfod1

🐛 +
axelbarfod1

🐛
b-3-n

🐛
balbhadra9

🐛
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛 -
caesarkim

🐛 +
caesarkim

🐛
carolyujing

🐛
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛 -
cristalp

🐛 +
cristalp

🐛
crunsk

🐛
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛
d1ss0nanz

🐛
danbrycefairsailcom

🐛 -
dariansanity

🐛 +
dariansanity

🐛
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛
dinesh150

🐛 -
diziaq

🐛 +
diziaq

🐛
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛
ekkirala

🐛 -
emersonmoura

🐛 +
emersonmoura

🐛
fairy

🐛
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛
freafrea

🐛 -
fsapatin

🐛 +
fsapatin

🐛
gracia19

🐛
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛 -
henrik242

🐛 +
henrik242

🐛
hongpuwu

🐛
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛 -
jbennett2091

🐛 +
jbennett2091

🐛
jcamerin

🐛
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛 -
karwer

🐛 +
karwer

🐛
kaulonline

🐛
kdaemonv

🐛
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛
krzyk

🐛 -
lasselindqvist

🐛 +
lasselindqvist

🐛
lihuaib

🐛
lonelyma1021

🐛
lpeddy

🐛
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛 -
marcelmore

🐛 +
marcelmore

🐛
matchbox

🐛
matthiaskraaz

🐛
meandonlyme

🐛
mikesive

🐛
milossesic

🐛
mriddell95

🐛 -
mrlzh

🐛 +
mrlzh

🐛
msloan

🐛
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛 -
novsirion

🐛 +
novsirion

🐛
oggboy

🐛
oinume

🐛
orimarko

💻 🐛
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛 -
patriksevallius

🐛 +
patriksevallius

🐛
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛 -
pujitha8783

🐛 +
pujitha8783

🐛
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛 -
rijkt

🐛 +
rijkt

🐛
rillig-tk

🐛
rmohan20

💻 🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛 -
sebbASF

🐛 +
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛
snuyanzin

🐛 💻 -
sratz

🐛 +
sratz

🐛
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛
tashiscool

🐛 -
test-git-hook

🐛 +
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛
trentchilders

🐛 -
triandicAnt

🐛 +
triandicAnt

🐛
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛
wuchiuwong

🐛 -
xingsong

🐛 +
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛
yasuharu-sato

🐛 -
zenglian

🐛 +
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛
Árpád Magosányi

🐛 + +
任贵杰

🐛 From 8248f6e4e1f3bbda18fc924ed26bc58a10cfdd2b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 May 2022 11:49:51 +0200 Subject: [PATCH 38/38] Fix unit tests --- .../pmd/lang/cs/cpd/testdata/attributes.txt | 400 +++++++++--------- .../cs/cpd/testdata/attributes_ignored.txt | 182 ++++---- .../lang/go/cpd/testdata/sample_unicode.txt | 148 +++---- .../python/cpd/testdata/sample_unicode.txt | 18 +- .../python/cpd/testdata/var_with_dollar.txt | 18 +- 5 files changed, 383 insertions(+), 383 deletions(-) diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt index 403064af38..ec85e49500 100644 --- a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes.txt @@ -1,229 +1,229 @@ [Image] or [Truncated image[ Bcol Ecol L1 - [\[] 1 1 - [Serializable] 2 13 - [\]] 14 14 + [\[] 1 2 + [Serializable] 2 14 + [\]] 14 15 L2 - [public] 1 6 - [class] 8 12 - [SampleClass] 14 24 + [public] 1 7 + [class] 8 13 + [SampleClass] 14 25 L3 - [{] 1 1 + [{] 1 2 L5 - [}] 1 1 + [}] 1 2 L7 - [\[] 1 1 - [System] 2 7 - [.] 8 8 - [Runtime] 9 15 - [.] 16 16 - [InteropServices] 17 31 - [.] 32 32 - [DllImport] 33 41 - [(] 42 42 - ["user32.dll"] 43 54 - [)] 55 55 - [\]] 56 56 + [\[] 1 2 + [System] 2 8 + [.] 8 9 + [Runtime] 9 16 + [.] 16 17 + [InteropServices] 17 32 + [.] 32 33 + [DllImport] 33 42 + [(] 42 43 + ["user32.dll"] 43 55 + [)] 55 56 + [\]] 56 57 L8 - [extern] 1 6 - [static] 8 13 - [void] 15 18 - [SampleMethod] 20 31 - [(] 32 32 - [)] 33 33 - [;] 34 34 + [extern] 1 7 + [static] 8 14 + [void] 15 19 + [SampleMethod] 20 32 + [(] 32 33 + [)] 33 34 + [;] 34 35 L10 - [void] 1 4 - [MethodA] 6 12 - [(] 13 13 - [\[] 14 14 - [In] 15 16 - [\]] 17 17 - [\[] 18 18 - [Out] 19 21 - [\]] 22 22 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodA] 6 13 + [(] 13 14 + [\[] 14 15 + [In] 15 17 + [\]] 17 18 + [\[] 18 19 + [Out] 19 22 + [\]] 22 23 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L11 - [void] 1 4 - [MethodB] 6 12 - [(] 13 13 - [\[] 14 14 - [Out] 15 17 - [\]] 18 18 - [\[] 19 19 - [In] 20 21 - [\]] 22 22 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodB] 6 13 + [(] 13 14 + [\[] 14 15 + [Out] 15 18 + [\]] 18 19 + [\[] 19 20 + [In] 20 22 + [\]] 22 23 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L12 - [void] 1 4 - [MethodC] 6 12 - [(] 13 13 - [\[] 14 14 - [In] 15 16 - [,] 17 17 - [Out] 19 21 - [\]] 22 22 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodC] 6 13 + [(] 13 14 + [\[] 14 15 + [In] 15 17 + [,] 17 18 + [Out] 19 22 + [\]] 22 23 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L14 - [\[] 1 1 - [Conditional] 2 12 - [(] 13 13 - ["DEBUG"] 14 20 - [)] 21 21 - [,] 22 22 - [Conditional] 24 34 - [(] 35 35 - ["TEST1"] 36 42 - [)] 43 43 - [\]] 44 44 + [\[] 1 2 + [Conditional] 2 13 + [(] 13 14 + ["DEBUG"] 14 21 + [)] 21 22 + [,] 22 23 + [Conditional] 24 35 + [(] 35 36 + ["TEST1"] 36 43 + [)] 43 44 + [\]] 44 45 L15 - [void] 1 4 - [TraceMethod] 6 16 - [(] 17 17 - [)] 18 18 + [void] 1 5 + [TraceMethod] 6 17 + [(] 17 18 + [)] 18 19 L16 - [{] 1 1 + [{] 1 2 L18 - [}] 1 1 + [}] 1 2 L20 - [\[] 1 1 - [DllImport] 2 10 - [(] 11 11 - ["user32.dll"] 12 23 - [)] 24 24 - [\]] 25 25 + [\[] 1 2 + [DllImport] 2 11 + [(] 11 12 + ["user32.dll"] 12 24 + [)] 24 25 + [\]] 25 26 L21 - [\[] 1 1 - [DllImport] 2 10 - [(] 11 11 - ["user32.dll"] 12 23 - [,] 24 24 - [SetLastError] 26 37 - [=] 38 38 - [false] 39 43 - [,] 44 44 - [ExactSpelling] 46 58 - [=] 59 59 - [false] 60 64 - [)] 65 65 - [\]] 66 66 + [\[] 1 2 + [DllImport] 2 11 + [(] 11 12 + ["user32.dll"] 12 24 + [,] 24 25 + [SetLastError] 26 38 + [=] 38 39 + [false] 39 44 + [,] 44 45 + [ExactSpelling] 46 59 + [=] 59 60 + [false] 60 65 + [)] 65 66 + [\]] 66 67 L22 - [\[] 1 1 - [DllImport] 2 10 - [(] 11 11 - ["user32.dll"] 12 23 - [,] 24 24 - [ExactSpelling] 26 38 - [=] 39 39 - [false] 40 44 - [,] 45 45 - [SetLastError] 47 58 - [=] 59 59 - [false] 60 64 - [)] 65 65 - [\]] 66 66 + [\[] 1 2 + [DllImport] 2 11 + [(] 11 12 + ["user32.dll"] 12 24 + [,] 24 25 + [ExactSpelling] 26 39 + [=] 39 40 + [false] 40 45 + [,] 45 46 + [SetLastError] 47 59 + [=] 59 60 + [false] 60 65 + [)] 65 66 + [\]] 66 67 L24 - [using] 1 5 - [System] 7 12 - [;] 13 13 + [using] 1 6 + [System] 7 13 + [;] 13 14 L25 - [using] 1 5 - [System] 7 12 - [.] 13 13 - [Reflection] 14 23 - [;] 24 24 + [using] 1 6 + [System] 7 13 + [.] 13 14 + [Reflection] 14 24 + [;] 24 25 L26 - [\[] 1 1 - [assembly] 2 9 - [:] 10 10 - [AssemblyTitleAttribute] 12 33 - [(] 34 34 - ["Production assembly 4"] 35 57 - [)] 58 58 - [\]] 59 59 + [\[] 1 2 + [assembly] 2 10 + [:] 10 11 + [AssemblyTitleAttribute] 12 34 + [(] 34 35 + ["Production assembly 4"] 35 58 + [)] 58 59 + [\]] 59 60 L27 - [\[] 1 1 - [module] 2 7 - [:] 8 8 - [CLSCompliant] 10 21 - [(] 22 22 - [true] 23 26 - [)] 27 27 - [\]] 28 28 + [\[] 1 2 + [module] 2 8 + [:] 8 9 + [CLSCompliant] 10 22 + [(] 22 23 + [true] 23 27 + [)] 27 28 + [\]] 28 29 L30 - [\[] 1 1 - [ValidatedContract] 2 18 - [\]] 19 19 + [\[] 1 2 + [ValidatedContract] 2 19 + [\]] 19 20 L31 - [int] 1 3 - [Method1] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method1] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 L34 - [\[] 1 1 - [method] 2 7 - [:] 8 8 - [ValidatedContract] 10 26 - [\]] 27 27 + [\[] 1 2 + [method] 2 8 + [:] 8 9 + [ValidatedContract] 10 27 + [\]] 27 28 L35 - [int] 1 3 - [Method2] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method2] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 L38 - [int] 1 3 - [Method3] 5 11 - [(] 12 12 - [\[] 13 13 - [ValidatedContract] 14 30 - [\]] 31 31 - [string] 33 38 - [contract] 40 47 - [)] 48 48 - [{] 50 50 - [return] 52 57 - [0] 59 59 - [;] 60 60 - [}] 62 62 + [int] 1 4 + [Method3] 5 12 + [(] 12 13 + [\[] 13 14 + [ValidatedContract] 14 31 + [\]] 31 32 + [string] 33 39 + [contract] 40 48 + [)] 48 49 + [{] 50 51 + [return] 52 58 + [0] 59 60 + [;] 60 61 + [}] 62 63 L41 - [\[] 1 1 - [return] 2 7 - [:] 8 8 - [ValidatedContract] 10 26 - [\]] 27 27 + [\[] 1 2 + [return] 2 8 + [:] 8 9 + [ValidatedContract] 10 27 + [\]] 27 28 L42 - [int] 1 3 - [Method4] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method4] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 EOF diff --git a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt index 0796c4384c..c2de96f13f 100644 --- a/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt +++ b/pmd-cs/src/test/resources/net/sourceforge/pmd/lang/cs/cpd/testdata/attributes_ignored.txt @@ -1,109 +1,109 @@ [Image] or [Truncated image[ Bcol Ecol L2 - [public] 1 6 - [class] 8 12 - [SampleClass] 14 24 + [public] 1 7 + [class] 8 13 + [SampleClass] 14 25 L3 - [{] 1 1 + [{] 1 2 L5 - [}] 1 1 + [}] 1 2 L8 - [extern] 1 6 - [static] 8 13 - [void] 15 18 - [SampleMethod] 20 31 - [(] 32 32 - [)] 33 33 - [;] 34 34 + [extern] 1 7 + [static] 8 14 + [void] 15 19 + [SampleMethod] 20 32 + [(] 32 33 + [)] 33 34 + [;] 34 35 L10 - [void] 1 4 - [MethodA] 6 12 - [(] 13 13 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodA] 6 13 + [(] 13 14 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L11 - [void] 1 4 - [MethodB] 6 12 - [(] 13 13 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodB] 6 13 + [(] 13 14 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L12 - [void] 1 4 - [MethodC] 6 12 - [(] 13 13 - [ref] 24 26 - [double] 28 33 - [x] 35 35 - [)] 36 36 - [{] 38 38 - [}] 40 40 + [void] 1 5 + [MethodC] 6 13 + [(] 13 14 + [ref] 24 27 + [double] 28 34 + [x] 35 36 + [)] 36 37 + [{] 38 39 + [}] 40 41 L15 - [void] 1 4 - [TraceMethod] 6 16 - [(] 17 17 - [)] 18 18 + [void] 1 5 + [TraceMethod] 6 17 + [(] 17 18 + [)] 18 19 L16 - [{] 1 1 + [{] 1 2 L18 - [}] 1 1 + [}] 1 2 L24 - [using] 1 5 - [System] 7 12 - [;] 13 13 + [using] 1 6 + [System] 7 13 + [;] 13 14 L25 - [using] 1 5 - [System] 7 12 - [.] 13 13 - [Reflection] 14 23 - [;] 24 24 + [using] 1 6 + [System] 7 13 + [.] 13 14 + [Reflection] 14 24 + [;] 24 25 L31 - [int] 1 3 - [Method1] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method1] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 L35 - [int] 1 3 - [Method2] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method2] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 L38 - [int] 1 3 - [Method3] 5 11 - [(] 12 12 - [string] 33 38 - [contract] 40 47 - [)] 48 48 - [{] 50 50 - [return] 52 57 - [0] 59 59 - [;] 60 60 - [}] 62 62 + [int] 1 4 + [Method3] 5 12 + [(] 12 13 + [string] 33 39 + [contract] 40 48 + [)] 48 49 + [{] 50 51 + [return] 52 58 + [0] 59 60 + [;] 60 61 + [}] 62 63 L42 - [int] 1 3 - [Method4] 5 11 - [(] 12 12 - [)] 13 13 - [{] 15 15 - [return] 17 22 - [0] 24 24 - [;] 25 25 - [}] 27 27 + [int] 1 4 + [Method4] 5 12 + [(] 12 13 + [)] 13 14 + [{] 15 16 + [return] 17 23 + [0] 24 25 + [;] 25 26 + [}] 27 28 EOF diff --git a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt index f1b02aef86..ecc27507ff 100644 --- a/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt +++ b/pmd-go/src/test/resources/net/sourceforge/pmd/lang/go/cpd/testdata/sample_unicode.txt @@ -1,89 +1,89 @@ [Image] or [Truncated image[ Bcol Ecol L1 - [func] 1 4 - [main] 6 9 - [(] 10 10 - [)] 11 11 - [{] 13 13 + [func] 1 5 + [main] 6 10 + [(] 10 11 + [)] 11 12 + [{] 13 14 L3 - [str] 2 4 - [:=] 6 7 - ["hello world"] 9 21 + [str] 2 5 + [:=] 6 8 + ["hello world"] 9 22 L4 - [slice] 2 6 - [:=] 8 9 - [str] 11 13 - [\[] 14 14 - [4] 15 15 - [:] 16 16 - [\]] 17 17 + [slice] 2 7 + [:=] 8 10 + [str] 11 14 + [\[] 14 15 + [4] 15 16 + [:] 16 17 + [\]] 17 18 L5 - [fmt] 2 4 - [.] 5 5 - [Println] 6 12 - [(] 13 13 - [slice] 14 18 - [)] 19 19 + [fmt] 2 5 + [.] 5 6 + [Println] 6 13 + [(] 13 14 + [slice] 14 19 + [)] 19 20 L9 - [bytes] 2 6 - [:=] 8 9 - [\[] 11 11 - [\]] 12 12 - [byte] 13 16 - [(] 17 17 - [str] 18 20 - [)] 21 21 + [bytes] 2 7 + [:=] 8 10 + [\[] 11 12 + [\]] 12 13 + [byte] 13 17 + [(] 17 18 + [str] 18 21 + [)] 21 22 L10 - [bytes] 2 6 - [\[] 7 7 - [2] 8 8 - [\]] 9 9 - [=] 11 11 - ['x'] 13 15 + [bytes] 2 7 + [\[] 7 8 + [2] 8 9 + [\]] 9 10 + [=] 11 12 + ['x'] 13 16 L11 - [str] 2 4 - [=] 6 6 - [string] 8 13 - [(] 14 14 - [bytes] 15 19 - [)] 20 20 + [str] 2 5 + [=] 6 7 + [string] 8 14 + [(] 14 15 + [bytes] 15 20 + [)] 20 21 L12 - [fmt] 2 4 - [.] 5 5 - [Println] 6 12 - [(] 13 13 - [str] 14 16 - [)] 17 17 + [fmt] 2 5 + [.] 5 6 + [Println] 6 13 + [(] 13 14 + [str] 14 17 + [)] 17 18 L15 - [runes] 2 6 - [:=] 8 9 - [\[] 11 11 - [\]] 12 12 - [rune] 13 16 - [(] 17 17 - [str] 18 20 - [)] 21 21 + [runes] 2 7 + [:=] 8 10 + [\[] 11 12 + [\]] 12 13 + [rune] 13 17 + [(] 17 18 + [str] 18 21 + [)] 21 22 L16 - [runes] 2 6 - [\[] 7 7 - [0] 8 8 - [\]] 9 9 - [=] 11 11 - ['哈'] 13 15 + [runes] 2 7 + [\[] 7 8 + [0] 8 9 + [\]] 9 10 + [=] 11 12 + ['哈'] 13 16 L17 - [str] 2 4 - [=] 6 6 - [string] 8 13 - [(] 14 14 - [runes] 15 19 - [)] 20 20 + [str] 2 5 + [=] 6 7 + [string] 8 14 + [(] 14 15 + [runes] 15 20 + [)] 20 21 L18 - [fmt] 2 4 - [.] 5 5 - [Println] 6 12 - [(] 13 13 - [str] 14 16 - [)] 17 17 + [fmt] 2 5 + [.] 5 6 + [Println] 6 13 + [(] 13 14 + [str] 14 17 + [)] 17 18 L20 - [}] 1 1 + [}] 1 2 EOF diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt index 9476d45ba4..ec7d598bfc 100644 --- a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/sample_unicode.txt @@ -1,13 +1,13 @@ [Image] or [Truncated image[ Bcol Ecol L3 - [def] 1 3 - [check] 5 9 - [(] 10 10 - [)] 11 11 - [:] 12 12 + [def] 1 4 + [check] 5 10 + [(] 10 11 + [)] 11 12 + [:] 12 13 L4 - [total_cost_μs] 5 17 - [=] 19 19 - [\[] 21 21 - [\]] 22 22 + [total_cost_μs] 5 18 + [=] 19 20 + [\[] 21 22 + [\]] 22 23 EOF diff --git a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt index 39607ea38f..07eeb8ba7d 100644 --- a/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt +++ b/pmd-python/src/test/resources/net/sourceforge/pmd/lang/python/cpd/testdata/var_with_dollar.txt @@ -1,13 +1,13 @@ [Image] or [Truncated image[ Bcol Ecol L1 - [def] 1 3 - [check] 5 9 - [(] 10 10 - [)] 11 11 - [:] 12 12 + [def] 1 4 + [check] 5 10 + [(] 10 11 + [)] 11 12 + [:] 12 13 L2 - [a$a] 5 7 - [=] 9 9 - [\[] 11 11 - [\]] 12 12 + [a$a] 5 8 + [=] 9 10 + [\[] 11 12 + [\]] 12 13 EOF