diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspection.java index dbbb1b79385c..250d7b195373 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspection.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspection.java @@ -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 { diff --git a/RegExpSupport/test/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspectionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspectionTest.java index d52594d50bea..b5610d72bf4d 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspectionTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/inspection/UnnecessaryNonCapturingGroupInspectionTest.java @@ -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("(?:xx|xy)", "xx|xy", RegExpBundle.message("inspection.quick.fix.remove.unnecessary.non.capturing.group"));