add dependency on external library quick-fix: API simplified, duplicated code removed
authornik <Nikolay.Chashnikov@jetbrains.com>
Wed, 29 Jul 2015 05:31:13 +0000 (08:31 +0300)
committernik <Nikolay.Chashnikov@jetbrains.com>
Wed, 29 Jul 2015 05:31:13 +0000 (08:31 +0300)
18 files changed:
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExternalLibraryToDependenciesQuickFix.java [new file with mode: 0644]
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java [new file with mode: 0644]
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java
java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryDescriptor.java [new file with mode: 0644]
java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryResolver.java [new file with mode: 0644]
java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/MissingDependencyFixProvider.java
java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPExternalLibraryResolver.java [new file with mode: 0644]
java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPOrderEntryFix.java [deleted file]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/orderEntry/A/src/x/DoTest.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/orderEntry/A/src/x/DoTest4.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/orderEntry/A/src/x/DoTest4junit.java
plugins/junit/src/META-INF/plugin.xml
plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitExternalLibraryResolver.java [new file with mode: 0644]
plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java [deleted file]
plugins/testng/src/META-INF/plugin.xml
plugins/testng/src/com/theoryinpractice/testng/intention/TestNGExternalLibraryResolver.java [new file with mode: 0644]
plugins/testng/src/com/theoryinpractice/testng/intention/TestNGOrderEntryFix.java [deleted file]
resources/src/META-INF/IdeaPlugin.xml

diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExternalLibraryToDependenciesQuickFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddExternalLibraryToDependenciesQuickFix.java
new file mode 100644 (file)
index 0000000..97c33ac
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2015 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.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+class AddExternalLibraryToDependenciesQuickFix extends OrderEntryFix {
+  private final Module myCurrentModule;
+  private final PsiReference myReference;
+  private final ExternalLibraryDescriptor myLibraryDescriptor;
+  private final String myQualifiedClassName;
+
+  public AddExternalLibraryToDependenciesQuickFix(@NotNull Module currentModule,
+                                                  @NotNull ExternalLibraryDescriptor libraryDescriptor, @NotNull PsiReference reference,
+                                                  @Nullable String qualifiedClassName) {
+    myCurrentModule = currentModule;
+    myReference = reference;
+    myLibraryDescriptor = libraryDescriptor;
+    myQualifiedClassName = qualifiedClassName;
+  }
+
+  @Nls
+  @NotNull
+  @Override
+  public String getText() {
+    return "Add '" + myLibraryDescriptor.getPresentableName() + "' to classpath";
+  }
+
+  @Nls
+  @NotNull
+  @Override
+  public String getFamilyName() {
+    return getText();
+  }
+
+  @Override
+  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
+    return !project.isDisposed() && !myCurrentModule.isDisposed();
+  }
+
+  @Override
+  public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
+    List<String> classesRoots = myLibraryDescriptor.locateLibraryClassesRoots(myCurrentModule);
+    if (!classesRoots.isEmpty()) {
+      String libraryName = classesRoots.size() > 1 ? myLibraryDescriptor.getPresentableName() : null;
+      addJarsToRootsAndImportClass(classesRoots, libraryName, myCurrentModule, editor, myReference,
+                                   myQualifiedClassName);
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java
new file mode 100644 (file)
index 0000000..e5b6a3c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2015 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.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.ThreeState;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class JetBrainsAnnotationsExternalLibraryResolver extends ExternalLibraryResolver {
+  private static final ExternalLibraryDescriptor ANNOTATIONS = new ExternalLibraryDescriptor("com.intellij", "annotations", null) {
+    @NotNull
+    @Override
+    public List<String> locateLibraryClassesRoots(@NotNull Module contextModule) {
+      return ContainerUtil.createMaybeSingletonList(OrderEntryFix.locateAnnotationsJar(contextModule));
+    }
+  };
+
+  @Nullable
+  @Override
+  public ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation) {
+    if (AnnotationUtil.isJetbrainsAnnotation(shortClassName)) {
+      return new ExternalClassResolveResult("org.jetbrains.annotations." + shortClassName, ANNOTATIONS);
+    }
+    return null;
+  }
+}
index ccad56346af21e0c100d4487268e701ad8441029..91e4b9456f9bffd0eb948094b96624faa62ee495 100644 (file)
@@ -19,11 +19,13 @@ import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.daemon.impl.actions.AddImportAction;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver.ExternalClassResolveResult;
 import com.intellij.codeInsight.daemon.quickFix.MissingDependencyFixProvider;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInspection.LocalQuickFix;
 import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
@@ -48,6 +50,7 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.Function;
 import com.intellij.util.ObjectUtils;
+import com.intellij.util.ThreeState;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NonNls;
@@ -91,7 +94,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix {
   @Nullable
   public static List<LocalQuickFix> registerFixes(@NotNull final QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) {
     final PsiElement psiElement = reference.getElement();
-    @NonNls final String referenceName = reference.getRangeInElement().substring(psiElement.getText());
+    @NonNls final String shortReferenceName = reference.getRangeInElement().substring(psiElement.getText());
 
     Project project = psiElement.getProject();
     PsiFile containingFile = psiElement.getContainingFile();
@@ -114,65 +117,33 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix {
       return providedFixes;
     }
 
-    if (isAnnotation(psiElement) && AnnotationUtil.isJetbrainsAnnotation(referenceName)) {
-      @NonNls final String className = "org.jetbrains.annotations." + referenceName;
-      PsiClass found =
-        JavaPsiFacade.getInstance(project).findClass(className, currentModule.getModuleWithDependenciesAndLibrariesScope(true));
-      if (found != null) return null; //no need to add junit to classpath
-      final OrderEntryFix platformFix = new OrderEntryFix() {
-        @Override
-        @NotNull
-        public String getText() {
-          return QuickFixBundle.message("orderEntry.fix.add.annotations.jar.to.classpath");
-        }
-
-        @Override
-        @NotNull
-        public String getFamilyName() {
-          return getText();
-        }
-
-        @Override
-        public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
-          return !project.isDisposed() && !currentModule.isDisposed();
-        }
-
-        @Override
-        public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) {
-          ApplicationManager.getApplication().invokeLater(new Runnable() {
-            @Override
-            public void run() {
-              final String libraryPath = locateAnnotationsJar(currentModule);
-              if (libraryPath != null) {
-                new WriteCommandAction(project) {
-                  @Override
-                  protected void run(@NotNull final Result result) throws Throwable {
-                    addJarsToRootsAndImportClass(Collections.singletonList(libraryPath), null, currentModule, editor, reference,
-                                                 "org.jetbrains.annotations." + referenceName);
-                  }
-                }.execute();
-              }
-            }
-          });
-        }
-      };
-
-      final OrderEntryFix providedFix = provideFix(new Function<MissingDependencyFixProvider, OrderEntryFix>() {
-        @Override
-        public OrderEntryFix fun(MissingDependencyFixProvider provider) {
-          return provider.getJetbrainsAnnotationFix(reference, platformFix, currentModule);
+    List<LocalQuickFix> result = new ArrayList<LocalQuickFix>();
+    JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
+    String fullReferenceText = reference.getCanonicalText();
+    for (ExternalLibraryResolver resolver : ExternalLibraryResolver.EP_NAME.getExtensions()) {
+      final ExternalClassResolveResult resolveResult = resolver.resolveClass(shortReferenceName, isReferenceToAnnotation(psiElement));
+      OrderEntryFix fix = null;
+      if (resolveResult != null && psiFacade.findClass(resolveResult.getQualifiedClassName(), currentModule.getModuleWithDependenciesAndLibrariesScope(true)) == null) {
+        fix = new AddExternalLibraryToDependenciesQuickFix(currentModule, resolveResult.getLibrary(), reference, resolveResult.getQualifiedClassName());
+      }
+      else if (!fullReferenceText.equals(shortReferenceName)) {
+        ExternalLibraryDescriptor descriptor = resolver.resolvePackage(fullReferenceText);
+        if (descriptor != null) {
+          fix = new AddExternalLibraryToDependenciesQuickFix(currentModule, descriptor, reference, null);
         }
-      });
-      final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix);
-
-      registrar.register(fix);
-      return Collections.singletonList((LocalQuickFix)fix);
+      }
+      if (fix != null) {
+        registrar.register(fix);
+        result.add(fix);
+      }
+    }
+    if (!result.isEmpty()) {
+      return result;
     }
 
-    List<LocalQuickFix> result = new ArrayList<LocalQuickFix>();
     Set<Object> librariesToAdd = new THashSet<Object>();
     final JavaPsiFacade facade = JavaPsiFacade.getInstance(psiElement.getProject());
-    PsiClass[] classes = PsiShortNamesCache.getInstance(project).getClassesByName(referenceName, GlobalSearchScope.allScope(project));
+    PsiClass[] classes = PsiShortNamesCache.getInstance(project).getClassesByName(shortReferenceName, GlobalSearchScope.allScope(project));
     List<PsiClass> allowedDependencies = filterAllowedDependencies(psiElement, classes);
     if (allowedDependencies.isEmpty()) {
       return result;
@@ -283,8 +254,17 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix {
     return result;
   }
 
-  private static boolean isAnnotation(final PsiElement psiElement) {
-    return PsiTreeUtil.getParentOfType(psiElement, PsiAnnotation.class) != null && PsiUtil.isLanguageLevel5OrHigher(psiElement);
+  private static ThreeState isReferenceToAnnotation(final PsiElement psiElement) {
+    if (!PsiUtil.isLanguageLevel5OrHigher(psiElement)) {
+      return ThreeState.NO;
+    }
+    if (PsiTreeUtil.getParentOfType(psiElement, PsiAnnotation.class) != null) {
+      return ThreeState.YES;
+    }
+    if (PsiTreeUtil.getParentOfType(psiElement, PsiImportStatement.class) != null) {
+      return ThreeState.UNSURE;
+    }
+    return ThreeState.NO;
   }
 
   /**
@@ -301,7 +281,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix {
                                                   final String libraryName,
                                                   @NotNull final Module currentModule, @Nullable final Editor editor,
                                                   @Nullable final PsiReference reference,
-                                                  @NonNls final String className) {
+                                                  @Nullable @NonNls final String className) {
     addJarsToRoots(jarPaths, libraryName, currentModule, reference != null ? reference.getElement() : null);
 
     final Project project = currentModule.getProject();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryDescriptor.java
new file mode 100644 (file)
index 0000000..4200209
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2015 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.codeInsight.daemon.quickFix;
+
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ExternalLibraryDescriptor {
+  private final String myLibraryGroupId;
+  private final String myLibraryArtifactId;
+  private final String myMinVersion;
+
+  public ExternalLibraryDescriptor(@NotNull String libraryGroupId, @NotNull String libraryArtifactId, @Nullable String minVersion) {
+    myLibraryGroupId = libraryGroupId;
+    myLibraryArtifactId = libraryArtifactId;
+    myMinVersion = minVersion;
+  }
+
+  @NotNull
+  public String getLibraryGroupId() {
+    return myLibraryGroupId;
+  }
+
+  @NotNull
+  public String getLibraryArtifactId() {
+    return myLibraryArtifactId;
+  }
+
+  @Nullable
+  public String getMinVersion() {
+    return myMinVersion;
+  }
+
+  public String getPresentableName() {
+    return myLibraryArtifactId;
+  }
+
+  @NotNull
+  public abstract List<String> locateLibraryClassesRoots(@NotNull Module contextModule);
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryResolver.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/ExternalLibraryResolver.java
new file mode 100644 (file)
index 0000000..00f48ff
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2015 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.codeInsight.daemon.quickFix;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.util.ThreeState;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ExternalLibraryResolver {
+  public static final ExtensionPointName<ExternalLibraryResolver> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.externalLibraryResolver");
+
+  @Nullable
+  public abstract ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation);
+
+  @Nullable
+  public ExternalLibraryDescriptor resolvePackage(@NotNull String packageName) {
+    return null;
+  }
+
+  public static class ExternalClassResolveResult {
+    private final String myQualifiedClassName;
+    private final ExternalLibraryDescriptor myLibrary;
+
+    public ExternalClassResolveResult(String qualifiedClassName,
+                                      ExternalLibraryDescriptor library) {
+      myQualifiedClassName = qualifiedClassName;
+      myLibrary = library;
+    }
+
+    public String getQualifiedClassName() {
+      return myQualifiedClassName;
+    }
+
+    public ExternalLibraryDescriptor getLibrary() {
+      return myLibrary;
+    }
+  }
+}
index 46c0e7abc887a02c1bba2f7450fc8352e5d82ed4..3818c92dfb31e026ba99a636785312bbf9b9c16f 100644 (file)
@@ -19,15 +19,12 @@ import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
 import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
 import com.intellij.codeInspection.LocalQuickFix;
 import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.roots.LibraryOrderEntry;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiReference;
-import com.intellij.testIntegration.JavaTestFramework;
-import com.intellij.util.Function;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -51,22 +48,6 @@ public abstract class MissingDependencyFixProvider {
     return null;
   }
 
-  @Nullable
-  public OrderEntryFix getJUnitFix(@NotNull PsiReference reference,
-                                   @NotNull OrderEntryFix platformFix,
-                                   @NotNull Module currentModule,
-                                   @NotNull JavaTestFramework framework,
-                                   @NotNull String className) {
-    return null;
-  }
-
-  @Nullable
-  public OrderEntryFix getJetbrainsAnnotationFix(@NotNull PsiReference reference,
-                                                 @NotNull OrderEntryFix platformFix,
-                                                 @NotNull Module currentModule) {
-    return null;
-  }
-
   @Nullable
   public OrderEntryFix getAddModuleDependencyFix(@NotNull PsiReference reference,
                                                  @NotNull OrderEntryFix platformFix,
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPExternalLibraryResolver.java b/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPExternalLibraryResolver.java
new file mode 100644 (file)
index 0000000..4f5cc2d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2015 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.codeInspection.concurrencyAnnotations;
+
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.PathUtil;
+import com.intellij.util.ThreeState;
+import net.jcip.annotations.GuardedBy;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class JCiPExternalLibraryResolver extends ExternalLibraryResolver {
+  private static final ExternalLibraryDescriptor JDCIP_LIBRARY_DESCRIPTOR =
+    new ExternalLibraryDescriptor("net.jcip", "jcip-annotations", null) {
+      @NotNull
+      @Override
+      public List<String> locateLibraryClassesRoots(@NotNull Module contextModule) {
+        return Collections.singletonList(PathUtil.getJarPathForClass(GuardedBy.class));
+      }
+
+      @Override
+      public String getPresentableName() {
+        return "jcip-annotations.jar";
+      }
+    };
+
+  @Nullable
+  @Override
+  public ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation) {
+    if (JCiPUtil.isJCiPAnnotation(shortClassName) && isAnnotation == ThreeState.YES) {
+      return new ExternalClassResolveResult("net.jcip.annotations." + shortClassName, JDCIP_LIBRARY_DESCRIPTOR);
+    }
+    return null;
+  }
+
+  @Nullable
+  @Override
+  public ExternalLibraryDescriptor resolvePackage(@NotNull String packageName) {
+    if (packageName.equals("net.jcip.annotations")) {
+      return JDCIP_LIBRARY_DESCRIPTOR;
+    }
+    return null;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPOrderEntryFix.java b/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPOrderEntryFix.java
deleted file mode 100644 (file)
index c10ca63..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2000-2009 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.
- */
-
-/*
- * User: anna
- * Date: 30-Jul-2007
- */
-package com.intellij.codeInspection.concurrencyAnnotations;
-
-import com.intellij.codeInsight.TargetElementUtil;
-import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.module.ModuleUtil;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.PathUtil;
-import net.jcip.annotations.GuardedBy;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collections;
-
-public class JCiPOrderEntryFix implements IntentionAction {
-  private static final Logger LOG = Logger.getInstance("#" + JCiPOrderEntryFix.class.getName());
-
-  @Override
-  @NotNull
-  public String getText() {
-    return "Add jcip-annotations.jar to classpath";
-  }
-
-  @Override
-  @NotNull
-  public String getFamilyName() {
-    return getText();
-  }
-
-  @Override
-  public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
-    if (!(file instanceof PsiJavaFile)) return false;
-
-    final PsiReference reference = TargetElementUtil.findReference(editor);
-    if (!(reference instanceof PsiJavaCodeReferenceElement)) return false;
-    if (reference.resolve() != null) return false;
-    @NonNls final String referenceName = ((PsiJavaCodeReferenceElement)reference).getReferenceName();
-    if (referenceName == null) return false;
-    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
-    final VirtualFile virtualFile = file.getVirtualFile();
-    if (virtualFile == null) return false;
-    if (fileIndex.getModuleForFile(virtualFile) == null) return false;
-    if (!(((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiAnnotation &&
-          PsiUtil.isLanguageLevel5OrHigher(((PsiJavaCodeReferenceElement)reference)))) return false;
-    if (!JCiPUtil.isJCiPAnnotation(referenceName)) return false;
-    return true;
-  }
-
-  @Override
-  public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
-    final PsiJavaCodeReferenceElement reference = (PsiJavaCodeReferenceElement)TargetElementUtil.findReference(editor);
-    LOG.assertTrue(reference != null);
-    String jarPath = PathUtil.getJarPathForClass(GuardedBy.class);
-    final VirtualFile virtualFile = file.getVirtualFile();
-    LOG.assertTrue(virtualFile != null);
-    OrderEntryFix.addJarsToRootsAndImportClass(Collections.singletonList(jarPath), null, ModuleUtil.findModuleForFile(virtualFile, project), editor,
-                                               reference, "net.jcip.annotations." + reference.getReferenceName());
-  }
-
-  @Override
-  public boolean startInWriteAction() {
-    return true;
-  }
-
-}
\ No newline at end of file
index b596520ae6b631fc824dd33608ed40db235bdba0..c503e02b305cb0c95443cbcfb301f9f730236625 100644 (file)
@@ -1,4 +1,4 @@
-// "Add JUnit to classpath" "true"
+// "Add 'JUnit3' to classpath" "true"
 package x;
 public class DoTest extends TestCase<caret>{
 
index a4696ac5c8807949a8ad373d6563eb3ee66a6566..04e0eafaaa6fd4df6a57ed45e33a6e540f21b5b7 100644 (file)
@@ -1,4 +1,4 @@
-// "Add JUnit to classpath" "true"
+// "Add 'JUnit4' to classpath" "true"
 package x;
 
 public class DoTest4 {
index 00fa3994b118809569e36b86da5a758ac5dd988e..a80c2bde39940049bf6ed35cd5c51ed14f7e858a 100644 (file)
@@ -60,7 +60,7 @@
     <stacktrace.fold substring="at junit.framework.TestResult"/>
 
     <programRunner implementation="com.intellij.execution.junit.JUnitDebuggerRunner"/>
-    <codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.execution.junit.codeInsight.JUnitUnresolvedReferenceQuickFixProvider"/>
+    <codeInsight.externalLibraryResolver implementation="com.intellij.execution.junit.codeInsight.JUnitExternalLibraryResolver"/>
     <junitListener implementation="com.intellij.junit4.JUnitTestDiscoveryListener"/>
     <configurationType implementation="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationType"/>
     <runConfigurationProducer implementation="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer"/>
diff --git a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitExternalLibraryResolver.java b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitExternalLibraryResolver.java
new file mode 100644 (file)
index 0000000..7c21ac2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2015 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.execution.junit.codeInsight;
+
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
+import com.intellij.execution.junit.JUnit3Framework;
+import com.intellij.execution.junit.JUnit4Framework;
+import com.intellij.openapi.module.Module;
+import com.intellij.testIntegration.JavaTestFramework;
+import com.intellij.testIntegration.TestFramework;
+import com.intellij.util.ThreeState;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class JUnitExternalLibraryResolver extends ExternalLibraryResolver {
+  public static final ExternalLibraryDescriptor JUNIT3 = createJUnitDescriptor("3", JUnit3Framework.class);
+  public static final ExternalLibraryDescriptor JUNIT4 = createJUnitDescriptor("4", JUnit4Framework.class);
+
+  @NotNull
+  private static ExternalLibraryDescriptor createJUnitDescriptor(final String version, final Class<? extends JavaTestFramework> frameworkClass) {
+    return new ExternalLibraryDescriptor("junit", "junit", version) {
+      @NotNull
+      @Override
+      public List<String> locateLibraryClassesRoots(@NotNull Module contextModule) {
+        return TestFramework.EXTENSION_NAME.findExtension(frameworkClass).getLibraryPaths();
+      }
+
+      @Override
+      public String getPresentableName() {
+        return "JUnit" + version;
+      }
+    };
+  }
+
+  private static Set<String> JUNIT4_ANNOTATIONS = ContainerUtil.set(
+    "Test", "Ignore", "RunWith", "Before", "BeforeClass", "After", "AfterClass"
+  );
+  @Nullable
+  @Override
+  public ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation) {
+    if ("TestCase".equals(shortClassName)) {
+      return new ExternalClassResolveResult("junit.framework.TestCase", JUNIT3);
+    }
+    if (isAnnotation == ThreeState.YES && JUNIT4_ANNOTATIONS.contains(shortClassName)) {
+      return new ExternalClassResolveResult("org.junit." + shortClassName, JUNIT4);
+    }
+    return null;
+  }
+
+  @Nullable
+  @Override
+  public ExternalLibraryDescriptor resolvePackage(@NotNull String packageName) {
+    if (packageName.equals("org.junit")) {
+      return JUNIT4;
+    }
+    if (packageName.equals("junit.framework")) {
+      return JUNIT3;
+    }
+    return null;
+  }
+}
diff --git a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java
deleted file mode 100644 (file)
index 2daa86e..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright 2000-2015 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.execution.junit.codeInsight;
-
-import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
-import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.quickfix.MissingDependencyFixUtil;
-import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
-import com.intellij.codeInsight.daemon.quickFix.MissingDependencyFixProvider;
-import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
-import com.intellij.execution.junit.JUnit3Framework;
-import com.intellij.execution.junit.JUnit4Framework;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.testIntegration.JavaTestFramework;
-import com.intellij.testIntegration.TestFramework;
-import com.intellij.util.Function;
-import com.intellij.util.ObjectUtils;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-/**
- * @author nik
- */
-public class JUnitUnresolvedReferenceQuickFixProvider extends UnresolvedReferenceQuickFixProvider<PsiJavaCodeReferenceElement> {
-  @Override
-  public void registerFixes(@NotNull final PsiJavaCodeReferenceElement reference, @NotNull QuickFixActionRegistrar registrar) {
-    final PsiElement psiElement = reference.getElement();
-    @NonNls final String referenceName = reference.getRangeInElement().substring(psiElement.getText());
-
-    Project project = psiElement.getProject();
-    PsiFile containingFile = psiElement.getContainingFile();
-    if (containingFile == null) return;
-
-    final VirtualFile classVFile = containingFile.getVirtualFile();
-    if (classVFile == null) return;
-
-    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
-    final Module currentModule = fileIndex.getModuleForFile(classVFile);
-    if (currentModule == null) return;
-
-    final JavaTestFramework framework;
-    @NonNls final String className;
-    if ("TestCase".equals(referenceName)) {
-      framework = TestFramework.EXTENSION_NAME.findExtension(JUnit3Framework.class);
-      className = "junit.framework.TestCase";
-    }
-    else if (PsiTreeUtil.getParentOfType(psiElement, PsiAnnotation.class) != null && isJunitAnnotationName(referenceName, psiElement)) {
-      framework = TestFramework.EXTENSION_NAME.findExtension(JUnit4Framework.class);
-      className = "org.junit." + referenceName;
-    }
-    else {
-      return;
-    }
-
-    PsiClass found = JavaPsiFacade.getInstance(project).findClass(className, currentModule.getModuleWithDependenciesAndLibrariesScope(true));
-    if (found != null) return;
-
-    final OrderEntryFix platformFix = new OrderEntryFix() {
-      @Override
-      @NotNull
-      public String getText() {
-        return QuickFixBundle.message("orderEntry.fix.add.junit.jar.to.classpath");
-      }
-
-      @Override
-      @NotNull
-      public String getFamilyName() {
-        return getText();
-      }
-
-      @Override
-      public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
-        return !project.isDisposed() && !currentModule.isDisposed();
-      }
-
-      @Override
-      public void invoke(@NotNull Project project, @Nullable Editor editor, PsiFile file) {
-        List<String> jarPaths = framework.getLibraryPaths();
-        String libraryName = jarPaths.size() == 1 ? null : framework.getName();
-        addJarsToRootsAndImportClass(jarPaths, libraryName, currentModule, editor, reference, className);
-      }
-    };
-
-    final OrderEntryFix providedFix = MissingDependencyFixUtil.provideFix(new Function<MissingDependencyFixProvider, OrderEntryFix>() {
-      @Override
-      public OrderEntryFix fun(MissingDependencyFixProvider provider) {
-        return provider.getJUnitFix(reference, platformFix, currentModule, framework, className);
-      }
-    });
-    final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix);
-
-    registrar.register(fix);
-  }
-
-  private static boolean isJunitAnnotationName(@NonNls final String referenceName, @NotNull final PsiElement psiElement) {
-    if ("Test".equals(referenceName) || "Ignore".equals(referenceName) || "RunWith".equals(referenceName) ||
-        "Before".equals(referenceName) || "BeforeClass".equals(referenceName) ||
-        "After".equals(referenceName) || "AfterClass".equals(referenceName)) {
-      return true;
-    }
-    final PsiElement parent = psiElement.getParent();
-    if (parent != null && !(parent instanceof PsiAnnotation)) {
-      final PsiReference reference = parent.getReference();
-      if (reference != null) {
-        final String referenceText = parent.getText();
-        if (isJunitAnnotationName(reference.getRangeInElement().substring(referenceText), parent)) {
-          final int lastDot = referenceText.lastIndexOf('.');
-          return lastDot > -1 && referenceText.substring(0, lastDot).equals("org.junit");
-        }
-      }
-    }
-    return false;
-  }
-
-  @NotNull
-  @Override
-  public Class<PsiJavaCodeReferenceElement> getReferenceClass() {
-    return PsiJavaCodeReferenceElement.class;
-  }
-}
index 10adc1cb4357811d3784ebb948c8ede17c1e1bb2..6f47dd780bad30906c0638b629207a5a8abbd375 100644 (file)
                        groupName="TestNG" enabledByDefault="true" level="ERROR"
                        implementationClass="com.theoryinpractice.testng.inspection.DataProviderReturnTypeInspection"/>
 
-      <intentionAction>
-          <className>com.theoryinpractice.testng.intention.TestNGOrderEntryFix</className>
-        </intentionAction>
-        <testFramework implementation="com.theoryinpractice.testng.TestNGFramework"/>
+      <testFramework implementation="com.theoryinpractice.testng.TestNGFramework"/>
+      <codeInsight.externalLibraryResolver implementation="com.theoryinpractice.testng.intention.TestNGExternalLibraryResolver"/>
       <standardResource url="http://testng.org/testng-1.0.dtd" path="resources/standardSchemas/testng-1.0.dtd"/>
       <overrideImplementsAnnotationsHandler implementation="com.theoryinpractice.testng.intention.OverrideImplementsTestNGAnnotationsHandler"/>
       <forcedElementWeigher implementation="com.theoryinpractice.testng.TestNGForcedElementWeigher"/>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/intention/TestNGExternalLibraryResolver.java b/plugins/testng/src/com/theoryinpractice/testng/intention/TestNGExternalLibraryResolver.java
new file mode 100644 (file)
index 0000000..211b64d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2015 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.theoryinpractice.testng.intention;
+
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryDescriptor;
+import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.PathUtil;
+import com.intellij.util.ThreeState;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class TestNGExternalLibraryResolver extends ExternalLibraryResolver {
+  private static final Set<String> TEST_NG_ANNOTATIONS = ContainerUtil.set(
+    "Test", "BeforeClass", "BeforeGroups", "BeforeMethod", "BeforeSuite", "BeforeTest", "AfterClass", "AfterGroups", "AfterMethod",
+    "AfterSuite", "AfterTest", "Configuration"
+  );
+  private static final ExternalLibraryDescriptor TESTNG_DESCRIPTOR = new ExternalLibraryDescriptor("org.testng", "testng", null) {
+    @NotNull
+    @Override
+    public List<String> locateLibraryClassesRoots(@NotNull Module contextModule) {
+      return Collections.singletonList(PathUtil.getJarPathForClass(Test.class));
+    }
+  };
+
+  @Nullable
+  @Override
+  public ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation) {
+    if (TEST_NG_ANNOTATIONS.contains(shortClassName)) {
+      return new ExternalClassResolveResult("org.testng.annotations." + shortClassName, TESTNG_DESCRIPTOR);
+    }
+    return null;
+  }
+}
diff --git a/plugins/testng/src/com/theoryinpractice/testng/intention/TestNGOrderEntryFix.java b/plugins/testng/src/com/theoryinpractice/testng/intention/TestNGOrderEntryFix.java
deleted file mode 100644 (file)
index 29c59ef..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2000-2009 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.
- */
-
-/*
- * User: anna
- * Date: 30-Jul-2007
- */
-package com.theoryinpractice.testng.intention;
-
-import com.intellij.codeInsight.TargetElementUtil;
-import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
-import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.lang.java.JavaLanguage;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.module.ModuleUtilCore;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.PathUtil;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.Test;
-
-import java.util.Collections;
-
-public class TestNGOrderEntryFix implements IntentionAction {
-  private static final Logger LOG = Logger.getInstance("#" + TestNGOrderEntryFix.class.getName());
-
-  @NotNull
-  public String getText() {
-    return "Add testng.jar to classpath";
-  }
-
-  @NotNull
-  public String getFamilyName() {
-    return getText();
-  }
-
-  public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
-    if (!(file instanceof PsiJavaFile)) return false;
-    if (!file.getLanguage().isKindOf(JavaLanguage.INSTANCE)) return false;
-
-    final PsiReference reference = TargetElementUtil.findReference(editor);
-    if (!(reference instanceof PsiJavaCodeReferenceElement)) return false;
-    if (reference.resolve() != null) return false;
-    @NonNls final String referenceName = ((PsiJavaCodeReferenceElement)reference).getReferenceName();
-    if (referenceName == null) return false;
-    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
-    final VirtualFile virtualFile = file.getVirtualFile();
-    if (virtualFile == null) return false;
-    if (fileIndex.getModuleForFile(virtualFile) == null) return false;
-    if (!(((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiAnnotation &&
-          PsiUtil.isLanguageLevel5OrHigher(((PsiJavaCodeReferenceElement)reference)))) return false;
-    if (!isTestNGAnnotationName(referenceName)) return false;
-    return true;
-  }
-
-  public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
-    final PsiJavaCodeReferenceElement reference = (PsiJavaCodeReferenceElement)TargetElementUtil.findReference(editor);
-    LOG.assertTrue(reference != null);
-    String jarPath = PathUtil.getJarPathForClass(Test.class);
-    final VirtualFile virtualFile = file.getVirtualFile();
-    LOG.assertTrue(virtualFile != null);
-    OrderEntryFix.addJarsToRootsAndImportClass(Collections.singletonList(jarPath), null, ModuleUtilCore.findModuleForFile(virtualFile, project),
-                                    editor, reference, "org.testng.annotations." + reference.getReferenceName());
-  }
-
-  public boolean startInWriteAction() {
-    return true;
-  }
-
-  private static boolean isTestNGAnnotationName(@NonNls final String referenceName) {
-    return "Test".equals(referenceName) ||
-           "BeforeClass".equals(referenceName) ||
-           "BeforeGroups".equals(referenceName) ||
-           "BeforeMethod".equals(referenceName) ||
-           "BeforeSuite".equals(referenceName) ||
-           "BeforeTest".equals(referenceName) ||
-           "AfterClass".equals(referenceName) ||
-           "AfterGroups".equals(referenceName) ||
-           "AfterMethod".equals(referenceName) ||
-           "AfterSuite".equals(referenceName) ||
-           "AfterTest".equals(referenceName) ||
-           "Configuration".equals(referenceName);
-
-  }
-}
\ No newline at end of file
index 71ee1d40597ce0cc787e0040ced13a320524ac66..0056de562fd45c464ebb81f56ec3f44b4642681e 100644 (file)
     <!--suppress DeprecatedClassUsageInspection -->
     <extensionPoint name="psi.clsCustomNavigationPolicy" interface="com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy"/>
 
+    <extensionPoint name="codeInsight.externalLibraryResolver" interface="com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver"/>
+
     <extensionPoint name="vetoSPICondition" interface="com.intellij.openapi.util.Condition"/>
 
     <extensionPoint name="hierarchy.referenceProcessor" interface="com.intellij.ide.hierarchy.call.CallReferenceProcessor"/>
     </intentionAction>
 
 
-    <intentionAction>
-      <className>com.intellij.codeInspection.concurrencyAnnotations.JCiPOrderEntryFix</className>
-    </intentionAction>
-
     <intentionAction>
       <className>com.intellij.codeInsight.intention.impl.RemoveLiteralUnderscoresAction</className>
       <category>Java/Numbers</category>
     <generation.toStringClassFilter implementation="org.jetbrains.generate.tostring.GenerateToStringInterfaceFilter" order="last"/>
 
     <codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>
+    <codeInsight.externalLibraryResolver
+        implementation="com.intellij.codeInsight.daemon.impl.quickfix.JetBrainsAnnotationsExternalLibraryResolver"/>
+    <codeInsight.externalLibraryResolver implementation="com.intellij.codeInspection.concurrencyAnnotations.JCiPExternalLibraryResolver"/>
 
     <refactoring.pullUpHelperFactory language="JAVA" implementationClass="com.intellij.refactoring.memberPullUp.JavaPullUpHelperFactory"/>
     <hierarchy.referenceProcessor implementation="com.intellij.ide.hierarchy.call.JavaCallReferenceProcessor"/>