mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
RegExp: don't suggests simplifying replacements that are not equivalent in Unicode mode (IDEA-290490)
GitOrigin-RevId: cb85ddaee91cb6ff13596603e10fce7a55eac07c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d213a56e85
commit
be71678b09
@@ -3,11 +3,11 @@
|
||||
Reports regular expressions that can be simplified.
|
||||
<p><b>Example:</b></p>
|
||||
<pre><code>
|
||||
[a] [0-9] xx* [ah-hz]
|
||||
[a] xx* [ah-hz]
|
||||
</code></pre>
|
||||
<p>After the quick-fix is applied:</p>
|
||||
<pre><code>
|
||||
a \d x+ [ahz]
|
||||
a x+ [ahz]
|
||||
</code></pre>
|
||||
<!-- tooltip end -->
|
||||
<p><small>New in 2022.1</small>
|
||||
|
||||
+2
-94
@@ -19,8 +19,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
|
||||
@Override
|
||||
public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
|
||||
boolean isOnTheFly) {
|
||||
public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new RegExpSimplifiableVisitor(holder);
|
||||
}
|
||||
|
||||
@@ -28,7 +27,6 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
private final ProblemsHolder myHolder;
|
||||
|
||||
RegExpSimplifiableVisitor(@NotNull ProblemsHolder holder) {
|
||||
super();
|
||||
myHolder = holder;
|
||||
}
|
||||
|
||||
@@ -58,23 +56,6 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
registerProblem(regExpClass, text);
|
||||
}
|
||||
}
|
||||
else if (isDigitRange(element)) {
|
||||
// [^0-9] -> \D
|
||||
registerProblem(regExpClass, "\\D");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isWordCharClassExpression(elements)) {
|
||||
// [^0-9a-zA-Z_] -> \W
|
||||
registerProblem(regExpClass, "\\W");
|
||||
return;
|
||||
}
|
||||
for (RegExpClassElement element : elements) {
|
||||
if (isDigitRange(element)) {
|
||||
// [^0-9abc] -> [^\dabc]
|
||||
registerProblem(element, "\\d");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -87,25 +68,6 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
registerProblem(regExpClass, element.getUnescapedText());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isDigitRange(element)) {
|
||||
// [0-9] -> \d
|
||||
registerProblem(regExpClass, "\\d");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isWordCharClassExpression(elements)) {
|
||||
// [0-9a-zA-Z_] -> \w
|
||||
registerProblem(regExpClass, "\\w");
|
||||
return;
|
||||
}
|
||||
for (RegExpClassElement element : elements) {
|
||||
// [0-9abc] -> [\dabc]
|
||||
if (isDigitRange(element)) {
|
||||
registerProblem(element, "\\d");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +81,7 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
}
|
||||
PsiElement sibling = closure.getPrevSibling();
|
||||
RegExpAtom atom = closure.getAtom();
|
||||
if (sibling instanceof RegExpElement && atom.getClass() == sibling.getClass() && sibling.textMatches(atom) && !containsGroup(atom)) {
|
||||
if (sibling instanceof RegExpElement && atom.getClass() == sibling.getClass() && sibling.textMatches(atom) && !containsGroup(atom)) {
|
||||
final String text = atom.getUnescapedText() + '+';
|
||||
myHolder.registerProblem(closure.getParent(),
|
||||
TextRange.from(sibling.getStartOffsetInParent(), sibling.getTextLength() + closure.getTextLength()),
|
||||
@@ -191,60 +153,6 @@ public class RegExpSimplifiableInspection extends LocalInspectionTool {
|
||||
return atom instanceof RegExpGroup || PsiTreeUtil.findChildOfType(atom, RegExpGroup.class) != null;
|
||||
}
|
||||
|
||||
private static boolean isDigitRange(RegExpElement element) {
|
||||
if (!(element instanceof RegExpCharRange)) {
|
||||
return false;
|
||||
}
|
||||
final RegExpCharRange charRange = (RegExpCharRange)element;
|
||||
final RegExpChar from = charRange.getFrom();
|
||||
final RegExpChar to = charRange.getTo();
|
||||
return from.getValue() == '0' && to != null && to.getValue() == '9';
|
||||
}
|
||||
|
||||
private static boolean isWordCharClassExpression(RegExpClassElement[] elements) {
|
||||
if (elements.length != 4) {
|
||||
return false;
|
||||
}
|
||||
boolean lowerCaseChars = false;
|
||||
boolean upperCaseChars = false;
|
||||
boolean digits = false;
|
||||
boolean underscore = false;
|
||||
for (RegExpClassElement element : elements) {
|
||||
if (element instanceof RegExpChar) {
|
||||
final RegExpChar aChar = (RegExpChar)element;
|
||||
if (aChar.getValue() == '_') {
|
||||
underscore = true;
|
||||
}
|
||||
}
|
||||
else if (element instanceof RegExpSimpleClass) {
|
||||
final RegExpSimpleClass simpleClass = (RegExpSimpleClass)element;
|
||||
if (simpleClass.getKind() == RegExpSimpleClass.Kind.DIGIT) {
|
||||
digits = true;
|
||||
}
|
||||
}
|
||||
else if (element instanceof RegExpCharRange) {
|
||||
final RegExpCharRange range = (RegExpCharRange)element;
|
||||
final RegExpChar from = range.getFrom();
|
||||
final RegExpChar to = range.getTo();
|
||||
if (to == null) {
|
||||
break;
|
||||
}
|
||||
final int fromValue = from.getValue();
|
||||
final int toValue = to.getValue();
|
||||
if (fromValue == '0' && toValue == '9') {
|
||||
digits = true;
|
||||
}
|
||||
else if (fromValue == 'A' && toValue == 'Z') {
|
||||
upperCaseChars = true;
|
||||
}
|
||||
else if (fromValue == 'a' && toValue == 'z') {
|
||||
lowerCaseChars = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return underscore && digits && lowerCaseChars && upperCaseChars;
|
||||
}
|
||||
|
||||
private static String getInverseSimpleClassText(RegExpSimpleClass simpleClass) {
|
||||
switch (simpleClass.getKind()) {
|
||||
case DIGIT:
|
||||
|
||||
+10
-6
@@ -22,19 +22,19 @@ public class RegExpSimplifiableInspectionTest extends RegExpInspectionTestCase {
|
||||
}
|
||||
|
||||
public void testNegatedDigitRange() {
|
||||
doTest("[^0-9]", "\\D");
|
||||
highlightTest("[^0-9]"); // no warn; replacing with \D is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testNegatedWordClassCharExpression() {
|
||||
doTest("[^0-9a-zA-Z_]", "\\W");
|
||||
highlightTest("[^0-9a-zA-Z_]"); // no warn; replacing with \W is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testDigitRange() {
|
||||
doTest("[^0-9abc]", 2, 3, "\\d", "[^\\dabc]");
|
||||
highlightTest("[^0-9abc]"); // no warn; replacing with [^\dabc] is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testDigitRange2() {
|
||||
doTest("[0-9abc]", 1, 3, "\\d", "[\\dabc]");
|
||||
highlightTest("[0-9abc]"); // no warn; replacing with \d is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testSingleElementClass() {
|
||||
@@ -46,11 +46,15 @@ public class RegExpSimplifiableInspectionTest extends RegExpInspectionTestCase {
|
||||
}
|
||||
|
||||
public void testSimpleDigitRange() {
|
||||
doTest("[0-9]", "\\d");
|
||||
highlightTest("[0-9]"); // no warn; replacing with \d is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testWordCharClassExpression() {
|
||||
doTest("[0-9a-zA-Z_]", "\\w");
|
||||
highlightTest("[0-9a-zA-Z_]"); // no warn; replacing with \w is not equivalent in Unicode context
|
||||
}
|
||||
|
||||
public void testProperty() {
|
||||
doTest("\\p{IsDigit}", "\\d");
|
||||
}
|
||||
|
||||
public void testStarToPlusNoWarm() {
|
||||
|
||||
Reference in New Issue
Block a user