diff --git a/RegExpSupport/resources/META-INF/RegExpPlugin.xml b/RegExpSupport/resources/META-INF/RegExpPlugin.xml
index fcfc8b35f2f0..c2a96352bdd1 100644
--- a/RegExpSupport/resources/META-INF/RegExpPlugin.xml
+++ b/RegExpSupport/resources/META-INF/RegExpPlugin.xml
@@ -77,5 +77,8 @@
Example:
+
+ [a] [0-9] xx* [ah-hz]
+
+After the quick-fixes are applied:
+
+ a \d x+ [ahz]
+
+
+New in 2022.1
+
+
\ No newline at end of file
diff --git a/RegExpSupport/resources/messages/RegExpBundle.properties b/RegExpSupport/resources/messages/RegExpBundle.properties
index 2613f5e83cee..97c151baecb2 100644
--- a/RegExpSupport/resources/messages/RegExpBundle.properties
+++ b/RegExpSupport/resources/messages/RegExpBundle.properties
@@ -46,7 +46,6 @@ error.named.group.reference.not.allowed.inside.lookbehind=Named group reference
error.named.unicode.characters.are.not.allowed.in.this.regex.dialect=Named Unicode characters are not allowed in this regex dialect
error.nested.quantifier.in.regexp=Nested quantifier in regexp
error.property.escape.sequences.are.not.supported.in.this.regex.dialect=Property escape sequences are not supported in this regex dialect
-error.redundant.character.range=Redundant character range
error.redundant.group.nesting=Redundant group nesting
error.repetition.value.too.large=Repetition value too large
error.this.boundary.is.not.supported.in.this.regex.dialect=This boundary is not supported in this regex dialect
@@ -75,6 +74,7 @@ inspection.name.escaped.meta.character=Escaped meta character
inspection.name.octal.escape=Octal escape
inspection.name.redundant.character.escape=Redundant character escape
inspection.name.redundant.nested.character.class=Redundant nested character class
+inspection.name.simplifiable.expression=Regular expression can be simplified
inspection.name.single.character.alternation=Single character alternation
inspection.name.suspicious.backref=Suspicious back reference
inspection.name.unnecessary.non.capturing.group=Unnecessary non-capturing group
@@ -92,6 +92,8 @@ inspection.quick.fix.replace.with.hexadecimal.escape=Replace with hexadecimal es
inspection.quick.fix.replace.with.space.and.repeated.quantifier=Replace with space and repeated quantifier
inspection.warning.anchor.code.ref.code.in.unexpected.position=Anchor #ref in unexpected position
inspection.warning.anonymous.capturing.group=Anonymous capturing group
+inspection.warning.can.be.removed=#ref is redundant
+inspection.warning.can.be.simplified=#ref can be simplified to ''{0}''
inspection.warning.consecutive.spaces.in.regexp={0} consecutive spaces in RegExp
inspection.warning.duplicate.branch.in.alternation=Duplicate branch in alternation
inspection.warning.empty.branch.in.alternation=Empty branch in alternation
@@ -106,7 +108,6 @@ inspection.warning.redundant.nested.character.class=Redundant nested character c
inspection.warning.single.character.alternation.in.regexp=Single character alternation in RegExp
inspection.warning.unnecessary.non.capturing.group=Unnecessary non-capturing group {0}
intention.name.check.regexp=Check RegExp
-intention.name.simplify.quantifier=Simplify quantifier
label.regexp=&RegExp:
label.sample=&Sample:
parse.error.category.shorthand.not.allowed.in.this.regular.expression.dialect=Category shorthand not allowed in this regular expression dialect
@@ -156,6 +157,3 @@ tooltip.no.match=Expression and example do not match
tooltip.pattern.is.too.complex=Regular expression pattern is too complex
warning.duplicate.character.0.inside.character.class=Duplicate character ''{0}'' inside character class
warning.duplicate.predefined.character.class.0.inside.character.class=Duplicate predefined character class ''{0}'' inside character class
-weak.warning.fixed.repetition.range=Fixed repetition range
-weak.warning.repetition.range.replaceable.by.0=Repetition range replaceable by ''{0}''
-weak.warning.single.repetition=Single repetition
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpReplacementUtil.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpReplacementUtil.java
index 584e96eee881..fb4313a3c568 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpReplacementUtil.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpReplacementUtil.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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.lang.regexp.inspection;
import com.intellij.lang.injection.InjectedLanguageManager;
@@ -27,12 +27,22 @@ public final class RegExpReplacementUtil {
private RegExpReplacementUtil() {}
public static void replaceInContext(@NotNull PsiElement element, @NotNull String text) {
+ replaceInContext(element, text, null);
+ }
+
+ public static void replaceInContext(@NotNull PsiElement element, @NotNull String text, TextRange range) {
final PsiFile file = element.getContainingFile();
text = escapeForContext(text, file);
final Document document = file.getViewProvider().getDocument();
assert document != null;
final TextRange replaceRange = element.getTextRange();
- document.replaceString(replaceRange.getStartOffset(), replaceRange.getEndOffset(), text);
+ final int startOffset = replaceRange.getStartOffset();
+ if (range != null) {
+ document.replaceString(startOffset + range.getStartOffset(), startOffset + range.getEndOffset(), text);
+ }
+ else {
+ document.replaceString(startOffset, replaceRange.getEndOffset(), text);
+ }
}
private static String escapeForContext(String text, PsiFile file) {
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java
new file mode 100644
index 000000000000..e42b0abfd088
--- /dev/null
+++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/RegExpSimplifiableInspection.java
@@ -0,0 +1,317 @@
+// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.intellij.lang.regexp.inspection;
+
+import com.intellij.codeInspection.*;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.intellij.lang.regexp.RegExpBundle;
+import org.intellij.lang.regexp.RegExpTT;
+import org.intellij.lang.regexp.psi.*;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class RegExpSimplifiableInspection extends LocalInspectionTool {
+
+ @Override
+ public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder,
+ boolean isOnTheFly) {
+ return new RegExpSimplifiableVisitor(holder);
+ }
+
+ private static class RegExpSimplifiableVisitor extends RegExpElementVisitor {
+ private final ProblemsHolder myHolder;
+
+ RegExpSimplifiableVisitor(@NotNull ProblemsHolder holder) {
+ super();
+ myHolder = holder;
+ }
+
+ @Override
+ public void visitRegExpClass(RegExpClass regExpClass) {
+ super.visitRegExpClass(regExpClass);
+ final RegExpClassElement[] elements = regExpClass.getElements();
+ for (RegExpClassElement element : elements) {
+ if (element instanceof RegExpCharRange) {
+ final RegExpCharRange range = (RegExpCharRange)element;
+ final int from = range.getFrom().getValue();
+ final RegExpChar to = range.getTo();
+ if (from != -1 && to != null && from == to.getValue()) {
+ // [a-abc] -> [abc]
+ registerProblem(range, to.getUnescapedText());
+ }
+ }
+ }
+ if (regExpClass.isNegated()) {
+ if (elements.length == 1) {
+ final RegExpClassElement element = elements[0];
+ if (element instanceof RegExpSimpleClass) {
+ final RegExpSimpleClass simpleClass = (RegExpSimpleClass)element;
+ final String text = getInverseSimpleClassText(simpleClass);
+ if (text != null) {
+ // [^\d] -> \D
+ 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 {
+ if (elements.length == 1) {
+ final RegExpClassElement element = elements[0];
+ if (!(element instanceof RegExpCharRange)) {
+ if (!(element instanceof RegExpChar) || !"{}().*+?|$".contains(element.getText())) {
+ // [a] -> a
+ 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");
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitRegExpClosure(RegExpClosure closure) {
+ super.visitRegExpClosure(closure);
+ ASTNode token = closure.getQuantifier().getToken();
+ if (token == null || token.getElementType() != RegExpTT.STAR) {
+ return;
+ }
+ PsiElement sibling = closure.getPrevSibling();
+ RegExpAtom atom = closure.getAtom();
+ 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()),
+ RegExpBundle.message("inspection.warning.can.be.simplified", text),
+ new RegExpSimplifiableFix(text));
+ }
+ }
+
+ @Override
+ public void visitRegExpProperty(RegExpProperty property) {
+ super.visitRegExpProperty(property);
+ final ASTNode categoryNode = property.getCategoryNode();
+ if (categoryNode == null) {
+ return;
+ }
+ final String category = categoryNode.getText();
+ if ("Digit".equals(category) || "IsDigit".equals(category)) {
+ registerProblem(property, property.isNegated() ? "\\D" : "\\d");
+ }
+ else if ("Blank".equals(category) || "IsBlank".equals(category)) {
+ registerProblem(property, property.isNegated() ? "[^ \\t]" : "[ \\t]");
+ }
+ else if ("Space".equals(category) || "IsSpace".equals(category) ||
+ "IsWhite_Space".equals(category) || "IsWhiteSpace".equals(category)) {
+ registerProblem(property, property.isNegated() ? "\\S" : "\\s");
+ }
+ }
+
+ @Override
+ public void visitRegExpQuantifier(RegExpQuantifier quantifier) {
+ if (!quantifier.isCounted()) {
+ return;
+ }
+ final RegExpNumber minElement = quantifier.getMin();
+ final String min = minElement == null ? "" : minElement.getText();
+ final RegExpNumber maxElement = quantifier.getMax();
+ final String max = maxElement == null ? "" : maxElement.getText();
+ if (!max.isEmpty() && max.equals(min)) {
+ if ("1".equals(max)) {
+ myHolder.registerProblem(quantifier,
+ RegExpBundle.message("inspection.warning.can.be.removed"),
+ new RegExpSimplifiableFix(quantifier.getText(), true));
+ }
+ else {
+ final ASTNode node = quantifier.getNode();
+ if (node.findChildByType(RegExpTT.COMMA) != null) {
+ registerProblem(quantifier, "{" + max + "}");
+ }
+ }
+ }
+ else if (("0".equals(min) || min.isEmpty()) && "1".equals(max)) {
+ registerProblem(quantifier, "?");
+ }
+ else if (("0".equals(min) || min.isEmpty()) && max.isEmpty()) {
+ registerProblem(quantifier, "*");
+ }
+ else if ("1".equals(min) && max.isEmpty()) {
+ registerProblem(quantifier, "+");
+ }
+ }
+
+ private void registerProblem(RegExpElement element, String replacement) {
+ myHolder.registerProblem(element,
+ RegExpBundle.message("inspection.warning.can.be.simplified", replacement),
+ new RegExpSimplifiableFix(replacement));
+ }
+
+ private static boolean containsGroup(RegExpAtom atom) {
+ 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:
+ return "\\D";
+ case NON_DIGIT:
+ return "\\d";
+ case WORD:
+ return "\\W";
+ case NON_WORD:
+ return "\\w";
+ case SPACE:
+ return "\\S";
+ case NON_SPACE:
+ return "\\s";
+ case HORIZONTAL_SPACE:
+ return "\\H";
+ case NON_HORIZONTAL_SPACE:
+ return "\\h";
+ case VERTICAL_SPACE:
+ return "\\V";
+ case NON_VERTICAL_SPACE:
+ return "\\v";
+ case XML_NAME_START:
+ return "\\I";
+ case NON_XML_NAME_START:
+ return "\\i";
+ case XML_NAME_PART:
+ return "\\C";
+ case NON_XML_NAME_PART:
+ return "\\c";
+ default:
+ return null;
+ }
+ }
+
+ private static class RegExpSimplifiableFix implements LocalQuickFix {
+ private final String myExpression;
+ private final boolean myDelete;
+
+ RegExpSimplifiableFix(String newExpression) {
+ this(newExpression, false);
+ }
+
+ RegExpSimplifiableFix(String expression, boolean delete) {
+ myExpression = expression;
+ myDelete = delete;
+ }
+
+ @Override
+ public @NotNull String getFamilyName() {
+ return CommonQuickFixBundle.message("fix.simplify");
+ }
+
+ @Override
+ public @NotNull String getName() {
+ return myDelete
+ ? CommonQuickFixBundle.message("fix.remove", myExpression)
+ : CommonQuickFixBundle.message("fix.replace.with.x", myExpression);
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiElement element = descriptor.getPsiElement();
+ if (!(element instanceof RegExpElement)) {
+ return;
+ }
+ RegExpReplacementUtil.replaceInContext(element, myDelete ? "" : myExpression, descriptor.getTextRangeInElement());
+ }
+ }
+ }
+}
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java
index f022e15f81b6..5173aa9334bc 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java
@@ -103,9 +103,6 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
if (toCodePoint < fromCodePoint) {
myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.illegal.character.range.to.from")).range(range).create();
}
- else if (toCodePoint == fromCodePoint) {
- myHolder.newAnnotation(HighlightSeverity.WARNING, RegExpBundle.message("error.redundant.character.range")).range(range).create();
- }
}
@Override
@@ -368,34 +365,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
public void visitRegExpQuantifier(RegExpQuantifier quantifier) {
if (quantifier.isCounted()) {
final RegExpNumber minElement = quantifier.getMin();
- final String min = minElement == null ? "" : minElement.getText();
final RegExpNumber maxElement = quantifier.getMax();
- final String max = maxElement == null ? "" : maxElement.getText();
- if (!max.isEmpty() && max.equals(min)) {
- if ("1".equals(max)) {
- myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, RegExpBundle.message("weak.warning.single.repetition"))
- .withFix(new SimplifyQuantifierAction(quantifier, null)).create();
- }
- else {
- final ASTNode node = quantifier.getNode();
- if (node.findChildByType(RegExpTT.COMMA) != null) {
- myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, RegExpBundle.message("weak.warning.fixed.repetition.range"))
- .withFix(new SimplifyQuantifierAction(quantifier, "{" + max + "}")).create();
- }
- }
- }
- else if (("0".equals(min) || min.isEmpty()) && "1".equals(max)) {
- myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, RegExpBundle.message("weak.warning.repetition.range.replaceable.by.0", "?"))
- .withFix(new SimplifyQuantifierAction(quantifier, "?")).create();
- }
- else if (("0".equals(min) || min.isEmpty()) && max.isEmpty()) {
- myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, RegExpBundle.message("weak.warning.repetition.range.replaceable.by.0", "*"))
- .withFix(new SimplifyQuantifierAction(quantifier, "*")).create();
- }
- else if ("1".equals(min) && max.isEmpty()) {
- myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, RegExpBundle.message("weak.warning.repetition.range.replaceable.by.0", "+"))
- .withFix(new SimplifyQuantifierAction(quantifier, "+")).create();
- }
Number minValue = null;
if (minElement != null) {
minValue = myLanguageHosts.getQuantifierValue(minElement);
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/SimplifyQuantifierAction.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/SimplifyQuantifierAction.java
deleted file mode 100644
index d0897b676697..000000000000
--- a/RegExpSupport/src/org/intellij/lang/regexp/validation/SimplifyQuantifierAction.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.lang.regexp.validation;
-
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.CommonQuickFixBundle;
-import com.intellij.lang.ASTNode;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiFileFactory;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.IncorrectOperationException;
-import org.intellij.lang.regexp.RegExpBundle;
-import org.intellij.lang.regexp.RegExpFileType;
-import org.intellij.lang.regexp.inspection.RegExpReplacementUtil;
-import org.intellij.lang.regexp.psi.RegExpClosure;
-import org.intellij.lang.regexp.psi.RegExpPattern;
-import org.intellij.lang.regexp.psi.RegExpQuantifier;
-import org.jetbrains.annotations.NotNull;
-
-class SimplifyQuantifierAction implements IntentionAction {
- private final RegExpQuantifier myQuantifier;
- private final String myReplacement;
-
- SimplifyQuantifierAction(RegExpQuantifier quantifier, String s) {
- myQuantifier = quantifier;
- myReplacement = s;
- }
-
- @Override
- @NotNull
- public String getText() {
- return myReplacement == null ?
- CommonQuickFixBundle.message("fix.remove", "{1,1}") :
- CommonQuickFixBundle.message("fix.replace.with.x", myReplacement);
- }
-
- @Override
- @NotNull
- public String getFamilyName() {
- return RegExpBundle.message("intention.name.simplify.quantifier");
- }
-
- @Override
- public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
- return myQuantifier.isValid();
- }
-
- @Override
- public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
- if (myReplacement == null) {
- PsiElement parent = myQuantifier.getParent();
- if (!(parent instanceof RegExpClosure)) {
- return;
- }
- RegExpClosure closure = (RegExpClosure)parent;
- RegExpReplacementUtil.replaceInContext(closure, closure.getAtom().getUnescapedText());
- } else {
- final PsiFileFactory factory = PsiFileFactory.getInstance(project);
-
- final ASTNode modifier = myQuantifier.getModifier();
- final PsiFile f = factory.createFileFromText("dummy.regexp", RegExpFileType.INSTANCE,
- "a" + myReplacement + (modifier != null ? modifier.getText() : ""));
- final RegExpPattern pattern = PsiTreeUtil.getChildOfType(f, RegExpPattern.class);
- assert pattern != null;
-
- final RegExpClosure closure = (RegExpClosure)pattern.getBranches()[0].getAtoms()[0];
- myQuantifier.replace(closure.getQuantifier());
- }
- }
-
- @Override
- public boolean startInWriteAction() {
- return true;
- }
-}
diff --git a/RegExpSupport/test/org/intellij/lang/regexp/inspection/DuplicateAlternationBranchInspectionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/inspection/DuplicateAlternationBranchInspectionTest.java
index a0c5c08ed1d7..21c68d872920 100644
--- a/RegExpSupport/test/org/intellij/lang/regexp/inspection/DuplicateAlternationBranchInspectionTest.java
+++ b/RegExpSupport/test/org/intellij/lang/regexp/inspection/DuplicateAlternationBranchInspectionTest.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2018 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-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.intellij.lang.regexp.inspection;
import com.intellij.codeInspection.LocalInspectionTool;
@@ -15,7 +15,7 @@ public class DuplicateAlternationBranchInspectionTest extends RegExpInspectionTe
}
public void testMoreBranches() {
- quickfixTest("