From 517eb364017811fb14b6f0df68d4d752045a04d2 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 9 Jan 2020 13:38:30 +0300 Subject: [PATCH] port regexp to the new Annotator APIDefault GitOrigin-RevId: 1b23390720da9f36a634303498e1ebfeff5d8d48 --- .../regexp/validation/RegExpAnnotator.java | 128 +++++++++--------- .../config/ui/ValueRegExpAnnotator.java | 3 +- 2 files changed, 64 insertions(+), 67 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index a234101920df..f18588056dfe 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -18,10 +18,7 @@ package org.intellij.lang.regexp.validation; import com.intellij.codeInsight.intention.IntentionAction; 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.lang.annotation.*; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiComment; @@ -81,7 +78,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot final int c = text.codePointAt(i); if (!Character.isBmpCodePoint(c) || !myLanguageHosts.supportsInlineOptionFlag((char)c, options)) { final int offset = options.getTextOffset() + i; - myHolder.createErrorAnnotation(new TextRange(offset, offset + 1), "Unknown inline option flag"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown inline option flag").range(new TextRange(offset, offset + 1)).create(); } } } @@ -90,12 +87,11 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot public void visitRegExpCharRange(RegExpCharRange range) { final RegExpChar from = range.getFrom(); final RegExpChar to = range.getTo(); - if (to != null) { - checkRange(range, from.getValue(), to.getValue()); + if (to == null) { + return; } - } - - private void checkRange(RegExpCharRange range, int fromCodePoint, int toCodePoint) { + int fromCodePoint = from.getValue(); + int toCodePoint = to.getValue(); if (fromCodePoint == -1 || toCodePoint == -1) { return; } @@ -133,14 +129,14 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpBoundary(RegExpBoundary boundary) { if (!myLanguageHosts.supportsBoundary(boundary)) { - myHolder.createErrorAnnotation(boundary, "This boundary is not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "This boundary is not supported in this regex dialect").create(); } } @Override public void visitSimpleClass(RegExpSimpleClass simpleClass) { if (!myLanguageHosts.supportsSimpleClass(simpleClass)) { - myHolder.createErrorAnnotation(simpleClass, "Illegal/unsupported escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal/unsupported escape sequence").create(); } } @@ -156,15 +152,15 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot final RegExpChar regExpChar = (RegExpChar)element; final int value = regExpChar.getValue(); if (value != -1 && !seen.add(value)) { - myHolder.createWarningAnnotation(regExpChar, "Duplicate character '" + regExpChar.getText() + "' inside character class"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Duplicate character '" + regExpChar.getText() + "' inside character class").range(regExpChar).create(); } } else if (element instanceof RegExpSimpleClass) { final RegExpSimpleClass regExpSimpleClass = (RegExpSimpleClass)element; final RegExpSimpleClass.Kind kind = regExpSimpleClass.getKind(); if (!seen.add(kind)) { - myHolder.createWarningAnnotation(regExpSimpleClass, "Duplicate predefined character class '" + regExpSimpleClass.getText() + - "' inside character class"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Duplicate predefined character class '" + regExpSimpleClass.getText() + + "' inside character class").range(regExpSimpleClass).create(); } } else if (element instanceof RegExpClass) { @@ -180,34 +176,34 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot final PsiElement child = ch.getFirstChild(); final IElementType type = child.getNode().getElementType(); if (type == StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN) { - myHolder.createErrorAnnotation(ch, "Illegal/unsupported escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal/unsupported escape sequence").create(); return; } else if (type == RegExpTT.BAD_HEX_VALUE) { - myHolder.createErrorAnnotation(ch, "Illegal hexadecimal escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal hexadecimal escape sequence").create(); return; } else if (type == RegExpTT.BAD_OCT_VALUE) { - myHolder.createErrorAnnotation(ch, "Illegal octal escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal octal escape sequence").create(); return; } else if (type == StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN) { - myHolder.createErrorAnnotation(ch, "Illegal unicode escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal unicode escape sequence").create(); return; } final String text = ch.getUnescapedText(); if (type == RegExpTT.ESC_CTRL_CHARACTER && text.equals("\\b") && !myLanguageHosts.supportsLiteralBackspace(ch)) { - myHolder.createErrorAnnotation(ch, "Illegal/unsupported escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal/unsupported escape sequence").create(); } final RegExpChar.Type charType = ch.getType(); if (charType == RegExpChar.Type.HEX || charType == RegExpChar.Type.UNICODE) { if (ch.getValue() == -1) { - myHolder.createErrorAnnotation(ch, "Illegal unicode escape sequence"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal unicode escape sequence").create(); return; } if (text.charAt(text.length() - 1) == '}') { if (!myLanguageHosts.supportsExtendedHexCharacter(ch)) { - myHolder.createErrorAnnotation(ch, "This hex character syntax is not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "This hex character syntax is not supported in this regex dialect").create(); } } } @@ -220,27 +216,27 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot return; } if (!myLanguageHosts.supportsPropertySyntax(property)) { - myHolder.createErrorAnnotation(property, "Property escape sequences are not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Property escape sequences are not supported in this regex dialect").create(); return; } final String propertyName = category.getText(); final ASTNode next = category.getTreeNext(); if (next == null || next.getElementType() != RegExpTT.EQ) { if(!myLanguageHosts.isValidCategory(category.getPsi(), propertyName)) { - final Annotation a = myHolder.createErrorAnnotation(category, "Unknown character category"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown character category").range(category) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } else { if(!myLanguageHosts.isValidPropertyName(category.getPsi(), propertyName)) { - final Annotation a = myHolder.createErrorAnnotation(category, "Unknown property name"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown property name").range(category) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); return; } final ASTNode valueNode = property.getValueNode(); if (valueNode != null && !myLanguageHosts.isValidPropertyValue(category.getPsi(), propertyName, valueNode.getText())) { - final Annotation a = myHolder.createErrorAnnotation(valueNode, "Unknown property value"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown property value").range(valueNode) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } } @@ -248,13 +244,13 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpNamedCharacter(RegExpNamedCharacter namedCharacter) { if (!myLanguageHosts.supportsNamedCharacters(namedCharacter)) { - myHolder.createErrorAnnotation(namedCharacter, "Named Unicode characters are not allowed in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Named Unicode characters are not allowed in this regex dialect").create(); } else if (!myLanguageHosts.isValidNamedCharacter(namedCharacter)) { final ASTNode node = namedCharacter.getNameNode(); if (node != null) { - final Annotation a = myHolder.createErrorAnnotation(node, "Unknown character name"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown character name").range(node) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } } @@ -263,11 +259,11 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot public void visitRegExpBackref(final RegExpBackref backref) { final RegExpGroup group = backref.resolve(); if (group == null) { - final Annotation a = myHolder.createErrorAnnotation(backref, "Unresolved back reference"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unresolved back reference") + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } else if (PsiTreeUtil.isAncestor(group, backref, true)) { - myHolder.createWarningAnnotation(backref, "Back reference is nested into the capturing group it refers to"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Back reference is nested into the capturing group it refers to").create(); } } @@ -278,7 +274,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot final RegExpBranch[] branches = pattern.getBranches(); if (isEmpty(branches)) { // catches "()" as well as "(|)" - myHolder.createWarningAnnotation(group, "Empty group"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Empty group").create(); } else if (branches.length == 1) { final RegExpAtom[] atoms = branches[0].getAtoms(); @@ -287,7 +283,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot if (type == RegExpGroup.Type.CAPTURING_GROUP || type == RegExpGroup.Type.ATOMIC || type == RegExpGroup.Type.NON_CAPTURING) { final RegExpGroup innerGroup = (RegExpGroup)atoms[0]; if (group.isCapturing() == innerGroup.isCapturing()) { - myHolder.createWarningAnnotation(group, "Redundant group nesting"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Redundant group nesting").create(); } } } @@ -295,29 +291,29 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } if (group.isAnyNamedGroup()) { if (!myLanguageHosts.supportsNamedGroupSyntax(group)) { - myHolder.createErrorAnnotation(group, "This named group syntax is not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "This named group syntax is not supported in this regex dialect").create(); } } if (group.getType() == RegExpGroup.Type.ATOMIC && !myLanguageHosts.supportsPossessiveQuantifiers(group)) { - myHolder.createErrorAnnotation(group, "Atomic groups are not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Atomic groups are not supported in this regex dialect").create(); } final String name = group.getName(); if (name != null && !myLanguageHosts.isValidGroupName(name, group)) { final ASTNode node = group.getNode().findChildByType(RegExpTT.NAME); - if (node != null) myHolder.createErrorAnnotation(node, "Invalid group name"); + if (node != null) myHolder.newAnnotation(HighlightSeverity.ERROR, "Invalid group name").range(node).create(); } final AnnotationSession session = myHolder.getCurrentAnnotationSession(); final Map 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"); + if (node != null) myHolder.newAnnotation(HighlightSeverity.ERROR, "Group with name '" + name + "' already defined").range(node).create(); } final RegExpGroup.Type groupType = group.getType(); if (groupType == RegExpGroup.Type.POSITIVE_LOOKBEHIND || groupType == RegExpGroup.Type.NEGATIVE_LOOKBEHIND) { final RegExpLanguageHost.Lookbehind support = myLanguageHosts.supportsLookbehind(group); if (support == RegExpLanguageHost.Lookbehind.NOT_SUPPORTED) { - myHolder.createErrorAnnotation(group, "Look-behind groups are not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Look-behind groups are not supported in this regex dialect").create(); } else { group.accept(new LookbehindVisitor(support, myHolder)); @@ -328,7 +324,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpNamedGroupRef(RegExpNamedGroupRef groupRef) { if (!myLanguageHosts.supportsNamedGroupRefSyntax(groupRef)) { - myHolder.createErrorAnnotation(groupRef, "This named group reference syntax is not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "This named group reference syntax is not supported in this regex dialect").create(); return; } if (groupRef.getGroupName() == null) { @@ -338,12 +334,12 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot if (group == null) { final ASTNode node = groupRef.getNode().findChildByType(RegExpTT.NAME); if (node != null) { - final Annotation a = myHolder.createErrorAnnotation(node, "Unresolved named group reference"); - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unresolved named group reference").range(node) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } else if (PsiTreeUtil.isAncestor(group, groupRef, true)) { - myHolder.createWarningAnnotation(groupRef, "Group reference is nested into the named group it refers to"); + myHolder.newAnnotation(HighlightSeverity.WARNING, "Group reference is nested into the named group it refers to").create(); } } @@ -351,7 +347,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot public void visitComment(@NotNull PsiComment comment) { if (comment.getText().startsWith("(?#")) { if (!myLanguageHosts.supportsPerl5EmbeddedComments(comment)) { - myHolder.createErrorAnnotation(comment, "Embedded comments are not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Embedded comments are not supported in this regex dialect").create(); } } } @@ -359,7 +355,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpPyCondRef(RegExpPyCondRef condRef) { if (!myLanguageHosts.supportsPythonConditionalRefs(condRef)) { - myHolder.createErrorAnnotation(condRef, "Conditional references are not supported in this regex dialect"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Conditional references are not supported in this regex dialect").create(); } } @@ -375,7 +371,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpClosure(RegExpClosure closure) { if (closure.getAtom() instanceof RegExpSetOptions) { - myHolder.createErrorAnnotation(closure.getQuantifier(), "Dangling metacharacter"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Dangling metacharacter").range(closure.getQuantifier()).create(); } } @@ -388,50 +384,50 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot final String max = maxElement == null ? "" : maxElement.getText(); if (!max.isEmpty() && max.equals(min)) { if ("1".equals(max)) { - final Annotation a = myHolder.createWeakWarningAnnotation(quantifier, "Single repetition"); - registerFix(a, new SimplifyQuantifierAction(quantifier, null)); + myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Single repetition") + .withFix(new SimplifyQuantifierAction(quantifier, null)).create(); } else { final ASTNode node = quantifier.getNode(); if (node.findChildByType(RegExpTT.COMMA) != null) { - final Annotation a = myHolder.createWeakWarningAnnotation(quantifier, "Fixed repetition range"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "{" + max + "}")); + myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Fixed repetition range") + .withFix(new SimplifyQuantifierAction(quantifier, "{" + max + "}")).create(); } } } else if (("0".equals(min) || min.isEmpty()) && "1".equals(max)) { - final Annotation a = myHolder.createWeakWarningAnnotation(quantifier, "Repetition range replaceable by '?'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "?")); + myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Repetition range replaceable by '?'") + .withFix(new SimplifyQuantifierAction(quantifier, "?")).create(); } else if (("0".equals(min) || min.isEmpty()) && max.isEmpty()) { - final Annotation a = myHolder.createWeakWarningAnnotation(quantifier, "Repetition range replaceable by '*'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "*")); + myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Repetition range replaceable by '*'") + .withFix(new SimplifyQuantifierAction(quantifier, "*")).create(); } else if ("1".equals(min) && max.isEmpty()) { - final Annotation a = myHolder.createWeakWarningAnnotation(quantifier, "Repetition range replaceable by '+'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "+")); + myHolder.newAnnotation(HighlightSeverity.WEAK_WARNING, "Repetition range replaceable by '+'") + .withFix(new SimplifyQuantifierAction(quantifier, "+")).create(); } Number minValue = null; if (minElement != null) { minValue = myLanguageHosts.getQuantifierValue(minElement); - if (minValue == null) myHolder.createErrorAnnotation(minElement, "Repetition value too large"); + if (minValue == null) myHolder.newAnnotation(HighlightSeverity.ERROR, "Repetition value too large").range(minElement).create(); } Number maxValue = null; if (maxElement != null) { maxValue= myLanguageHosts.getQuantifierValue(maxElement); - if (maxValue == null) myHolder.createErrorAnnotation(maxElement, "Repetition value too large"); + if (maxValue == null) myHolder.newAnnotation(HighlightSeverity.ERROR, "Repetition value too large").range(maxElement).create(); } if (minValue != null && maxValue != null) { if (minValue.longValue() > maxValue.longValue() || minValue.doubleValue() > maxValue.doubleValue()) { final TextRange range = new TextRange(minElement.getTextOffset(), maxElement.getTextOffset() + maxElement.getTextLength()); - myHolder.createErrorAnnotation(range, "Illegal repetition range (min > max)"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Illegal repetition range (min > max)").range(range).create(); } } } if (quantifier.isPossessive() && !myLanguageHosts.supportsPossessiveQuantifiers(quantifier)) { final ASTNode modifier = quantifier.getModifier(); assert modifier != null; - myHolder.createErrorAnnotation(modifier, "Nested quantifier in regexp"); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Nested quantifier in regexp").range(modifier).create(); } } @@ -441,8 +437,8 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot if (!POSIX_CHARACTER_CLASSES.contains(className) && !"<".equals(className) && !">".equals(className)) { final ASTNode node = posixBracketExpression.getNode().findChildByType(RegExpTT.NAME); if (node != null) { - final Annotation annotation = myHolder.createErrorAnnotation(node, "Unknown POSIX character class"); - annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + myHolder.newAnnotation(HighlightSeverity.ERROR, "Unknown POSIX character class").range(node) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL).create(); } } } @@ -586,7 +582,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } public void stopAndReportError(RegExpElement element, @NotNull String message) { - myHolder.createErrorAnnotation(element, message); + myHolder.newAnnotation(HighlightSeverity.ERROR, message).range(element).create(); myStop = true; } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/ValueRegExpAnnotator.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/ValueRegExpAnnotator.java index 5db049e3fbcd..e0c3684b0357 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/ValueRegExpAnnotator.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/ValueRegExpAnnotator.java @@ -18,6 +18,7 @@ package org.intellij.plugins.intelliLang.inject.config.ui; import com.intellij.lang.LanguageAnnotators; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; +import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import org.intellij.lang.regexp.RegExpFile; @@ -69,7 +70,7 @@ public class ValueRegExpAnnotator implements Annotator { }); if (count[0] != 1) { - holder.createWarningAnnotation(branch, "The pattern should contain exactly one capturing group"); + holder.newAnnotation(HighlightSeverity.WARNING, "The pattern should contain exactly one capturing group").range(branch).create(); } } }