public AddModuleDependencyFix( Module currentModule, VirtualFile classVFile, PsiClass[] classes, PsiReference reference) { final PsiElement psiElement = reference.getElement(); final Project project = psiElement.getProject(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); for (PsiClass aClass : classes) { if (!facade.getResolveHelper().isAccessible(aClass, psiElement, aClass)) continue; PsiFile psiFile = aClass.getContainingFile(); if (psiFile == null) continue; VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) continue; final Module classModule = fileIndex.getModuleForFile(virtualFile); if (classModule != null && classModule != currentModule && !ModuleRootManager.getInstance(currentModule).isDependsOn(classModule)) { myModules.add(classModule); } } myCurrentModule = currentModule; myClassVFile = classVFile; myClasses = classes; myReference = reference; }
@Nullable public static List<LocalQuickFix> registerFixes( @NotNull final QuickFixActionRegistrar registrar, @NotNull final PsiReference reference) { final PsiElement psiElement = reference.getElement(); @NonNls final String shortReferenceName = reference.getRangeInElement().substring(psiElement.getText()); Project project = psiElement.getProject(); PsiFile containingFile = psiElement.getContainingFile(); if (containingFile == null) return null; final VirtualFile classVFile = containingFile.getVirtualFile(); if (classVFile == null) return null; final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); final Module currentModule = fileIndex.getModuleForFile(classVFile); if (currentModule == null) return null; final List<LocalQuickFix> providedFixes = findFixes( new Function<MissingDependencyFixProvider, List<LocalQuickFix>>() { @Override public List<LocalQuickFix> fun(MissingDependencyFixProvider provider) { return provider.registerFixes(registrar, reference); } }); if (providedFixes != null) { return providedFixes; } 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); } } if (fix != null) { registrar.register(fix); result.add(fix); } } if (!result.isEmpty()) { return result; } Set<Object> librariesToAdd = new THashSet<Object>(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(psiElement.getProject()); PsiClass[] classes = PsiShortNamesCache.getInstance(project) .getClassesByName(shortReferenceName, GlobalSearchScope.allScope(project)); List<PsiClass> allowedDependencies = filterAllowedDependencies(psiElement, classes); if (allowedDependencies.isEmpty()) { return result; } classes = allowedDependencies.toArray(new PsiClass[allowedDependencies.size()]); OrderEntryFix moduleDependencyFix = new AddModuleDependencyFix(currentModule, classVFile, classes, reference); final PsiClass[] finalClasses = classes; final OrderEntryFix finalModuleDependencyFix = moduleDependencyFix; final OrderEntryFix providedModuleDependencyFix = provideFix( new Function<MissingDependencyFixProvider, OrderEntryFix>() { @Override public OrderEntryFix fun(MissingDependencyFixProvider 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) { if (!facade.getResolveHelper().isAccessible(aClass, psiElement, aClass)) continue; PsiFile psiFile = aClass.getContainingFile(); if (psiFile == null) continue; VirtualFile virtualFile = psiFile.getVirtualFile(); if (virtualFile == null) continue; ModuleFileIndex moduleFileIndex = ModuleRootManager.getInstance(currentModule).getFileIndex(); for (OrderEntry orderEntry : fileIndex.getOrderEntriesForFile(virtualFile)) { if (orderEntry instanceof LibraryOrderEntry) { final LibraryOrderEntry libraryEntry = (LibraryOrderEntry) orderEntry; final Library library = libraryEntry.getLibrary(); if (library == null) continue; VirtualFile[] files = library.getFiles(OrderRootType.CLASSES); if (files.length == 0) continue; final VirtualFile jar = files[0]; if (jar == null || libraryEntry.isModuleLevel() && !librariesToAdd.add(jar) || !librariesToAdd.add(library)) continue; OrderEntry entryForFile = moduleFileIndex.getOrderEntryForFile(virtualFile); if (entryForFile != null && !(entryForFile instanceof ExportableOrderEntry && ((ExportableOrderEntry) entryForFile).getScope() == DependencyScope.TEST && !ModuleRootManager.getInstance(currentModule) .getFileIndex() .isInTestSourceContent(classVFile))) { continue; } final OrderEntryFix platformFix = new OrderEntryFix() { @Override @NotNull public String getText() { return QuickFixBundle.message( "orderEntry.fix.add.library.to.classpath", libraryEntry.getPresentableName()); } @Override @NotNull public String getFamilyName() { return QuickFixBundle.message("orderEntry.fix.family.add.library.to.classpath"); } @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return !project.isDisposed() && !currentModule.isDisposed() && libraryEntry.isValid(); } @Override public void invoke( @NotNull final Project project, @Nullable final Editor editor, PsiFile file) { OrderEntryUtil.addLibraryToRoots(libraryEntry, currentModule); if (editor != null) { DumbService.getInstance(project) .withAlternativeResolveEnabled( new Runnable() { @Override public void run() { new AddImportAction(project, reference, editor, aClass).execute(); } }); } } }; final OrderEntryFix providedFix = provideFix( new Function<MissingDependencyFixProvider, OrderEntryFix>() { @Override public OrderEntryFix fun(MissingDependencyFixProvider provider) { return provider.getAddLibraryToClasspathFix( reference, platformFix, currentModule, libraryEntry, aClass); } }); final OrderEntryFix fix = ObjectUtils.notNull(providedFix, platformFix); registrar.register(fix); result.add(fix); } } } return result; }