don't highlight named groups in Java 1.7 regular expressions as errors (IDEA-80456)
authorDmitry Jemerov <yole@jetbrains.com>
Tue, 31 Jan 2012 12:35:55 +0000 (13:35 +0100)
committerDmitry Jemerov <yole@jetbrains.com>
Tue, 31 Jan 2012 12:35:55 +0000 (13:35 +0100)
RegExpSupport/RegExpSupport.iml
RegExpSupport/src/META-INF/RegExpPlugin.xml
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java [new file with mode: 0644]
RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java
java/java-impl/java-impl.iml
java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java [new file with mode: 0644]
resources/src/META-INF/IdeaPlugin.xml

index b9b3142c9ce2c3c4c9283c02722ee9619737efd5..4597318e788506313ecc84b544bd2ab297331afe 100644 (file)
@@ -15,6 +15,9 @@
     <orderEntry type="module" module-name="xml" />
     <orderEntry type="module" module-name="testFramework" scope="TEST" />
     <orderEntry type="library" name="Jaxen" level="project" />
+    <orderEntry type="module" module-name="dom-impl" scope="RUNTIME" />
+    <orderEntry type="module" module-name="relaxng" scope="RUNTIME" />
+    <orderEntry type="module" module-name="spellchecker" scope="RUNTIME" />
   </component>
 </module>
 
index 3c37bbbac87590985df6c1c51da30b9d3c28aebf..a245a2eae7cda0e1d2267954dcb87d5e315b090a 100644 (file)
@@ -1,4 +1,7 @@
 <idea-plugin>
+  <extensionPoints>
+    <extensionPoint name="regExpLanguageHost" beanClass="com.intellij.openapi.util.ClassExtensionPoint"/>
+  </extensionPoints>
   <extensions defaultExtensionNs="com.intellij">
     <lang.documentationProvider language="RegExp" implementationClass="org.intellij.lang.regexp.RegExpDocumentationProvider"/>
     <completion.contributor language="RegExp" implementationClass="org.intellij.lang.regexp.RegExpCompletionContributor"/>
index 37dcc6c527b185f562bfa3dc32bc151a94e97da3..c283f19e87af545b50d08b6157c2344e27221cff 100644 (file)
@@ -15,6 +15,8 @@
  */
 package org.intellij.lang.regexp;
 
+import org.intellij.lang.regexp.psi.RegExpGroup;
+
 /**
  * @author yole
  */
@@ -22,7 +24,6 @@ public interface RegExpLanguageHost {
   boolean characterNeedsEscaping(char c);
   boolean supportsPerl5EmbeddedComments();
   boolean supportsPossessiveQuantifiers();
-  boolean supportsPythonNamedGroups();
   boolean supportsPythonConditionalRefs();
-  boolean supportsRubyNamedGroups();
+  boolean supportsNamedGroupSyntax(RegExpGroup group);
 }
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java
new file mode 100644 (file)
index 0000000..0f57f33
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * 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;
+
+import com.intellij.openapi.util.ClassExtension;
+
+/**
+ * @author yole
+ */
+public class RegExpLanguageHosts extends ClassExtension<RegExpLanguageHost> {
+  public static RegExpLanguageHosts INSTANCE = new RegExpLanguageHosts();
+
+  private RegExpLanguageHosts() {
+    super("com.intellij.regExpLanguageHost");
+  }
+}
index 359849287d83ada4bd1b30effccfe5d66ad8ad8c..359a4871acf69c141687d4cc27bea8a82551e40c 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiLanguageInjectionHost;
 import com.intellij.psi.util.PsiTreeUtil;
 import org.intellij.lang.regexp.RegExpLanguageHost;
+import org.intellij.lang.regexp.RegExpLanguageHosts;
 import org.intellij.lang.regexp.RegExpTT;
 import org.intellij.lang.regexp.psi.*;
 import org.intellij.lang.regexp.psi.impl.RegExpPropertyImpl;
