RegExp: report already defined group name

This commit is contained in:
Bas Leijdekkers
2017-06-06 09:06:46 +02:00
parent bec31c50f6
commit 751d7b6aaf
2 changed files with 16 additions and 0 deletions
@@ -20,7 +20,9 @@ import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.AnnotationSession;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
@@ -35,7 +37,9 @@ import org.intellij.lang.regexp.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public final class RegExpAnnotator extends RegExpElementVisitor implements Annotator {
@@ -43,6 +47,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph", "lower", "print", "punct", "space", "upper", "word", "xdigit");
private AnnotationHolder myHolder;
private final RegExpLanguageHosts myLanguageHosts;
private final Key<Map<String, RegExpGroup>> NAMED_GROUP_MAP = new Key<>("REG_EXP_NAMED_GROUP_MAP");
public RegExpAnnotator() {
myLanguageHosts = RegExpLanguageHosts.getInstance();
@@ -288,6 +293,13 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
final ASTNode node = group.getNode().findChildByType(RegExpTT.NAME);
if (node != null) myHolder.createErrorAnnotation(node, "Invalid group name");
}
final AnnotationSession session = myHolder.getCurrentAnnotationSession();
final Map<String, RegExpGroup> namedGroups = NAMED_GROUP_MAP.get(session, new HashMap<>());
if (namedGroups.isEmpty()) session.putUserData(NAMED_GROUP_MAP, namedGroups);
if (namedGroups.put(name, group) != null) {
final ASTNode node = group.getNode().findChildByType(RegExpTT.NAME);
if (node != null) myHolder.createErrorAnnotation(node, "Group with name '" + name + "' already defined");
}
final RegExpGroup.Type groupType = group.getType();
if (groupType == RegExpGroup.Type.POSITIVE_LOOKBEHIND || groupType == RegExpGroup.Type.NEGATIVE_LOOKBEHIND) {
final RegExpLanguageHost.Lookbehind support = myLanguageHosts.supportsLookbehind(group);
@@ -31,6 +31,10 @@ import org.jetbrains.annotations.NotNull;
@SuppressWarnings("Annotator")
public class RegExpHighlightingTest extends LightCodeInsightFixtureTestCase {
public void testDuplicateNamedGroup() {
doTest("(?<name>abc)(?<<error descr=\"Group with name 'name' already defined\">name</error>>xyz)");
}
public void testAnonymousCapturingGroupInspection() {
myFixture.enableInspections(new AnonymousGroupInspection());
doTest("<warning descr=\"Anonymous capturing group\">(</warning>moo)<warning descr=\"Numeric back reference\">\\1</warning>");