quick fixes: extension point for order entry quick fixes to override or complement default platform fixes added

This commit is contained in:
Vladislav.Soroka
2015-07-16 10:54:56 +03:00
parent f478850c39
commit 5313a8cd3b
4 changed files with 173 additions and 8 deletions
@@ -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<LocalQuickFix> registerFixes(@NotNull QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) {
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());
@@ -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<OrderEntryFixProvider, OrderEntryFix>() {
@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<OrderEntryFixProvider, OrderEntryFix>() {
@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<OrderEntryFixProvider, OrderEntryFix>() {
@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<String> jarPaths, @Nullable String libraryName,
@NotNull Module module, @Nullable PsiElement location) {
public static void addJarsToRoots(@NotNull final List<String> jarPaths, @Nullable final String libraryName,
@NotNull final Module module, @Nullable final PsiElement location) {
final Boolean isAdded = OrderEntryFixProvider.find(new Function<OrderEntryFixProvider, Boolean>() {
@Override
public Boolean fun(OrderEntryFixProvider provider) {
return provider.addJarsToRoots(jarPaths, libraryName, module, location);
}
});
if (Boolean.TRUE.equals(isAdded)) return;
List<String> urls = ContainerUtil.map(jarPaths, new Function<String, String>() {
@Override
public String fun(String path) {
@@ -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.
* <p/>
* 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<OrderEntryFixProvider> EP_NAME =
ExtensionPointName.create("com.intellij.codeInsight.orderEntryFixProvider");
@Nullable
public static List<LocalQuickFix> findFixes(Function<OrderEntryFixProvider, List<LocalQuickFix>> provider) {
OrderEntryFixProvider[] fixProviders = Extensions.getExtensions(EP_NAME);
for (OrderEntryFixProvider each : fixProviders) {
List<LocalQuickFix> result = provider.fun(each);
if (result != null && !result.isEmpty()) return result;
}
return null;
}
@Nullable
public static <T> T find(Function<OrderEntryFixProvider, T> 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<LocalQuickFix> 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<String> jarPaths, @Nullable String libraryName,
@NotNull Module module, @Nullable PsiElement location) {
return Boolean.FALSE;
}
}
@@ -52,6 +52,8 @@
<extensionPoint name="codeInsight.unresolvedReferenceQuickFixProvider"
interface="com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider"/>
<extensionPoint name="codeInsight.orderEntryFixProvider"
interface="com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFixProvider"/>
<extensionPoint name="bidiRegionsSeparator"
beanClass="com.intellij.lang.LanguageExtensionPoint">
@@ -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<OrderEntryFixProvider, OrderEntryFix>() {
@Override
public OrderEntryFix fun(OrderEntryFixProvider provider) {
return provider.getJUnitFix(reference, platformFix, currentModule, framework, className);
}
});
final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix);
registrar.register(fix);
}