@@ -124,6 +125,9 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
     if (host instanceof RegExpLanguageHost) {
       return (RegExpLanguageHost)host;
     }
+    if (host != null) {
+      return RegExpLanguageHosts.INSTANCE.forClass(host.getClass());
+    }
     return null;
   }
 
@@ -174,8 +178,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
     }
     if (group.isPythonNamedGroup() || group.isRubyNamedGroup()) {
       RegExpLanguageHost host = findRegExpHost(group);
-      if (host == null || (group.isPythonNamedGroup() && !host.supportsPythonNamedGroups()) ||
-                          (group.isRubyNamedGroup() && !host.supportsRubyNamedGroups())) {
+      if (host == null || !host.supportsNamedGroupSyntax(group)) {
         myHolder.createErrorAnnotation(group, "This named group syntax is not supported");
       }
     }
@@ -183,11 +186,13 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
 
   @Override
   public void visitRegExpPyNamedGroupRef(RegExpPyNamedGroupRef groupRef) {
+    /* the named group itself will be highlighted as unsupported; no need to highlight reference as well
     RegExpLanguageHost host = findRegExpHost(groupRef);
     if (host == null || !host.supportsPythonNamedGroups()) {
       myHolder.createErrorAnnotation(groupRef, "This named group reference syntax is not supported");
       return;
     }
+    */
     final RegExpGroup group = groupRef.resolve();
     if (group == null) {
       final Annotation a = myHolder.createErrorAnnotation(groupRef, "Unresolved backreference");
index 934740800fe97b7b3eac8d120c3e27da8644a989..20ad95d8d9bba9f03b60af5f06e42389adcb0973 100644 (file)
@@ -31,6 +31,7 @@
     <orderEntry type="library" name="Guava" level="project" />
     <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
     <orderEntry type="module" module-name="java-psi-impl" exported="" />
+    <orderEntry type="module" module-name="RegExpSupport" />
   </component>
   <component name="copyright">
     <Base>
diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java b/java/java-impl/src/com/intellij/psi/impl/JavaRegExpHost.java
new file mode 100644 (file)
index 0000000..a86bb91
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * 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 com.intellij.psi.impl;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import org.intellij.lang.regexp.RegExpLanguageHost;
+import org.intellij.lang.regexp.psi.RegExpGroup;
+
+/**
+ * @author yole
+ */
+public class JavaRegExpHost implements RegExpLanguageHost {
+  @Override
+  public boolean characterNeedsEscaping(char c) {
+    return c == ']' || c == '}';
+  }
+
+  @Override
+  public boolean supportsPerl5EmbeddedComments() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPossessiveQuantifiers() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsPythonConditionalRefs() {
+    return false;
+  }
+
+  @Override
+  public boolean supportsNamedGroupSyntax(RegExpGroup group) {
+    if (group.isRubyNamedGroup()) {
+      final Module module = ModuleUtil.findModuleForPsiElement(group);
+      if (module != null) {
+        final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+        if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
+          final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
+          return version != null && version.isAtLeast(JavaSdkVersion.JDK_1_7);
+        }
+      }
+    }
+    return false;
+  }
+}
index bec0cf45f755f77d40f0eedd1226edf87c1c4aea..adb4c5cd8e460b0752217d4f8a4d4dfb6d1b5dc6 100644 (file)
     <wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateProjectFromSourcesMode" id="CreateProjectFromSourcesMode" order="after CreateFromScratchMode"/>
     <wizardMode implementation="com.intellij.ide.util.newProjectWizard.modes.CreateModuleFromSourcesMode" id="CreateModuleFromSourcesMode" order="after CreateProjectFromSourcesMode"/>
     <projectStructureDetector implementation="com.intellij.ide.util.projectWizard.importSources.impl.JavaProjectStructureDetector" order="first"/>
+
+    <regExpLanguageHost forClass="com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl"
+                        implementationClass="com.intellij.psi.impl.JavaRegExpHost"/>
   </extensions>
 
   <actions>