RegExp: don't warn about redundant nested character classes when negated (IDEA-242520)

because class negation behaviour changed between JDK 8 and JDK 9

GitOrigin-RevId: eb9bf0c636d17a98aac1a40a7376c13c65ef4999
This commit is contained in:
Bas Leijdekkers
2020-06-18 16:49:53 +02:00
committed by intellij-monorepo-bot
parent e5ca7439a6
commit 8f2deb4c60
2 changed files with 25 additions and 6 deletions

View File

@@ -38,9 +38,14 @@ public class RedundantNestedCharacterClassInspection extends LocalInspectionTool
public void visitRegExpClass(RegExpClass regExpClass) {
super.visitRegExpClass(regExpClass);
final PsiElement parent = regExpClass.getParent();
// In JDK 9 the behaviour of negated character classes was changed, so we can never warn about them
// JDK 8: [^a&&b] is the intersection of [^a] with [b], which equals [b]
// JDK 9: [^a&&b] is the intersection of [a] and [b] (which is nothing), inverted, which equals everything.
// see https://bugs.openjdk.java.net/browse/JDK-8189343
// and http://mail.openjdk.java.net/pipermail/core-libs-dev/2011-June/006957.html
if (parent instanceof RegExpClass) {
final RegExpClass parentClass = (RegExpClass)parent;
if (parentClass.isNegated() == regExpClass.isNegated()) {
if (!parentClass.isNegated() && !regExpClass.isNegated()) {
myHolder.registerProblem(regExpClass.getFirstChild(), RegExpBundle.message("inspection.warning.redundant.nested.character.class"),
new RedundantNestedCharacterClassFix());
}
@@ -48,8 +53,8 @@ public class RedundantNestedCharacterClassInspection extends LocalInspectionTool
else if (parent instanceof RegExpIntersection) {
final PsiElement grandParent = parent.getParent();
if (grandParent instanceof RegExpClass) {
final RegExpClass parentClass = (RegExpClass)grandParent;
if (parentClass.isNegated() == regExpClass.isNegated()) {
final RegExpClass grandparentClass = (RegExpClass)grandParent;
if (!grandparentClass.isNegated() && !regExpClass.isNegated()) {
myHolder.registerProblem(regExpClass.getFirstChild(), RegExpBundle.message("inspection.warning.redundant.nested.character.class"),
new RedundantNestedCharacterClassFix());
}

View File

@@ -8,6 +8,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author Bas Leijdekkers
*/
@SuppressWarnings({"RegExpDuplicateCharacterInClass", "RegExpRedundantNestedCharacterClass"})
public class RedundantNestedCharacterClassInspectionTest extends RegExpInspectionTestCase {
public void testConjunction() {
@@ -21,12 +22,25 @@ public class RedundantNestedCharacterClassInspectionTest extends RegExpInspectio
}
public void testNegation() {
quickfixTest("[^*=<warning descr=\"Redundant nested character class\"><caret>[</warning>^&]]", "[^*=&]",
RegExpBundle.message("inspection.quick.fix.replace.redundant.character.class.with.contents"));
highlightTest("[^abc[^cde]]");
// JDK 8: conjunction of inverted [abc] and inverted [cde], which equals inverted [c]
// JDK 9: the inverse of the conjunction of [abc] and inverted [cde], which equals the inverse of inverted [de], which is [de]
}
public void testNoWarn() {
highlightTest("[a-z&&[^aeouiy]]" );
highlightTest("[a-z&&[^aeouiy]]" ); // intersection of [a-z] with [aeouiy] inverted, which equals the alphabet except vowels
}
public void testNoWarn2() {
highlightTest("[^a[abc]]");
// JDK 8: conjunction of inverted [a] and [abc], which equals [bc]
// JDK 9: inverted conjunction of [a] and [abc], which equals inverted [abc]
}
public void testNegatedIntersection() {
highlightTest("[^a&&[^abc]]");
// JDK 8: intersection of inverted [a] and inverted [abc], which equals inverted [abc]
// JDK 9: inverted intersection of [a] and inverted [abc], which equals inverted empty class, which matches everything
}