use of com.intellij.openapi.application.ex.ApplicationEx in project intellij-community by JetBrains.
the class PsiSearchHelperImpl method processFilesConcurrentlyDespiteWriteActions.
// Tries to run {@code localProcessor} for each file in {@code files} concurrently on ForkJoinPool.
// When encounters write action request, stops all threads, waits for write action to finish and re-starts all threads again.
// {@localProcessor} must be as idempotent as possible.
public static boolean processFilesConcurrentlyDespiteWriteActions(@NotNull Project project, @NotNull List<VirtualFile> files, @NotNull final ProgressIndicator progress, @NotNull final Processor<VirtualFile> localProcessor) {
ApplicationEx app = (ApplicationEx) ApplicationManager.getApplication();
final AtomicBoolean canceled = new AtomicBoolean(false);
while (true) {
List<VirtualFile> failedList = new SmartList<>();
final List<VirtualFile> failedFiles = Collections.synchronizedList(failedList);
final Processor<VirtualFile> processor = vfile -> {
try {
boolean result = localProcessor.process(vfile);
if (!result) {
canceled.set(true);
}
return result;
} catch (ApplicationUtil.CannotRunReadActionException action) {
failedFiles.add(vfile);
}
return !canceled.get();
};
boolean completed;
if (app.isWriteAccessAllowed() || app.isReadAccessAllowed() && app.isWriteActionPending()) {
// no point in processing in separate threads - they are doomed to fail to obtain read action anyway
completed = ContainerUtil.process(files, processor);
} else if (app.isWriteActionPending()) {
completed = true;
// we don't have read action now so wait for write action to complete
failedFiles.addAll(files);
} else {
// try to run parallel read actions but fail as soon as possible
completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, true, processor);
}
if (!completed) {
return false;
}
if (failedFiles.isEmpty()) {
break;
}
// we failed to run read action in job launcher thread
// run read action in our thread instead to wait for a write action to complete and resume parallel processing
DumbService.getInstance(project).runReadActionInSmartMode(EmptyRunnable.getInstance());
files = failedList;
}
return true;
}
use of com.intellij.openapi.application.ex.ApplicationEx in project intellij-community by JetBrains.
the class DaemonCodeAnalyzerImpl method runPasses.
@NotNull
@TestOnly
List<HighlightInfo> runPasses(@NotNull PsiFile file, @NotNull Document document, @NotNull List<TextEditor> textEditors, @NotNull int[] toIgnore, boolean canChangeDocument, @Nullable final Runnable callbackWhileWaiting) throws ProcessCanceledException {
assert myInitialized;
assert !myDisposed;
ApplicationEx application = ApplicationManagerEx.getApplicationEx();
application.assertIsDispatchThread();
if (application.isWriteAccessAllowed()) {
throw new AssertionError("Must not start highlighting from within write action, or deadlock is imminent");
}
DaemonProgressIndicator.setDebug(!ApplicationInfoImpl.isInStressTest());
((FileTypeManagerImpl) FileTypeManager.getInstance()).drainReDetectQueue();
// pump first so that queued event do not interfere
UIUtil.dispatchAllInvocationEvents();
// refresh will fire write actions interfering with highlighting
while (RefreshQueueImpl.isRefreshInProgress() || HeavyProcessLatch.INSTANCE.isRunning()) {
UIUtil.dispatchAllInvocationEvents();
}
long dstart = System.currentTimeMillis();
while (mustWaitForSmartMode && DumbService.getInstance(myProject).isDumb()) {
if (System.currentTimeMillis() > dstart + 100000) {
throw new IllegalStateException("Timeout waiting for smart mode. If you absolutely want to be dumb, please use DaemonCodeAnalyzerImpl.mustWaitForSmartMode(false).");
}
UIUtil.dispatchAllInvocationEvents();
}
UIUtil.dispatchAllInvocationEvents();
Project project = file.getProject();
FileStatusMap fileStatusMap = getFileStatusMap();
fileStatusMap.allowDirt(canChangeDocument);
Map<FileEditor, HighlightingPass[]> map = new HashMap<>();
for (TextEditor textEditor : textEditors) {
if (textEditor instanceof TextEditorImpl) {
try {
((TextEditorImpl) textEditor).waitForLoaded(10, TimeUnit.SECONDS);
} catch (TimeoutException e) {
throw new RuntimeException(textEditor + " has not completed loading in 10 seconds");
}
}
TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter) textEditor.getBackgroundHighlighter();
if (highlighter == null) {
Editor editor = textEditor.getEditor();
throw new RuntimeException("Null highlighter from " + textEditor + "; loaded: " + AsyncEditorLoader.isEditorLoaded(editor));
}
final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
HighlightingPass[] array = passes.toArray(new HighlightingPass[passes.size()]);
assert array.length != 0 : "Highlighting is disabled for the file " + file;
map.put(textEditor, array);
}
for (int ignoreId : toIgnore) {
fileStatusMap.markFileUpToDate(document, ignoreId);
}
myUpdateRunnableFuture.cancel(false);
final DaemonProgressIndicator progress = createUpdateProgress();
myPassExecutorService.submitPasses(map, progress);
try {
long start = System.currentTimeMillis();
while (progress.isRunning() && System.currentTimeMillis() < start + 5 * 60 * 1000) {
wrap(() -> {
progress.checkCanceled();
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
waitInOtherThread(50, canChangeDocument);
UIUtil.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null)
throw savedException;
});
}
if (progress.isRunning() && !progress.isCanceled()) {
throw new RuntimeException("Highlighting still running after " + (System.currentTimeMillis() - start) / 1000 + " seconds.\n" + ThreadDumper.dumpThreadsToString());
}
final HighlightingSessionImpl session = (HighlightingSessionImpl) HighlightingSessionImpl.getOrCreateHighlightingSession(file, textEditors.get(0).getEditor(), progress, null);
wrap(() -> {
if (!waitInOtherThread(60000, canChangeDocument)) {
throw new TimeoutException("Unable to complete in 60s");
}
session.waitForHighlightInfosApplied();
});
UIUtil.dispatchAllInvocationEvents();
UIUtil.dispatchAllInvocationEvents();
assert progress.isCanceled() && progress.isDisposed();
return getHighlights(document, null, project);
} finally {
DaemonProgressIndicator.setDebug(false);
fileStatusMap.allowDirt(true);
waitForTermination();
}
}
use of com.intellij.openapi.application.ex.ApplicationEx in project intellij-community by JetBrains.
the class InspectionApplication method startup.
public void startup() {
if (myProjectPath == null) {
logError("Project to inspect is not defined");
printHelp();
}
if (myProfileName == null && myProfilePath == null && myStubProfile == null) {
logError("Profile to inspect with is not defined");
printHelp();
}
final ApplicationEx application = ApplicationManagerEx.getApplicationEx();
application.runReadAction(() -> {
try {
final ApplicationInfoEx appInfo = (ApplicationInfoEx) ApplicationInfo.getInstance();
logMessage(1, InspectionsBundle.message("inspection.application.starting.up", appInfo.getFullApplicationName() + " (build " + appInfo.getBuild().asString() + ")"));
application.doNotSave();
logMessageLn(1, InspectionsBundle.message("inspection.done"));
this.run();
} catch (Exception e) {
LOG.error(e);
} finally {
if (myErrorCodeRequired)
application.exit(true, true);
}
});
}
use of com.intellij.openapi.application.ex.ApplicationEx in project intellij-community by JetBrains.
the class DaemonRespondToChangesTest method testModificationInWorkspaceXmlDoesNotCauseRehighlight.
public void testModificationInWorkspaceXmlDoesNotCauseRehighlight() throws Exception {
configureByText(JavaFileType.INSTANCE, "class X { <caret> }");
ApplicationEx application = ApplicationManagerEx.getApplicationEx();
boolean appSave = application.isDoNotSave();
application.doNotSave(false);
try {
application.saveAll();
final PsiFile excluded = PsiManager.getInstance(getProject()).findFile(getProject().getWorkspaceFile());
List<HighlightInfo> errors = highlightErrors();
assertEmpty(errors);
FileStatusMap me = DaemonCodeAnalyzerEx.getInstanceEx(getProject()).getFileStatusMap();
TextRange scope = me.getFileDirtyScope(getEditor().getDocument(), Pass.UPDATE_ALL);
assertNull(scope);
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(excluded);
document.insertString(0, "<!-- dsfsd -->");
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
});
UIUtil.dispatchAllInvocationEvents();
scope = me.getFileDirtyScope(getEditor().getDocument(), Pass.UPDATE_ALL);
assertNull(scope);
} finally {
application.doNotSave(appSave);
}
}
use of com.intellij.openapi.application.ex.ApplicationEx in project intellij-community by JetBrains.
the class PopupFactoryImpl method createConfirmation.
@NotNull
@Override
public ListPopup createConfirmation(String title, final String yesText, String noText, final Runnable onYes, final Runnable onNo, int defaultOptionIndex) {
final BaseListPopupStep<String> step = new BaseListPopupStep<String>(title, new String[] { yesText, noText }) {
@Override
public PopupStep onChosen(String selectedValue, final boolean finalChoice) {
if (selectedValue.equals(yesText)) {
onYes.run();
} else {
onNo.run();
}
return FINAL_CHOICE;
}
@Override
public void canceled() {
onNo.run();
}
@Override
public boolean isMnemonicsNavigationEnabled() {
return true;
}
};
step.setDefaultOptionIndex(defaultOptionIndex);
final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
return app == null || !app.isUnitTestMode() ? new ListPopupImpl(step) : new MockConfirmation(step, yesText);
}
Aggregations