regexp: non-capturing group with closure on both inside and outside is not unnecessary (IDEA-262576)

GitOrigin-RevId: 26d0f01e218065b5203363edfda98f967aa1cadb
This commit is contained in:
Bas Leijdekkers
2021-02-20 14:42:25 +01:00
committed by intellij-monorepo-bot
parent 6429f60f86
commit 262fba73d0
2 changed files with 23 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.lang.regexp.inspection;
import com.intellij.codeInspection.LocalInspectionTool;
@@ -10,10 +10,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import org.intellij.lang.regexp.RegExpBundle;
import org.intellij.lang.regexp.psi.RegExpBranch;
import org.intellij.lang.regexp.psi.RegExpElementVisitor;
import org.intellij.lang.regexp.psi.RegExpGroup;
import org.intellij.lang.regexp.psi.RegExpPattern;
import org.intellij.lang.regexp.psi.*;
import org.jetbrains.annotations.NotNull;
/**
@@ -41,20 +38,23 @@ public class UnnecessaryNonCapturingGroupInspection extends LocalInspectionTool
return;
}
final PsiElement parent = group.getParent();
if (parent instanceof RegExpBranch) {
final RegExpAtom atom = getSingleAtom(group.getPattern());
if (atom != null) {
if (!(parent instanceof RegExpClosure) || !(atom instanceof RegExpClosure)) {
registerProblem(group);
}
}
else if (parent instanceof RegExpBranch) {
if (hasOneBranch(group.getPattern())) {
registerProblem(group);
}
else {
final PsiElement grandParent = parent.getParent();
if (grandParent instanceof RegExpPattern && hasSingleAtom((RegExpPattern)grandParent)) {
if (grandParent instanceof RegExpPattern && getSingleAtom((RegExpPattern)grandParent) != null) {
registerProblem(group);
}
}
}
else if (hasSingleAtom(group.getPattern())) {
registerProblem(group);
}
}
void registerProblem(RegExpGroup group) {
@@ -68,12 +68,12 @@ public class UnnecessaryNonCapturingGroupInspection extends LocalInspectionTool
return pattern != null && pattern.getBranches().length == 1;
}
private static boolean hasSingleAtom(RegExpPattern pattern) {
if (pattern == null) {
return false;
}
private static RegExpAtom getSingleAtom(RegExpPattern pattern) {
if (pattern == null) return null;
final RegExpBranch[] branches = pattern.getBranches();
return branches.length == 1 && branches[0].getAtoms().length == 1;
if (branches.length != 1) return null;
final RegExpAtom[] atoms = branches[0].getAtoms();
return atoms.length != 1 ? null : atoms[0];
}
private static class UnnecessaryNonCapturingGroupFix implements LocalQuickFix {

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.intellij.lang.regexp.inspection;
import com.intellij.codeInspection.LocalInspectionTool;
@@ -24,6 +24,13 @@ public class UnnecessaryNonCapturingGroupInspectionTest extends RegExpInspection
highlightTest("aa(?:bb|bbb)cccc");
}
public void testNoWarnOnNestedClosure() {
highlightTest("\\d{2}(?:\\d{3})?");
highlightTest("\\d{2}(?:\\d{3}){2}");
highlightTest("\\d{2}(?:\\d{3})+");
highlightTest("\\d{2}(?:\\d{3})*");
}
public void testTopLevelAlternation() {
quickfixTest("<warning descr=\"Unnecessary non-capturing group '(?:xx|xy)'\">(?:</warning>xx|xy)", "xx|xy",
RegExpBundle.message("inspection.quick.fix.remove.unnecessary.non.capturing.group"));