This is an automated email from the ASF dual-hosted git repository. matthiasblaesing pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new ddf958d Rewrote "String::replaceAll with dot" inspection to apply to more methods and regex control characters. new 23437da Merge pull request #3218 from mbien/split ddf958d is described below commit ddf958dac900f776afeb8d1d19e93755c5e4212c Author: Michael Bien <mbie...@gmail.com> AuthorDate: Wed Oct 6 23:50:44 2021 +0200 Rewrote "String::replaceAll with dot" inspection to apply to more methods and regex control characters. --- .../modules/java/hints/bugs/Bundle.properties | 9 ++-- .../org/netbeans/modules/java/hints/bugs/Tiny.java | 52 ++++++++++++++++++---- .../modules/java/hints/bugs/Bundle_test.properties | 4 +- .../netbeans/modules/java/hints/bugs/TinyTest.java | 32 +++++++++++-- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Bundle.properties b/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Bundle.properties index aca26e7..aa59c26 100644 --- a/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Bundle.properties +++ b/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Bundle.properties @@ -25,10 +25,11 @@ DN_AnnotationsNotRuntime_instanceof={0} does not have runtime Retention, the con DN_org.netbeans.modules.java.hints.bugs.AnnotationsNotRuntime=Annotations without runtime Retention DESC_org.netbeans.modules.java.hints.bugs.AnnotationsNotRuntime=Warns about reflective access to annotations with CLASS or SOURCE retentions -DN_org.netbeans.modules.java.hints.bugs.Tiny.stringReplaceAllDot=String.replaceAll(".", ) -DESC_org.netbeans.modules.java.hints.bugs.Tiny.stringReplaceAllDot=Finds occurrences of calls to String.replaceAll(".", $target), which would replace all characters of the source string with $target. -ERR_string-replace-all-dot=Call to String.replaceAll(".", $target) is probably undesired -FIX_string-replace-all-dot=Replace with call to String.replaceAll("\\.", $target) +DN_org.netbeans.modules.java.hints.bugs.Tiny.singleCharRegex=Single Char Regex +DESC_org.netbeans.modules.java.hints.bugs.Tiny.singleCharRegex=Finds occurrences of single regex control characters \ + used as parameter for methods expecting regular expressions and quotes those. +ERR_single-char-regex=Using a single regex control character as regex is probably undesired +FIX_single-char-regex=Escape character for regex usage DN_org.netbeans.modules.java.hints.bugs.CastVSInstanceOf=Incompatible cast/instanceof DESC_org.netbeans.modules.java.hints.bugs.CastVSInstanceOf=Incompatible cast surrounded with incompatible instanceof diff --git a/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Tiny.java b/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Tiny.java index fcd1eb2..149bf3c 100644 --- a/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Tiny.java +++ b/java/java.hints/src/org/netbeans/modules/java/hints/bugs/Tiny.java @@ -29,6 +29,7 @@ import com.sun.source.tree.ForLoopTree; import com.sun.source.tree.IfTree; import com.sun.source.tree.LabeledStatementTree; import com.sun.source.tree.LineMap; +import com.sun.source.tree.LiteralTree; import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.tree.SwitchTree; @@ -91,18 +92,53 @@ import org.openide.util.NbBundle.Messages; }) public class Tiny { - @Hint(displayName = "#DN_org.netbeans.modules.java.hints.bugs.Tiny.stringReplaceAllDot", description = "#DESC_org.netbeans.modules.java.hints.bugs.Tiny.stringReplaceAllDot", category="bugs", suppressWarnings="ReplaceAllDot") - @TriggerPattern(value="$str.replaceAll(\".\", $to)", - constraints=@ConstraintVariableType(variable="$str", type="java.lang.String")) - public static ErrorDescription stringReplaceAllDot(HintContext ctx) { + @Hint(displayName = "#DN_org.netbeans.modules.java.hints.bugs.Tiny.singleCharRegex", description = "#DESC_org.netbeans.modules.java.hints.bugs.Tiny.singleCharRegex", category="bugs", suppressWarnings="SingleCharRegex") + @TriggerPatterns({ + @TriggerPattern(value="$str.replaceAll($pattern, $to)", + constraints = { + @ConstraintVariableType(variable="$str", type="java.lang.String"), + @ConstraintVariableType(variable="$pattern", type="java.lang.String") }), + @TriggerPattern(value = "$str.replaceFirst($pattern, $repl)", + constraints = { + @ConstraintVariableType(variable = "$str", type = "java.lang.String"), + @ConstraintVariableType(variable = "$pattern", type = "java.lang.String"), + @ConstraintVariableType(variable = "$repl", type = "java.lang.String") + }), + @TriggerPattern(value="$str.split($pattern)", + constraints = { + @ConstraintVariableType(variable="$str", type="java.lang.String"), + @ConstraintVariableType(variable="$pattern", type="java.lang.String") }), + @TriggerPattern(value = "$str.split($pattern, $limit)", + constraints = { + @ConstraintVariableType(variable = "$str", type = "java.lang.String"), + @ConstraintVariableType(variable = "$pattern", type = "java.lang.String"), + @ConstraintVariableType(variable = "$limit", type = "int") + }) + }) + public static ErrorDescription singleCharRegex(HintContext ctx) { Tree constant = ((MethodInvocationTree) ctx.getPath().getLeaf()).getArguments().get(0); TreePath constantTP = new TreePath(ctx.getPath(), constant); - String fixDisplayName = NbBundle.getMessage(Tiny.class, "FIX_string-replace-all-dot"); - Fix fix = JavaFixUtilities.rewriteFix(ctx, fixDisplayName, constantTP, "\"\\\\.\""); - String displayName = NbBundle.getMessage(Tiny.class, "ERR_string-replace-all-dot"); + if (constantTP.getLeaf().getKind() == Kind.STRING_LITERAL) { + + String value = (String) ((LiteralTree) constantTP.getLeaf()).getValue(); + + if (value != null && value.length() == 1 && isRegExControlCharacter(value.charAt(0))) { + + String fixDisplayName = NbBundle.getMessage(Tiny.class, "FIX_single-char-regex"); + String displayName = NbBundle.getMessage(Tiny.class, "ERR_single-char-regex"); + + Fix fix = JavaFixUtilities.rewriteFix(ctx, fixDisplayName, constantTP, "\"\\\\"+value.charAt(0)+"\""); + return ErrorDescriptionFactory.forTree(ctx, constant, displayName, fix); + } + } + + return null; + } - return ErrorDescriptionFactory.forTree(ctx, constant, displayName, fix); + private static boolean isRegExControlCharacter(char c) { + return c == '.' || c == '$' || c == '|' || c == '^' || c == '?' || c == '*' || c == '+' || c == '\\' + || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}'; } @Hint(displayName = "#DN_org.netbeans.modules.java.hints.bugs.Tiny.newObject", description = "#DESC_org.netbeans.modules.java.hints.bugs.Tiny.newObject", category="bugs", suppressWarnings="ResultOfObjectAllocationIgnored", options=Options.QUERY) diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/Bundle_test.properties b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/Bundle_test.properties index cb973d0..6b96fc8 100644 --- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/Bundle_test.properties +++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/Bundle_test.properties @@ -22,8 +22,8 @@ DN_AnnotationsNotRuntime_instanceof={0} instanceof DN_RegExp=Invalid regular expression ERR_CastVSInstanceOf=CastVSInstanceOf -ERR_string-replace-all-dot=ERR_string-replace-all-dot -FIX_string-replace-all-dot=FIX_string-replace-all-dot +ERR_single-char-regex=ERR_single-char-regex +FIX_single-char-regex=FIX_single-char-regex ERR_newObject=new Object diff --git a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/TinyTest.java b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/TinyTest.java index 8402374..824bfca 100644 --- a/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/TinyTest.java +++ b/java/java.hints/test/unit/src/org/netbeans/modules/java/hints/bugs/TinyTest.java @@ -38,7 +38,7 @@ public class TinyTest extends NbTestCase { super(name); } - public void testPositive1() throws Exception { + public void testSingleCharRegexPositive1() throws Exception { HintTest .create() .input("package test;\n" + @@ -48,8 +48,8 @@ public class TinyTest extends NbTestCase { " }\n" + "}\n") .run(Tiny.class) - .findWarning("3:23-3:26:verifier:ERR_string-replace-all-dot") - .applyFix("FIX_string-replace-all-dot") + .findWarning("3:23-3:26:verifier:ERR_single-char-regex") + .applyFix("FIX_single-char-regex") .assertCompilable() .assertOutput("package test;\n" + "public class Test {\n" + @@ -59,13 +59,37 @@ public class TinyTest extends NbTestCase { "}\n"); } - public void testNegative1() throws Exception { + public void testSingleCharRegexPositive2() throws Exception { + HintTest + .create() + .input("package test;\n" + + "public class Test {\n" + + " public void test(String[] args) {\n" + + " \"a\".split(\"$\");\n" + + " }\n" + + "}\n") + .run(Tiny.class) + .findWarning("3:18-3:21:verifier:ERR_single-char-regex") + .applyFix("FIX_single-char-regex") + .assertCompilable() + .assertOutput("package test;\n" + + "public class Test {\n" + + " public void test(String[] args) {\n" + + " \"a\".split(\"\\\\$\");\n" + + " }\n" + + "}\n"); + } + + public void testSingleCharRegexNegative1() throws Exception { HintTest .create() .input("package test;\n" + "public class Test {\n" + " public void test(String[] args) {\n" + " \"a\".replaceAll(\",\", \"/\");\n" + + " \"a\".replaceFirst(\"$$\", \"/\");\n" + + " String foo = \"foo\";\n" + + " \"a\".split(foo);\n" + " }\n" + "}\n") .run(Tiny.class) --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists