From 5313a8cd3b5e71f243adf45be9f6a49844d71c81 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 16 Jul 2015 10:22:07 +0300 Subject: [PATCH] quick fixes: extension point for order entry quick fixes to override or complement default platform fixes added --- .../daemon/impl/quickfix/OrderEntryFix.java | 51 ++++++-- .../impl/quickfix/OrderEntryFixProvider.java | 114 ++++++++++++++++++ .../src/META-INF/LangExtensionPoints.xml | 2 + ...itUnresolvedReferenceQuickFixProvider.java | 14 ++- 4 files changed, 173 insertions(+), 8 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFixProvider.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java index 76389e1debdd..0750d9ef8ef8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java @@ -46,6 +46,7 @@ import com.intellij.psi.search.PsiShortNamesCache; 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.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; @@ -62,7 +63,7 @@ import java.util.Set; * @author cdr */ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { - private static final String JUNIT4_LIBRARY_NAME = "JUnit4"; + public static final String JUNIT4_LIBRARY_NAME = "JUnit4"; protected OrderEntryFix() { } @@ -84,7 +85,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { } @Nullable - public static List registerFixes(@NotNull QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) { + public static List registerFixes(@NotNull final QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) { final PsiElement psiElement = reference.getElement(); @NonNls final String referenceName = reference.getRangeInElement().substring(psiElement.getText()); @@ -104,7 +105,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { PsiClass found = JavaPsiFacade.getInstance(project).findClass(className, currentModule.getModuleWithDependenciesAndLibrariesScope(true)); if (found != null) return null; //no need to add junit to classpath - final OrderEntryFix fix = new OrderEntryFix() { + final OrderEntryFix platformFix = new OrderEntryFix() { @Override @NotNull public String getText() { @@ -141,6 +142,15 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { }); } }; + + final OrderEntryFix providedFix = OrderEntryFixProvider.find(new Function() { + @Override + public OrderEntryFix fun(OrderEntryFixProvider provider) { + return provider.getJetbrainsAnnotationFix(reference, platformFix, currentModule); + } + }); + final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix); + registrar.register(fix); return Collections.singletonList((LocalQuickFix)fix); } @@ -154,7 +164,18 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { return result; } classes = allowedDependencies.toArray(new PsiClass[allowedDependencies.size()]); - final OrderEntryFix moduleDependencyFix = new AddModuleDependencyFix(currentModule, classVFile, classes, reference); + OrderEntryFix moduleDependencyFix = new AddModuleDependencyFix(currentModule, classVFile, classes, reference); + + final PsiClass[] finalClasses = classes; + final OrderEntryFix finalModuleDependencyFix = moduleDependencyFix; + final OrderEntryFix providedModuleDependencyFix = OrderEntryFixProvider.find(new Function() { + @Override + public OrderEntryFix fun(OrderEntryFixProvider provider) { + return provider.getAddModuleDependencyFix(reference, finalModuleDependencyFix, currentModule, classVFile, finalClasses); + } + }); + moduleDependencyFix = ObjectUtils.notNull(providedModuleDependencyFix, moduleDependencyFix); + registrar.register(moduleDependencyFix); result.add(moduleDependencyFix); for (final PsiClass aClass : classes) { @@ -181,7 +202,7 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { !ModuleRootManager.getInstance(currentModule).getFileIndex().isInTestSourceContent(classVFile))) { continue; } - final OrderEntryFix fix = new OrderEntryFix() { + final OrderEntryFix platformFix = new OrderEntryFix() { @Override @NotNull public String getText() { @@ -212,6 +233,14 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { } } }; + + final OrderEntryFix providedFix = OrderEntryFixProvider.find(new Function() { + @Override + public OrderEntryFix fun(OrderEntryFixProvider provider) { + return provider.getAddLibraryToClasspathFix(reference, platformFix, currentModule, libraryEntry, aClass); + } + }); + final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix); registrar.register(fix); result.add(fix); } @@ -280,8 +309,16 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { addJarsToRoots(Collections.singletonList(jarPath), null, module, location); } - public static void addJarsToRoots(@NotNull List jarPaths, @Nullable String libraryName, - @NotNull Module module, @Nullable PsiElement location) { + public static void addJarsToRoots(@NotNull final List jarPaths, @Nullable final String libraryName, + @NotNull final Module module, @Nullable final PsiElement location) { + final Boolean isAdded = OrderEntryFixProvider.find(new Function() { + @Override + public Boolean fun(OrderEntryFixProvider provider) { + return provider.addJarsToRoots(jarPaths, libraryName, module, location); + } + }); + if (Boolean.TRUE.equals(isAdded)) return; + List urls = ContainerUtil.map(jarPaths, new Function() { @Override public String fun(String path) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFixProvider.java new file mode 100644 index 000000000000..1c2face6a7d1 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFixProvider.java @@ -0,0 +1,114 @@ +/* + * 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.QuickFixActionRegistrar; +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; + +import java.util.List; + +/** + * {@link OrderEntryFixProvider} extension can be used to override or complement default platform {@link OrderEntryFix}-es. + *

+ * It can be useful for modules imported from external build system like Maven, Gradle etc, + * when external build configuration(pom.xml/*.gradle scripts) should be changed in additional or instead of IntelliJ project configuration. + * + * @author Vladislav.Soroka + * @since 7/15/2015 + */ +public abstract class OrderEntryFixProvider { + private static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.codeInsight.orderEntryFixProvider"); + + @Nullable + public static List findFixes(Function> provider) { + OrderEntryFixProvider[] fixProviders = Extensions.getExtensions(EP_NAME); + for (OrderEntryFixProvider each : fixProviders) { + List result = provider.fun(each); + if (result != null && !result.isEmpty()) return result; + } + + return null; + } + + @Nullable + public static T find(Function provider) { + OrderEntryFixProvider[] fixProviders = Extensions.getExtensions(EP_NAME); + for (OrderEntryFixProvider each : fixProviders) { + T result = provider.fun(each); + if (result != null && Boolean.FALSE != result) return result; + } + + return null; + } + + @Nullable + public List registerFixes(@NotNull QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) { + 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, + @NotNull Module currentModule, + @NotNull VirtualFile classVFile, + @NotNull PsiClass[] classes) { + return null; + } + + @Nullable + public OrderEntryFix getAddLibraryToClasspathFix(@NotNull PsiReference reference, + @NotNull OrderEntryFix platformFix, + @NotNull Module currentModule, + @NotNull LibraryOrderEntry libraryEntry, + @NotNull PsiClass aClass) { + return null; + } + + @NotNull + public Boolean addJarsToRoots(@NotNull List jarPaths, @Nullable String libraryName, + @NotNull Module module, @Nullable PsiElement location) { + return Boolean.FALSE; + } +} diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index f1329b51867d..bba07d47fb02 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -52,6 +52,8 @@ + diff --git a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java index 2d3a53ee95ae..a6ba6f0da00a 100644 --- a/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java +++ b/plugins/junit/src/com/intellij/execution/junit/codeInsight/JUnitUnresolvedReferenceQuickFixProvider.java @@ -18,6 +18,7 @@ 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.OrderEntryFix; +import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFixProvider; import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.execution.junit.JUnit3Framework; import com.intellij.execution.junit.JUnit4Framework; @@ -31,6 +32,8 @@ 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; @@ -74,7 +77,7 @@ public class JUnitUnresolvedReferenceQuickFixProvider extends UnresolvedReferenc PsiClass found = JavaPsiFacade.getInstance(project).findClass(className, currentModule.getModuleWithDependenciesAndLibrariesScope(true)); if (found != null) return; - final OrderEntryFix fix = new OrderEntryFix() { + final OrderEntryFix platformFix = new OrderEntryFix() { @Override @NotNull public String getText() { @@ -99,6 +102,15 @@ public class JUnitUnresolvedReferenceQuickFixProvider extends UnresolvedReferenc addJarsToRootsAndImportClass(jarPaths, libraryName, currentModule, editor, reference, className); } }; + + final OrderEntryFix providedFix = OrderEntryFixProvider.find(new Function() { + @Override + public OrderEntryFix fun(OrderEntryFixProvider provider) { + return provider.getJUnitFix(reference, platformFix, currentModule, framework, className); + } + }); + final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix); + registrar.register(fix); }