From bfff38cf9dbe7ec5b5be1a19877c3c057dfaefb5 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Mon, 11 Feb 2013 22:24:05 +0400 Subject: [PATCH] RUBY-13071: (refactoring) work with RegExpLanguageHost encapsulated into RegExpLanguageHosts --- .../lang/regexp/RegExpLanguageHosts.java | 68 ++++++++++++++++++- .../regexp/validation/RegExpAnnotator.java | 47 +++---------- 2 files changed, 76 insertions(+), 39 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java index d36e7e6a009c..e70cf47b3f94 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java @@ -15,15 +15,79 @@ */ package org.intellij.lang.regexp; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.util.ClassExtension; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLanguageInjectionHost; +import org.intellij.lang.regexp.psi.RegExpChar; +import org.intellij.lang.regexp.psi.RegExpGroup; +import org.intellij.lang.regexp.psi.RegExpPyCondRef; +import org.intellij.lang.regexp.psi.RegExpQuantifier; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author yole */ -public class RegExpLanguageHosts extends ClassExtension { - public static final RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts(); +public final class RegExpLanguageHosts extends ClassExtension { + private static final RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts(); + + public static RegExpLanguageHosts getInstance() { + return INSTANCE; + } private RegExpLanguageHosts() { super("com.intellij.regExpLanguageHost"); } + + @Nullable + private static RegExpLanguageHost findRegExpHost(@Nullable final PsiElement element) { + if (element == null) { + return null; + } + PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); + if (host instanceof RegExpLanguageHost) { + return (RegExpLanguageHost)host; + } + if (host != null) { + return INSTANCE.forClass(host.getClass()); + } + return null; + } + + public boolean isRedundantEscape(@NotNull final RegExpChar ch, @NotNull final String text) { + if (text.length() <= 1) { + return false; + } + final RegExpLanguageHost host = findRegExpHost(ch); + if (host != null) { + final char c = text.charAt(1); + final boolean needsEscaping = host.characterNeedsEscaping(c); + return !needsEscaping; + } + else { + return !("\\]".equals(text) || "\\}".equals(text)); + } + } + + public boolean supportsNamedGroupSyntax(@Nullable final RegExpGroup group) { + final RegExpLanguageHost host = findRegExpHost(group); + return host != null && host.supportsNamedGroupSyntax(group); + } + + public boolean supportsPerl5EmbeddedComments(@Nullable final PsiComment comment) { + final RegExpLanguageHost host = findRegExpHost(comment); + return host != null && host.supportsPerl5EmbeddedComments(); + } + + public boolean supportsPythonConditionalRefs(@Nullable final RegExpPyCondRef condRef) { + final RegExpLanguageHost host = findRegExpHost(condRef); + return host != null && host.supportsPythonConditionalRefs(); + } + + public boolean supportsPossessiveQuantifiers(@Nullable final RegExpQuantifier quantifier) { + final RegExpLanguageHost host = findRegExpHost(quantifier); + return host != null && host.supportsPossessiveQuantifiers(); + } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index 29626c69d04d..e6e7a021f91f 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -21,20 +21,22 @@ import com.intellij.lang.ASTNode; import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.psi.util.PsiTreeUtil; import org.intellij.lang.regexp.*; import org.intellij.lang.regexp.psi.*; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.math.BigInteger; public final class RegExpAnnotator extends RegExpElementVisitor implements Annotator { private AnnotationHolder myHolder; + private final RegExpLanguageHosts myLanguageHosts; + + public RegExpAnnotator() { + myLanguageHosts = RegExpLanguageHosts.getInstance(); + } public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { assert myHolder == null : "unsupported concurrent annotator invocation"; @@ -95,7 +97,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } else { final String text = ch.getUnescapedText(); - if (text.startsWith("\\") && isRedundantEscape(ch, text)) { + if (text.startsWith("\\") && myLanguageHosts.isRedundantEscape(ch, text)) { final ASTNode astNode = ch.getNode().getFirstChildNode(); if (astNode != null && astNode.getElementType() == RegExpTT.REDUNDANT_ESCAPE) { final Annotation a = myHolder.createWeakWarningAnnotation(ch, "Redundant character escape"); @@ -105,31 +107,6 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } - private static boolean isRedundantEscape(RegExpChar ch, String text) { - if (text.length() <= 1) return false; - RegExpLanguageHost host = findRegExpHost(ch); - if (host != null) { - final char c = text.charAt(1); - final boolean needsEscaping = host.characterNeedsEscaping(c); - return !needsEscaping; - } - else { - return !("\\]".equals(text) || "\\}".equals(text)); - } - } - - @Nullable - private static RegExpLanguageHost findRegExpHost(PsiElement element) { - PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); - if (host instanceof RegExpLanguageHost) { - return (RegExpLanguageHost)host; - } - if (host != null) { - return RegExpLanguageHosts.INSTANCE.forClass(host.getClass()); - } - return null; - } - public void visitRegExpProperty(RegExpProperty property) { final ASTNode category = property.getCategoryNode(); if (category == null) { @@ -180,8 +157,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } if (group.isPythonNamedGroup() || group.isRubyNamedGroup()) { - RegExpLanguageHost host = findRegExpHost(group); - if (host == null || !host.supportsNamedGroupSyntax(group)) { + if (!myLanguageHosts.supportsNamedGroupSyntax(group)) { myHolder.createErrorAnnotation(group, "This named group syntax is not supported"); } } @@ -212,8 +188,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitComment(PsiComment comment) { if (comment.getText().startsWith("(?#")) { - RegExpLanguageHost host = findRegExpHost(comment); - if (host == null || !host.supportsPerl5EmbeddedComments()) { + if (!myLanguageHosts.supportsPerl5EmbeddedComments(comment)) { myHolder.createErrorAnnotation(comment, "Embedded comments are not supported"); } } @@ -221,8 +196,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpPyCondRef(RegExpPyCondRef condRef) { - RegExpLanguageHost host = findRegExpHost(condRef); - if (host == null || !host.supportsPythonConditionalRefs()) { + if (!myLanguageHosts.supportsPythonConditionalRefs(condRef)) { myHolder.createErrorAnnotation(condRef, "Conditional references are not supported"); } } @@ -280,8 +254,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } } if (quantifier.getType() == RegExpQuantifier.Type.POSSESSIVE) { - RegExpLanguageHost host = findRegExpHost(quantifier); - if (host != null && !host.supportsPossessiveQuantifiers()) { + if (!myLanguageHosts.supportsPossessiveQuantifiers(quantifier)) { myHolder.createErrorAnnotation(quantifier, "Nested quantifier in regexp"); } }