下面列出了com.intellij.psi.impl.cache.CacheManager#consulo.application.AccessRule 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Nullable
private static Document createPsiDocument(@Nonnull Project project,
@Nonnull String content,
@Nonnull FileType fileType,
@Nonnull String fileName,
boolean readOnly) {
ThrowableComputable<Document,RuntimeException> action = () -> {
LightVirtualFile file = new LightVirtualFile(fileName, fileType, content);
file.setWritable(!readOnly);
file.putUserData(DiffPsiFileSupport.KEY, true);
Document document = FileDocumentManager.getInstance().getDocument(file);
if (document == null) return null;
PsiDocumentManager.getInstance(project).getPsiFile(document);
return document;
};
return AccessRule.read(action);
}
private Set<VirtualFile> getRootsToIterate(final Module module) {
return AccessRule.read(() -> {
if (module.isDisposed()) return Collections.emptySet();
Set<VirtualFile> result = new LinkedHashSet<>();
for (VirtualFile[] roots : getModuleContentAndSourceRoots(module)) {
for (VirtualFile root : roots) {
DirectoryInfo info = getInfoForFileOrDirectory(root);
if (!info.isInProject(root)) continue; // is excluded or ignored
if (!module.equals(info.getModule())) continue; // maybe 2 modules have the same content root?
VirtualFile parent = root.getParent();
if (parent != null) {
DirectoryInfo parentInfo = getInfoForFileOrDirectory(parent);
if (isFileInContent(parent, parentInfo)) continue;
}
result.add(root);
}
}
return result;
});
}
public void loadState(Element element) {
String url = element.getAttributeValue(URL);
if (url != null) {
setCompilerOutputUrl(url);
}
for (Element moduleElement : element.getChildren("module")) {
String name = moduleElement.getAttributeValue("name");
if (name == null) {
continue;
}
Module module = AccessRule.read(() -> myModuleManager.findModuleByName(name));
if (module != null) {
ModuleCompilerPathsManagerImpl moduleCompilerPathsManager = (ModuleCompilerPathsManagerImpl)ModuleCompilerPathsManager.getInstance(module);
moduleCompilerPathsManager.loadState(moduleElement);
}
}
}
public static MultiMap<String, Artifact> createOutputToArtifactMap(final Project project) {
final MultiMap<String, Artifact> result = new MultiMap<String, Artifact>() {
@Nonnull
@Override
protected Map<String, Collection<Artifact>> createMap() {
return new THashMap<String, Collection<Artifact>>(FileUtil.PATH_HASHING_STRATEGY);
}
};
AccessRule.read(() -> {
for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
String outputPath = artifact.getOutputFilePath();
if (!StringUtil.isEmpty(outputPath)) {
result.putValue(outputPath, artifact);
}
}
});
return result;
}
public void loadModules(@Nonnull ProgressIndicator indicator, AsyncResult<Void> result) {
StatCollector stat = new StatCollector();
stat.markWith("load modules", () -> loadModules(myModuleModel, indicator, true));
indicator.setIndeterminate(true);
AccessRule.writeAsync(() -> {
stat.markWith("fire modules add", () -> {
for (Module module : myModuleModel.myModules) {
fireModuleAdded(module);
}
});
stat.dump("ModulesManager", LOG::info);
}).doWhenDone((Runnable)result::setDone);
}
public static FilePath getLocalPath(@Nonnull Project project, FilePath filePath) {
// check if the file has just been renamed (IDEADEV-15494)
ThrowableComputable<Change, RuntimeException> action = () -> {
if (project.isDisposed()) throw new ProcessCanceledException();
return ChangeListManager.getInstance(project).getChange(filePath);
};
Change change = AccessRule.read(action);
if (change != null) {
ContentRevision beforeRevision = change.getBeforeRevision();
ContentRevision afterRevision = change.getAfterRevision();
if (beforeRevision != null && afterRevision != null && !beforeRevision.getFile().equals(afterRevision.getFile()) &&
beforeRevision.getFile().equals(filePath)) {
return afterRevision.getFile();
}
}
return filePath;
}
@javax.annotation.Nullable
private static VirtualFile getValidParentUnderReadAction(@Nonnull FilePath filePath) {
ThrowableComputable<VirtualFile,RuntimeException> action = () -> {
VirtualFile result = null;
FilePath parent = filePath;
LocalFileSystem lfs = LocalFileSystem.getInstance();
while (result == null && parent != null) {
result = lfs.findFileByPath(parent.getPath());
parent = parent.getParentPath();
}
return result;
};
return AccessRule.read(action);
}
private <B extends XBreakpoint<?>> void handleBreakpoint(final XBreakpointHandler<B> handler, final B b, final boolean register,
final boolean temporary) {
if (register) {
ThrowableComputable<Boolean,RuntimeException> action = () -> isBreakpointActive(b);
boolean active = AccessRule.read(action);
if (active) {
synchronized (myRegisteredBreakpoints) {
myRegisteredBreakpoints.put(b, new CustomizedBreakpointPresentation());
}
handler.registerBreakpoint(b);
}
}
else {
boolean removed;
synchronized (myRegisteredBreakpoints) {
removed = myRegisteredBreakpoints.remove(b) != null;
}
if (removed) {
handler.unregisterBreakpoint(b, temporary);
}
}
}
@Override
public String getContent() {
if (myContent == null) {
String localContext = AccessRule.read(() -> {
final Document doc = FileDocumentManager.getInstance().getDocument(myVf);
if(doc == null) {
return null;
}
return doc.getText();
});
if (localContext == null) {
myPatchApplyFailed = true;
return null;
}
final GenericPatchApplier applier = new GenericPatchApplier(localContext, myPatch.getHunks());
if (applier.execute()) {
myContent = applier.getAfter();
} else {
myPatchApplyFailed = true;
}
}
return myContent;
}
@Nonnull
static PsiElement[] getSelfAndImplementations(Editor editor, @Nonnull PsiElement element, @Nonnull ImplementationSearcher handler, final boolean includeSelfAlways) {
final PsiElement[] handlerImplementations = handler.searchImplementations(element, editor, includeSelfAlways, true);
if (handlerImplementations.length > 0) return handlerImplementations;
ThrowableComputable<PsiElement[], RuntimeException> action = () -> {
PsiElement psiElement = element;
PsiFile psiFile = psiElement.getContainingFile();
if (psiFile == null) {
// Magically, it's null for ant property declarations.
psiElement = psiElement.getNavigationElement();
psiFile = psiElement.getContainingFile();
if (psiFile == null) {
return PsiElement.EMPTY_ARRAY;
}
}
if (psiFile.getVirtualFile() != null && (psiElement.getTextRange() != null || psiElement instanceof PsiFile)) {
return new PsiElement[]{psiElement};
}
return PsiElement.EMPTY_ARRAY;
};
return AccessRule.read(action);
}
/**
* Allows to answer if any file that belongs to the given project has changes in comparison with VCS.
*
* @param project target project to check
* @return <code>true</code> if any file that belongs to the given project has changes in comparison with VCS
* <code>false</code> otherwise
*/
public static boolean hasChanges(@Nonnull final Project project) {
ThrowableComputable<ModifiableModuleModel,RuntimeException> action = () -> ModuleManager.getInstance(project).getModifiableModel();
final ModifiableModuleModel moduleModel = AccessRule.read(action);
try {
for (Module module : moduleModel.getModules()) {
if (hasChanges(module)) {
return true;
}
}
return false;
}
finally {
moduleModel.dispose();
}
}
private void doCheck(final ProjectStructureElement element) {
final ProjectStructureProblemsHolderImpl problemsHolder = new ProjectStructureProblemsHolderImpl();
AccessRule.read(() -> {
if (myStopped.get()) return;
if (LOG.isDebugEnabled()) {
LOG.debug("checking " + element);
}
ProjectStructureValidator.check(element, problemsHolder);
});
invokeLater(new Runnable() {
@Override
public void run() {
if (myStopped.get()) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating problems for " + element);
}
final ProjectStructureProblemDescription warning = myWarningsAboutUnused.get(element);
if (warning != null) problemsHolder.registerProblem(warning);
myProblemHolders.put(element, problemsHolder);
myDispatcher.getMulticaster().problemsChanged(element);
}
});
}
private void doCollectUsages(final ProjectStructureElement element) {
ThrowableComputable<List<ProjectStructureElementUsage>,RuntimeException> action = () -> {
if (myStopped.get()) return null;
if (LOG.isDebugEnabled()) {
LOG.debug("collecting usages in " + element);
}
return getUsagesInElement(element);
};
final List<ProjectStructureElementUsage> usages = AccessRule.read(action);
invokeLater(new Runnable() {
@Override
public void run() {
if (myStopped.get() || usages == null) return;
if (LOG.isDebugEnabled()) {
LOG.debug("updating usages for " + element);
}
updateUsages(element, usages);
}
});
}
@SuppressWarnings("MethodMayBeStatic")
@Nullable
public Icon getIcon(final Object object) {
if (!NavBarModel.isValid(object)) return null;
if (object instanceof Project) return AllIcons.Nodes.ProjectTab;
if (object instanceof Module) return AllIcons.Nodes.Module;
try {
if (object instanceof PsiElement) {
Icon icon = TargetAWT.to(AccessRule.read(() -> ((PsiElement)object).isValid() ? IconDescriptorUpdaters.getIcon(((PsiElement)object), 0) : null));
if (icon != null && (icon.getIconHeight() > JBUI.scale(16) || icon.getIconWidth() > JBUI.scale(16))) {
icon = IconUtil.cropIcon(icon, JBUI.scale(16), JBUI.scale(16));
}
return icon;
}
}
catch (IndexNotReadyException e) {
return null;
}
if (object instanceof ModuleExtensionWithSdkOrderEntry) {
return TargetAWT.to(SdkUtil.getIcon(((ModuleExtensionWithSdkOrderEntry)object).getSdk()));
}
if (object instanceof LibraryOrderEntry) return AllIcons.Nodes.PpLibFolder;
if (object instanceof ModuleOrderEntry) return AllIcons.Nodes.Module;
return null;
}
/**
* Finds duplicates of the code fragment specified in the finder in given scopes.
* Note that in contrast to {@link #processDuplicates} the search is performed synchronously because normally you need the results in
* order to complete the refactoring. If user cancels it, empty list will be returned.
*
* @param finder finder object to seek for duplicates
* @param searchScopes scopes where to look them in
* @param generatedMethod new method that should be excluded from the search
* @return list of discovered duplicate code fragments or empty list if user interrupted the search
* @see #replaceDuplicates(PsiElement, Editor, Consumer, List)
*/
@Nonnull
public static List<SimpleMatch> collectDuplicates(@Nonnull SimpleDuplicatesFinder finder,
@Nonnull List<PsiElement> searchScopes,
@Nonnull PsiElement generatedMethod) {
final Project project = generatedMethod.getProject();
try {
//noinspection RedundantCast
return ProgressManager.getInstance().runProcessWithProgressSynchronously(
(ThrowableComputable<List<SimpleMatch>, RuntimeException>)() -> {
ProgressManager.getInstance().getProgressIndicator().setIndeterminate(true);
ThrowableComputable<List<SimpleMatch>, RuntimeException> action = () -> finder.findDuplicates(searchScopes, generatedMethod);
return AccessRule.read(action);
}, RefactoringBundle.message("searching.for.duplicates"), true, project);
}
catch (ProcessCanceledException e) {
return Collections.emptyList();
}
}
@Override
public void fetchChildren(@Nonnull Function<T, TreeNode<T>> nodeFactory, @Nullable T parentValue) {
ThrowableComputable<Object[],RuntimeException> action = () -> myStructure.getChildElements(parentValue);
for (Object o : AccessRule.read(action)) {
T element = (T)o;
TreeNode<T> apply = nodeFactory.apply(element);
apply.setLeaf(o instanceof AbstractTreeNode && !((AbstractTreeNode)o).isAlwaysShowPlus());
apply.setRender((fileElement, itemPresentation) -> {
NodeDescriptor descriptor = myStructure.createDescriptor(element, null);
descriptor.update();
itemPresentation.append(descriptor.toString());
try {
AccessRule.read(() -> itemPresentation.setIcon(descriptor.getIcon()));
}
catch (Exception e) {
e.printStackTrace();
}
});
}
}
@Override
public void processQuery(@Nonnull ReferencesSearch.SearchParameters queryParameters, @Nonnull Processor<? super PsiReference> consumer)
{
PsiElement elementToSearch = queryParameters.getElementToSearch();
if(elementToSearch instanceof CSharpTypeDeclaration)
{
String name = AccessRule.read(((CSharpTypeDeclaration) elementToSearch)::getName);
if(name == null)
{
return;
}
for(DotNetNamedElement member : AccessRule.read(((CSharpTypeDeclaration) elementToSearch)::getMembers))
{
if(member instanceof CSharpConstructorDeclaration)
{
queryParameters.getOptimizer().searchWord(name, queryParameters.getEffectiveSearchScope(), true, member);
}
}
CSharpLightConstructorDeclarationBuilder constructor = AccessRule.read(() -> StructOrGenericParameterConstructorProvider.buildDefaultConstructor((DotNetNamedElement) elementToSearch, name));
queryParameters.getOptimizer().searchWord(name, queryParameters.getEffectiveSearchScope(), true, constructor);
} /*
else if(elementToSearch instanceof CSharpConstructorDeclaration)
{
PsiElement parent = elementToSearch.getParent();
if(parent instanceof CSharpTypeDeclaration)
{
ReferencesSearch.search(parent, queryParameters.getEffectiveSearchScope(), queryParameters.isIgnoreAccessScope()).forEach
(consumer);
}
} */
}
@Nonnull
private static File createTempFile(@Nonnull final DocumentContent content, @Nonnull FileNameInfo fileName) throws IOException {
FileDocumentManager.getInstance().saveDocument(content.getDocument());
LineSeparator separator = content.getLineSeparator();
if (separator == null) separator = LineSeparator.getSystemLineSeparator();
Charset charset = content.getCharset();
if (charset == null) charset = Charset.defaultCharset();
Boolean hasBom = content.hasBom();
if (hasBom == null) hasBom = CharsetToolkit.getMandatoryBom(charset) != null;
ThrowableComputable<String,RuntimeException> action = () -> {
return content.getDocument().getText();
};
String contentData = AccessRule.read(action);
if (separator != LineSeparator.LF) {
contentData = StringUtil.convertLineSeparators(contentData, separator.getSeparatorString());
}
byte[] bytes = contentData.getBytes(charset);
byte[] bom = hasBom ? CharsetToolkit.getPossibleBom(charset) : null;
if (bom != null) {
bytes = ArrayUtil.mergeArrays(bom, bytes);
}
return createFile(bytes, fileName);
}
@javax.annotation.Nullable
@Override
public DocumentContent createDocument(@javax.annotation.Nullable Project project, @Nonnull final VirtualFile file) {
// TODO: add notification, that file is decompiled ?
if (file.isDirectory()) return null;
ThrowableComputable<Document, RuntimeException> action = () -> {
return FileDocumentManager.getInstance().getDocument(file);
};
Document document = AccessRule.read(action);
if (document == null) return null;
return new FileDocumentContentImpl(project, document, file);
}
@Nonnull
protected ModuleEx createAndLoadModule(@Nonnull final ModuleLoadItem moduleLoadItem, @Nonnull ModuleModelImpl moduleModel, @Nullable final ProgressIndicator progressIndicator) {
final ModuleEx module = createModule(moduleLoadItem.getName(), moduleLoadItem.getDirUrl(), progressIndicator);
moduleModel.initModule(module);
collapseOrExpandMacros(module, moduleLoadItem.getElement(), false);
final ModuleRootManagerImpl moduleRootManager = (ModuleRootManagerImpl)ModuleRootManager.getInstance(module);
AccessRule.read(() -> moduleRootManager.loadState(moduleLoadItem.getElement(), progressIndicator));
return module;
}
@Override
public boolean iterateContent(@Nonnull ContentIterator processor, @Nullable VirtualFileFilter filter) {
Module[] modules = AccessRule.read(() -> ModuleManager.getInstance(myProject).getModules());
for (final Module module : modules) {
for (VirtualFile contentRoot : getRootsToIterate(module)) {
if (!iterateContentUnderDirectory(contentRoot, processor, filter)) {
return false;
}
}
}
return true;
}
@Override
public boolean iterateContent(@Nonnull ContentIterator processor, @Nullable VirtualFileFilter filter) {
final Set<VirtualFile> contentRoots = AccessRule.read(() -> {
if (myModule.isDisposed()) return Collections.emptySet();
Set<VirtualFile> result = new LinkedHashSet<>();
VirtualFile[][] allRoots = getModuleContentAndSourceRoots(myModule);
for (VirtualFile[] roots : allRoots) {
for (VirtualFile root : roots) {
DirectoryInfo info = getInfoForFileOrDirectory(root);
if (!info.isInProject(root)) continue;
VirtualFile parent = root.getParent();
if (parent != null) {
DirectoryInfo parentInfo = myDirectoryIndex.getInfoForFile(parent);
if (parentInfo.isInProject(parent) && myModule.equals(parentInfo.getModule())) continue; // inner content - skip it
}
result.add(root);
}
}
return result;
});
for (VirtualFile contentRoot : contentRoots) {
if (!iterateContentUnderDirectory(contentRoot, processor, filter)) {
return false;
}
}
return true;
}
public UsageInfo2UsageAdapter(@Nonnull final UsageInfo usageInfo) {
myUsageInfo = usageInfo;
myMergedUsageInfos = usageInfo;
ThrowableComputable<Point, RuntimeException> action = () -> {
PsiElement element = getElement();
PsiFile psiFile = usageInfo.getFile();
Document document = psiFile == null ? null : PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
int offset;
int lineNumber;
if (document == null) {
// element over light virtual file
offset = element == null ? 0 : element.getTextOffset();
lineNumber = -1;
}
else {
int startOffset = myUsageInfo.getNavigationOffset();
if (startOffset == -1) {
offset = element == null ? 0 : element.getTextOffset();
lineNumber = -1;
}
else {
offset = -1;
lineNumber = getLineNumber(document, startOffset);
}
}
return new Point(offset, lineNumber);
};
Point data = AccessRule.read(action);
myOffset = data.x;
myLineNumber = data.y;
myModificationStamp = getCurrentModificationStamp();
}
private Label label(final LabelImpl impl) {
return new Label() {
@Override
public void revert(@Nonnull Project project, @Nonnull VirtualFile file) throws LocalHistoryException {
revertToLabel(project, file, impl);
}
@Override
public ByteContent getByteContent(final String path) {
ThrowableComputable<ByteContent, RuntimeException> action = () -> impl.getByteContent(myGateway.createTransientRootEntryForPathOnly(path), path);
return AccessRule.read(action);
}
};
}
@Nullable
@Override
public byte[] getByteContent(final VirtualFile f, final FileRevisionTimestampComparator c) {
if (!isInitialized()) return null;
if (!myGateway.areContentChangesVersioned(f)) return null;
ThrowableComputable<byte[], RuntimeException> action = () -> new ByteContentRetriever(myGateway, myVcs, f, c).getResult();
return AccessRule.read(action);
}
public static AsyncResult<Void> startPackagingFiles(final Project project, final List<VirtualFile> files, final Artifact[] artifacts) {
final AsyncResult<Void> callback = new AsyncResult<>();
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Packaging Files") {
@Override
public void run(@Nonnull ProgressIndicator indicator) {
try {
for (final VirtualFile file : files) {
indicator.checkCanceled();
AccessRule.read(() -> {
try {
packageFile(file, project, artifacts);
}
catch (IOException e) {
String message = CompilerBundle.message("message.tect.package.file.io.error", e.toString());
Notifications.Bus.notify(new Notification("Package File", "Cannot package file", message, NotificationType.ERROR));
}
});
callback.setDone();
}
}
finally {
if (!callback.isDone()) {
callback.setRejected();
}
}
}
});
return callback;
}
@Nonnull
@Override
public List<ArtifactCompilerCompileItem> getItems(@Nonnull ArtifactBuildTarget target) {
myBuilderContext = new ArtifactsProcessingItemsBuilderContext(myContext);
final Artifact artifact = target.getArtifact();
ThrowableComputable<Map<String,String>,RuntimeException> action = () -> ArtifactSortingUtil.getInstance(getProject()).getArtifactToSelfIncludingNameMap();
final Map<String, String> selfIncludingArtifacts = AccessRule.read(action);
final String selfIncludingName = selfIncludingArtifacts.get(artifact.getName());
if (selfIncludingName != null) {
String name = selfIncludingName.equals(artifact.getName()) ? "it" : "'" + selfIncludingName + "' artifact";
myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot build '" + artifact.getName() + "' artifact: " + name + " includes itself in the output layout", null, -1, -1);
return Collections.emptyList();
}
final String outputPath = artifact.getOutputPath();
if (outputPath == null || outputPath.length() == 0) {
myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified", null, -1, -1);
return Collections.emptyList();
}
DumbService.getInstance(getProject()).waitForSmartMode();
AccessRule.read(() -> {
collectItems(artifact, outputPath);
});
return new ArrayList<ArtifactCompilerCompileItem>(myBuilderContext.getProcessingItems());
}
private void clearAffectedOutputPathsIfPossible(final CompileContextEx context) {
ThrowableComputable<List<File>, RuntimeException> action = () -> {
final MultiMap<File, Module> outputToModulesMap = new MultiMap<>();
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
ModuleCompilerPathsManager moduleCompilerPathsManager = ModuleCompilerPathsManager.getInstance(module);
for (ContentFolderTypeProvider contentFolderTypeProvider : ContentFolderTypeProvider.filter(ContentFolderScopes.productionAndTest())) {
final String outputPathUrl = moduleCompilerPathsManager.getCompilerOutputUrl(contentFolderTypeProvider);
if (outputPathUrl != null) {
final String path = VirtualFileManager.extractPath(outputPathUrl);
outputToModulesMap.putValue(new File(path), module);
}
}
}
final Set<Module> affectedModules = new HashSet<>(Arrays.asList(context.getCompileScope().getAffectedModules()));
List<File> result = new ArrayList<>(affectedModules.size() * 2);
for (File output : outputToModulesMap.keySet()) {
if (affectedModules.containsAll(outputToModulesMap.get(output))) {
result.add(output);
}
}
final Set<Artifact> artifactsToBuild = ArtifactCompileScope.getArtifactsToBuild(myProject, context.getCompileScope(), true);
for (Artifact artifact : artifactsToBuild) {
final String outputFilePath = ((ArtifactImpl)artifact).getOutputDirectoryPathToCleanOnRebuild();
if (outputFilePath != null) {
result.add(new File(FileUtil.toSystemDependentName(outputFilePath)));
}
}
return result;
};
final List<File> scopeOutputs = AccessRule.read(action);
if (scopeOutputs.size() > 0) {
CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), () -> CompilerUtil.clearOutputDirectories(scopeOutputs));
}
}
@Override
protected final void doSave(@Nullable List<SaveSession> saveSessions, @Nonnull List<Pair<SaveSession, File>> readonlyFiles) {
ProjectStorageUtil.UnableToSaveProjectNotification[] notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(ProjectStorageUtil.UnableToSaveProjectNotification.class, myProject);
if (notifications.length > 0) {
throw new SaveCancelledException();
}
beforeSave(readonlyFiles);
super.doSave(saveSessions, readonlyFiles);
if (!readonlyFiles.isEmpty()) {
ReadonlyStatusHandler.OperationStatus status = AccessRule.read(() -> {
List<File> filesList = getFilesList(readonlyFiles);
VirtualFile[] files = filesList.stream().map(file -> LocalFileSystem.getInstance().findFileByIoFile(file)).toArray(VirtualFile[]::new);
return ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(files);
});
if (status.hasReadonlyFiles()) {
ProjectStorageUtil.dropUnableToSaveProjectNotification(myProject, VfsUtil.virtualToIoFiles(Arrays.asList(status.getReadonlyFiles())));
throw new SaveCancelledException();
}
else {
List<Pair<SaveSession, File>> oldList = new ArrayList<>(readonlyFiles);
readonlyFiles.clear();
for (Pair<SaveSession, File> entry : oldList) {
executeSave(entry.first, readonlyFiles);
}
if (!readonlyFiles.isEmpty()) {
ProjectStorageUtil.dropUnableToSaveProjectNotification(myProject, getFilesList(readonlyFiles));
throw new SaveCancelledException();
}
}
}
}
@Override
@Nonnull
public FileEditorProvider[] getProviders(@Nonnull final Project project, @Nonnull final VirtualFile file) {
// Collect all possible editors
List<FileEditorProvider> sharedProviders = new ArrayList<>();
boolean doNotShowTextEditor = false;
for (final FileEditorProvider provider : myProviders) {
ThrowableComputable<Boolean, RuntimeException> action = () -> {
if (DumbService.isDumb(project) && !DumbService.isDumbAware(provider)) {
return false;
}
return provider.accept(project, file);
};
if (AccessRule.read(action)) {
sharedProviders.add(provider);
doNotShowTextEditor |= provider.getPolicy() == FileEditorPolicy.HIDE_DEFAULT_EDITOR;
}
}
// Throw out default editors provider if necessary
if (doNotShowTextEditor) {
ContainerUtil.retainAll(sharedProviders, provider -> !(provider instanceof TextEditorProvider));
}
// Sort editors according policies
Collections.sort(sharedProviders, MyComparator.ourInstance);
return sharedProviders.toArray(new FileEditorProvider[sharedProviders.size()]);
}