mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+5
-13
@@ -23,7 +23,6 @@ import com.intellij.codeInsight.daemon.impl.analysis.CustomHighlightInfoHolder;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager;
|
||||
import com.intellij.codeInsight.problems.ProblemImpl;
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -50,6 +49,7 @@ import com.intellij.psi.search.TodoItem;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.NotNullProducer;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -428,18 +428,10 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP
|
||||
private static void cancelAndRestartDaemonLater(@NotNull ProgressIndicator progress,
|
||||
@NotNull final Project project) throws ProcessCanceledException {
|
||||
progress.cancel();
|
||||
JobScheduler.getScheduler().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (!project.isDisposed() && !application.isDisposed() && !application.isUnitTestMode()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
}
|
||||
}, project.getDisposed());
|
||||
}
|
||||
EdtExecutorService.getScheduledExecutorInstance().schedule((Runnable)() -> {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (!project.isDisposed() && !application.isDisposed() && !application.isUnitTestMode()) {
|
||||
DaemonCodeAnalyzer.getInstance(project).restart();
|
||||
}
|
||||
}, RESTART_DAEMON_RANDOM.nextInt(100), TimeUnit.MILLISECONDS);
|
||||
throw new ProcessCanceledException();
|
||||
|
||||
@@ -94,7 +94,20 @@ public abstract class TransactionGuard {
|
||||
* @param transaction code to execute inside a transaction.
|
||||
*/
|
||||
public static void submitTransaction(@NotNull Runnable transaction) {
|
||||
getInstance().submitMergeableTransaction(TransactionKind.NO_MERGE, transaction);
|
||||
getInstance().submitMergeableTransaction(TransactionKind.ANY_CHANGE, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given code synchronously inside a transaction. Fails if transactions of given kind are not allowed at this moment.
|
||||
* @see #startSynchronousTransaction(TransactionKind)
|
||||
*/
|
||||
public static void syncTransaction(@NotNull TransactionKind kind, @NotNull Runnable transaction) {
|
||||
AccessToken token = getInstance().startSynchronousTransaction(kind);
|
||||
try {
|
||||
transaction.run();
|
||||
} finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,11 +27,6 @@ public interface TransactionKind {
|
||||
*/
|
||||
TransactionKind TEXT_EDITING = Common.TEXT_EDITING;
|
||||
|
||||
/**
|
||||
* Same as {@link Common#NO_MERGE}
|
||||
*/
|
||||
TransactionKind NO_MERGE = Common.NO_MERGE;
|
||||
|
||||
/**
|
||||
* Same as {@link Common#ANY_CHANGE}
|
||||
*/
|
||||
@@ -56,11 +51,7 @@ public interface TransactionKind {
|
||||
* <li>Project root set change
|
||||
* <li>Dumb mode (reindexing) start/finish, (see {@link com.intellij.openapi.project.DumbService}).
|
||||
*/
|
||||
ANY_CHANGE,
|
||||
ANY_CHANGE
|
||||
|
||||
/**
|
||||
* Transactions of this kind won't be merged into other transactions
|
||||
*/
|
||||
NO_MERGE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,5 +18,5 @@ public @interface WrapInTransaction {
|
||||
/**
|
||||
* @return the kind of transaction to wrap the action into. By default, it's {@link TransactionKind#NO_MERGE}.
|
||||
*/
|
||||
TransactionKind.Common value() default TransactionKind.Common.NO_MERGE;
|
||||
TransactionKind.Common value() default TransactionKind.Common.ANY_CHANGE;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
@NotNull
|
||||
public AccessToken startSynchronousTransaction(@NotNull TransactionKind kind) throws IllegalStateException {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (kind != TransactionKind.NO_MERGE && myMergeableKinds.contains(kind)) {
|
||||
if (myMergeableKinds.contains(kind)) {
|
||||
return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
}
|
||||
if (myTransactionStartTrace != null) {
|
||||
@@ -71,7 +71,7 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
|
||||
Runnable next = myQueue.poll();
|
||||
if (next != null) {
|
||||
runSyncTransaction(TransactionKind.NO_MERGE, next);
|
||||
runSyncTransaction(TransactionKind.ANY_CHANGE, next);
|
||||
}
|
||||
}
|
||||
}, app.getDisposed());
|
||||
@@ -118,7 +118,7 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
}
|
||||
|
||||
protected boolean canRunTransactionNow(@NotNull TransactionKind kind) {
|
||||
return !isInsideTransaction() || kind != TransactionKind.NO_MERGE && myMergeableKinds.contains(kind);
|
||||
return !isInsideTransaction() || myMergeableKinds.contains(kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -251,7 +251,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
|
||||
}
|
||||
if (containingFileByTree != null) {
|
||||
boolean isFromCommit = ApplicationManager.getApplication().isDispatchThread() &&
|
||||
ApplicationManager.getApplication().hasWriteAction(CommitToPsiFileAction.class);
|
||||
((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myProject)).isCommitInProgress();
|
||||
if (!isFromCommit && !synchronizer.isIgnorePsiEvents()) {
|
||||
reparseParallelTrees(containingFileByTree);
|
||||
if (docSynced) {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.psi.impl;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.DocumentRunnable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.IgnorePsiEventsMarker;
|
||||
|
||||
|
||||
public abstract class CommitToPsiFileAction extends DocumentRunnable implements IgnorePsiEventsMarker {
|
||||
protected CommitToPsiFileAction(Document document, Project project) {
|
||||
super(document,project);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,9 +19,7 @@ import com.intellij.diagnostic.ThreadDumper;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.FileASTNode;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationAdapter;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Attachment;
|
||||
@@ -75,6 +73,8 @@ import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class DocumentCommitThread implements Runnable, Disposable, DocumentCommitProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread");
|
||||
@@ -471,14 +471,29 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
throw new RuntimeException(s);
|
||||
}
|
||||
|
||||
CommitTask task = createNewTaskAndCancelSimilar(project, document, getAllFileNodes(psiFile), "Sync commit", ModalityState.current());
|
||||
assert !task.indicator.isCanceled();
|
||||
Pair<Runnable, Object> result = commitUnderProgress(task, true);
|
||||
Runnable finish = result.first;
|
||||
log(project, "Committed sync", task, finish, task.indicator);
|
||||
assert finish != null;
|
||||
List<Pair<PsiFileImpl, FileASTNode>> allFileNodes = getAllFileNodes(psiFile);
|
||||
|
||||
finish.run();
|
||||
Lock documentLock = getDocumentLock(document);
|
||||
|
||||
CommitTask task;
|
||||
synchronized (lock) {
|
||||
// synchronized to ensure no new similar tasks can start before we hold the document's lock
|
||||
task = createNewTaskAndCancelSimilar(project, document, allFileNodes, "Sync commit", ModalityState.current());
|
||||
documentLock.lock();
|
||||
}
|
||||
|
||||
try {
|
||||
assert !task.indicator.isCanceled();
|
||||
Pair<Runnable, Object> result = commitUnderProgress(task, true);
|
||||
Runnable finish = result.first;
|
||||
log(project, "Committed sync", task, finish, task.indicator);
|
||||
assert finish != null;
|
||||
|
||||
finish.run();
|
||||
}
|
||||
finally {
|
||||
documentLock.unlock();
|
||||
}
|
||||
|
||||
// will wake itself up on write action end
|
||||
}
|
||||
@@ -525,29 +540,40 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
myApplication.assertReadAccessAllowed();
|
||||
if (project.isDisposed()) return;
|
||||
|
||||
if (documentManager.isCommitted(document)) return;
|
||||
|
||||
if (!task.isStillValid()) {
|
||||
task.cancel("Task invalidated", DocumentCommitThread.this);
|
||||
Lock lock = getDocumentLock(document);
|
||||
if (!lock.tryLock()) {
|
||||
task.cancel("Can't obtain document lock", DocumentCommitThread.this);
|
||||
return;
|
||||
}
|
||||
|
||||
FileViewProvider viewProvider = documentManager.getCachedViewProvider(document);
|
||||
if (viewProvider == null) {
|
||||
finishProcessors.add(handleCommitWithoutPsi(documentManager, task));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (documentManager.isCommitted(document)) return;
|
||||
|
||||
for (Pair<PsiFileImpl, FileASTNode> pair : task.myOldFileNodes) {
|
||||
PsiFileImpl file = pair.first;
|
||||
if (file.isValid()) {
|
||||
FileASTNode oldFileNode = pair.second;
|
||||
Processor<Document> finishProcessor = doCommit(task, file, oldFileNode);
|
||||
if (finishProcessor != null) {
|
||||
finishProcessors.add(finishProcessor);
|
||||
if (!task.isStillValid()) {
|
||||
task.cancel("Task invalidated", DocumentCommitThread.this);
|
||||
return;
|
||||
}
|
||||
|
||||
FileViewProvider viewProvider = documentManager.getCachedViewProvider(document);
|
||||
if (viewProvider == null) {
|
||||
finishProcessors.add(handleCommitWithoutPsi(documentManager, task));
|
||||
return;
|
||||
}
|
||||
|
||||
for (Pair<PsiFileImpl, FileASTNode> pair : task.myOldFileNodes) {
|
||||
PsiFileImpl file = pair.first;
|
||||
if (file.isValid()) {
|
||||
FileASTNode oldFileNode = pair.second;
|
||||
Processor<Document> finishProcessor = doCommit(task, file, oldFileNode);
|
||||
if (finishProcessor != null) {
|
||||
finishProcessors.add(finishProcessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (synchronously) {
|
||||
@@ -742,7 +768,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
return new Processor<Document>() {
|
||||
@Override
|
||||
public boolean process(Document document) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
if (file.isPhysical()) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
}
|
||||
if (!task.isStillValid() ||
|
||||
((PsiDocumentManagerBase)PsiDocumentManager.getInstance(file.getProject())).getCachedViewProvider(document) != file.getViewProvider()) {
|
||||
return false; // optimistic locking failed
|
||||
@@ -887,4 +915,13 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an internal lock object to prevent read & write phases of commit from running simultaneously for free-threaded PSI
|
||||
*/
|
||||
private static Lock getDocumentLock(Document document) {
|
||||
Lock lock = document.getUserData(DOCUMENT_LOCK);
|
||||
return lock != null ? lock : ((UserDataHolderEx)document).putUserDataIfAbsent(DOCUMENT_LOCK, new ReentrantLock());
|
||||
}
|
||||
private static final Key<Lock> DOCUMENT_LOCK = Key.create("DOCUMENT_LOCK");
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.DocumentRunnable;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
@@ -153,6 +154,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
return ((PsiManagerEx)myPsiManager).getFileManager().findCachedViewProvider(virtualFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile getVirtualFile(@NotNull Document document) {
|
||||
final VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
|
||||
if (virtualFile == null || !virtualFile.isValid()) return null;
|
||||
@@ -261,7 +263,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
return true;
|
||||
}
|
||||
if (myUncommittedDocuments.isEmpty()) {
|
||||
if (!ApplicationManager.getApplication().hasWriteAction(CommitToPsiFileAction.class)) {
|
||||
if (!isCommitInProgress()) {
|
||||
// in case of fireWriteActionFinished() we didn't execute 'actionsWhenAllDocumentsAreCommitted' yet
|
||||
assert actionsWhenAllDocumentsAreCommitted.isEmpty() : actionsWhenAllDocumentsAreCommitted;
|
||||
}
|
||||
@@ -300,12 +302,18 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
@NotNull final Object reason) {
|
||||
assert !myProject.isDisposed() : "Already disposed";
|
||||
final boolean[] ok = {true};
|
||||
ApplicationManager.getApplication().runWriteAction(new CommitToPsiFileAction(document, myProject) {
|
||||
Runnable runnable = new DocumentRunnable(document, myProject) {
|
||||
@Override
|
||||
public void run() {
|
||||
ok[0] = finishCommitInWriteAction(document, finishProcessors, synchronously);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (synchronously) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
}
|
||||
|
||||
if (ok[0]) {
|
||||
// otherwise changes maybe not synced to the document yet, and injectors will crash
|
||||
@@ -408,7 +416,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
}
|
||||
};
|
||||
|
||||
if (Boolean.TRUE.equals(psiFile.getViewProvider().getVirtualFile().getUserData(SingleRootFileViewProvider.FREE_THREADED))) {
|
||||
if (isFreeThreaded(psiFile.getViewProvider().getVirtualFile())) {
|
||||
runnable.run();
|
||||
}
|
||||
else {
|
||||
@@ -416,6 +424,14 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFreeThreaded(@NotNull VirtualFile file) {
|
||||
return Boolean.TRUE.equals(file.getUserData(SingleRootFileViewProvider.FREE_THREADED));
|
||||
}
|
||||
|
||||
public boolean isCommitInProgress() {
|
||||
return myIsCommitInProgress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T commitAndRunReadAction(@NotNull final Computable<T> computation) {
|
||||
final Ref<T> ref = Ref.create(null);
|
||||
|
||||
@@ -209,7 +209,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
|
||||
}
|
||||
|
||||
public boolean toProcessPsiEvent() {
|
||||
return !myIgnorePsiEvents && !ApplicationManager.getApplication().hasWriteAction(IgnorePsiEventsMarker.class);
|
||||
return !myIgnorePsiEvents && !myPsiDocumentManager.isCommitInProgress() && !ApplicationManager.getApplication().hasWriteAction(IgnorePsiEventsMarker.class);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
+16
-12
@@ -18,6 +18,9 @@ package com.intellij.openapi.editor.colors.ex;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.DefaultColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.EmptyColorScheme;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -26,6 +29,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.openapi.editor.colors.impl.AbstractColorsScheme.NAME_ATTR;
|
||||
|
||||
@State(
|
||||
name = "DefaultColorSchemesManager",
|
||||
defaultStateAsResource = true,
|
||||
@@ -51,25 +56,24 @@ public class DefaultColorSchemesManager implements PersistentStateComponent<Elem
|
||||
|
||||
@Override
|
||||
public void loadState(Element state) {
|
||||
int index = 0;
|
||||
int count = mySchemes.size();
|
||||
for (Element schemeElement : state.getChildren(SCHEME_ELEMENT)) {
|
||||
if (index < count) {
|
||||
// update a scheme that is already loaded
|
||||
DefaultColorsScheme oldScheme = mySchemes.get(index++);
|
||||
oldScheme.readExternal(schemeElement);
|
||||
boolean isUpdated = false;
|
||||
Attribute nameAttr = schemeElement.getAttribute(NAME_ATTR);
|
||||
if (nameAttr != null) {
|
||||
for (DefaultColorsScheme oldScheme : mySchemes) {
|
||||
if (StringUtil.equals(nameAttr.getValue(), oldScheme.getName())) {
|
||||
oldScheme.readExternal(schemeElement);
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert index == 0 : "config file modified: scheme added";
|
||||
if (!isUpdated) {
|
||||
DefaultColorsScheme newScheme = new DefaultColorsScheme();
|
||||
newScheme.readExternal(schemeElement);
|
||||
mySchemes.add(newScheme);
|
||||
}
|
||||
}
|
||||
assert index == count : "config file modified: scheme removed";
|
||||
while (index < count--) {
|
||||
mySchemes.remove(index);
|
||||
}
|
||||
mySchemes.add(EmptyColorScheme.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+5
-5
@@ -307,7 +307,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
String isDefaultScheme = node.getAttributeValue(DEFAULT_SCHEME_ATTR);
|
||||
boolean isDefault = isDefaultScheme != null && Boolean.parseBoolean(isDefaultScheme);
|
||||
if (!isDefault) {
|
||||
myParentScheme = getDefaultScheme(node.getAttributeValue(PARENT_SCHEME_ATTR, DEFAULT_SCHEME_NAME));
|
||||
myParentScheme = getDefaultScheme(node.getAttributeValue(PARENT_SCHEME_ATTR, EmptyColorScheme.NAME));
|
||||
}
|
||||
|
||||
for (final Object o : node.getChildren()) {
|
||||
@@ -353,8 +353,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
DefaultColorSchemesManager manager = DefaultColorSchemesManager.getInstance();
|
||||
EditorColorsScheme defaultScheme = manager.getScheme(name);
|
||||
if (defaultScheme == null) {
|
||||
defaultScheme = manager.getScheme(DEFAULT_SCHEME_NAME);
|
||||
assert defaultScheme != null : "Fatal error: built-in 'Default' color scheme not found";
|
||||
defaultScheme = EmptyColorScheme.INSTANCE;
|
||||
}
|
||||
return defaultScheme;
|
||||
}
|
||||
@@ -481,11 +480,12 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExternal(Element parentNode) throws WriteExternalException {
|
||||
public void
|
||||
writeExternal(Element parentNode) throws WriteExternalException {
|
||||
parentNode.setAttribute(NAME_ATTR, getName());
|
||||
parentNode.setAttribute(VERSION_ATTR, Integer.toString(myVersion));
|
||||
|
||||
if (myParentScheme != null) {
|
||||
if (myParentScheme != null && myParentScheme != EmptyColorScheme.INSTANCE) {
|
||||
parentNode.setAttribute(PARENT_SCHEME_ATTR, myParentScheme.getName());
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -46,11 +46,16 @@ public class DefaultColorsScheme extends AbstractColorsScheme implements ReadOnl
|
||||
attrs = getFallbackAttributes(key.getFallbackAttributeKey());
|
||||
if (attrs != null && !attrs.isFallbackEnabled()) return attrs;
|
||||
}
|
||||
attrs = key.getDefaultAttributes();
|
||||
attrs = getKeyDefaults(key);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected TextAttributes getKeyDefaults(@NotNull TextAttributesKey key) {
|
||||
return key.getDefaultAttributes();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Color getColor(ColorKey key) {
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.openapi.editor.colors.impl;
|
||||
|
||||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.markup.EffectType;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* A base scheme for new schemes (not based on Default/Darcula), imported ones.
|
||||
*/
|
||||
@SuppressWarnings("UseJBColor")
|
||||
public class EmptyColorScheme extends DefaultColorsScheme {
|
||||
public final static String NAME = "Empty";
|
||||
public final static EmptyColorScheme INSTANCE = new EmptyColorScheme();
|
||||
|
||||
private final static TextAttributes EMPTY_TEXT = new TextAttributes(Color.BLACK, Color.white, null, EffectType.BOXED, Font.PLAIN);
|
||||
|
||||
private EmptyColorScheme() {
|
||||
myAttributesMap.put(HighlighterColors.TEXT, EMPTY_TEXT);
|
||||
initFonts();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TextAttributes getKeyDefaults(@NotNull TextAttributesKey key) {
|
||||
return myAttributesMap.get(HighlighterColors.TEXT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
+9
-14
@@ -110,7 +110,7 @@ public abstract class InspectionRVContentProvider {
|
||||
InspectionToolPresentation presentation = context.getPresentation(wrapper);
|
||||
Map<String, Set<RefEntity>> content = presentation.getContent();
|
||||
Map<RefEntity, CommonProblemDescriptor[]> problems = presentation.getProblemElements();
|
||||
appendToolNodeContent(context, toolNode, parentNode, showStructure, content, problems, null);
|
||||
appendToolNodeContent(context, toolNode, parentNode, showStructure, content, problems);
|
||||
}
|
||||
|
||||
public abstract void appendToolNodeContent(@NotNull GlobalInspectionContextImpl context,
|
||||
@@ -118,8 +118,7 @@ public abstract class InspectionRVContentProvider {
|
||||
@NotNull InspectionTreeNode parentNode,
|
||||
final boolean showStructure,
|
||||
@NotNull Map<String, Set<RefEntity>> contents,
|
||||
@NotNull Map<RefEntity, CommonProblemDescriptor[]> problems,
|
||||
@Nullable final DefaultTreeModel model);
|
||||
@NotNull Map<RefEntity, CommonProblemDescriptor[]> problems);
|
||||
|
||||
protected abstract void appendDescriptor(@NotNull GlobalInspectionContextImpl context,
|
||||
@NotNull InspectionToolWrapper toolWrapper,
|
||||
@@ -315,7 +314,7 @@ public abstract class InspectionRVContentProvider {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"ConstantConditions"}) //class cast suppression
|
||||
protected static void merge(@Nullable DefaultTreeModel model, InspectionTreeNode child, InspectionTreeNode parent, boolean merge) {
|
||||
protected static void merge(InspectionTreeNode child, InspectionTreeNode parent, boolean merge) {
|
||||
if (merge) {
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
InspectionTreeNode current = (InspectionTreeNode)parent.getChildAt(i);
|
||||
@@ -324,35 +323,31 @@ public abstract class InspectionRVContentProvider {
|
||||
}
|
||||
if (current instanceof InspectionPackageNode) {
|
||||
if (((InspectionPackageNode)current).getPackageName().compareTo(((InspectionPackageNode)child).getPackageName()) == 0) {
|
||||
processDepth(model, child, current);
|
||||
processDepth(child, current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (current instanceof RefElementNode) {
|
||||
if (((RefElementNode)current).getElement().getName().compareTo(((RefElementNode)child).getElement().getName()) == 0 &&
|
||||
((RefElementNode)current).getElement().getQualifiedName().compareTo(((RefElementNode)child).getElement().getQualifiedName()) == 0) {
|
||||
processDepth(model, child, current);
|
||||
processDepth(child, current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (current instanceof InspectionNode) {
|
||||
if (((InspectionNode)current).getToolWrapper().getShortName().compareTo(((InspectionNode)child).getToolWrapper().getShortName()) == 0) {
|
||||
processDepth(model, child, current);
|
||||
processDepth(child, current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (current instanceof InspectionModuleNode) {
|
||||
if (((InspectionModuleNode)current).getName().compareTo(((InspectionModuleNode)child).getName()) == 0) {
|
||||
processDepth(model, child, current);
|
||||
processDepth(child, current);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add(model, child, parent);
|
||||
}
|
||||
|
||||
protected static void add(@Nullable final DefaultTreeModel model, final InspectionTreeNode child, final InspectionTreeNode parent) {
|
||||
insertByIndex(child, parent);
|
||||
}
|
||||
|
||||
@@ -367,13 +362,13 @@ public abstract class InspectionRVContentProvider {
|
||||
parent.insert(child, -i -1);
|
||||
}
|
||||
|
||||
private static void processDepth(@Nullable DefaultTreeModel model, final InspectionTreeNode child, final InspectionTreeNode current) {
|
||||
private static void processDepth(final InspectionTreeNode child, final InspectionTreeNode current) {
|
||||
InspectionTreeNode[] children = new InspectionTreeNode[child.getChildCount()];
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
children[i] = (InspectionTreeNode)child.getChildAt(i);
|
||||
}
|
||||
for (InspectionTreeNode node : children) {
|
||||
merge(model, node, current, true);
|
||||
merge(node, current, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -93,8 +93,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider
|
||||
@NotNull final InspectionTreeNode parentNode,
|
||||
final boolean showStructure,
|
||||
@NotNull final Map<String, Set<RefEntity>> contents,
|
||||
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems,
|
||||
DefaultTreeModel model) {
|
||||
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems) {
|
||||
final InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
|
||||
|
||||
Function<RefEntity, UserObjectContainer<RefEntity>> computeContainer = new Function<RefEntity, UserObjectContainer<RefEntity>>() {
|
||||
@@ -114,7 +113,7 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider
|
||||
entities.addAll(moduleProblems);
|
||||
}
|
||||
buildTree(context, contents, false, toolWrapper, computeContainer, showStructure, node -> {
|
||||
merge(model, node, toolNode, true);
|
||||
merge(node, toolNode, true);
|
||||
});
|
||||
|
||||
if (presentation.isOldProblemsIncluded()) {
|
||||
@@ -127,10 +126,10 @@ public class InspectionRVContentProviderImpl extends InspectionRVContentProvider
|
||||
};
|
||||
|
||||
buildTree(context, presentation.getOldContent(), true, toolWrapper, computeContainer, showStructure, node -> {
|
||||
merge(model, node, toolNode, true);
|
||||
merge(node, toolNode, true);
|
||||
});
|
||||
}
|
||||
merge(model, toolNode, parentNode, false);
|
||||
merge(toolNode, parentNode, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-2
@@ -113,8 +113,7 @@ public class OfflineInspectionRVContentProvider extends InspectionRVContentProvi
|
||||
@NotNull final InspectionTreeNode parentNode,
|
||||
final boolean showStructure,
|
||||
@NotNull final Map<String, Set<RefEntity>> contents,
|
||||
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems,
|
||||
final DefaultTreeModel model) {
|
||||
@NotNull final Map<RefEntity, CommonProblemDescriptor[]> problems) {
|
||||
InspectionToolWrapper toolWrapper = toolNode.getToolWrapper();
|
||||
final Map<String, Set<OfflineProblemDescriptor>> filteredContent = getFilteredContent(context, toolWrapper);
|
||||
if (filteredContent != null && !filteredContent.values().isEmpty()) {
|
||||
|
||||
+2
-3
@@ -52,7 +52,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -262,8 +261,8 @@ public class DefaultInspectionToolPresentation implements ProblemDescriptionsPro
|
||||
content.add(refElement);
|
||||
|
||||
view.getProvider().appendToolNodeContent(context, toolNode,
|
||||
(InspectionTreeNode)toolNode.getParent(), context.getUIOptions().SHOW_STRUCTURE,
|
||||
contents, problems, (DefaultTreeModel)view.getTree().getModel());
|
||||
(InspectionTreeNode)toolNode.getParent(), context.getUIOptions().SHOW_STRUCTURE,
|
||||
contents, problems);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+5
-17
@@ -19,8 +19,7 @@ import com.intellij.ProjectTopics;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -126,26 +125,15 @@ public class ModuleManagerComponent extends ModuleManagerImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable runnableWithProgress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final Module module : myModuleModel.myModules.values()) {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
final Runnable swingRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fireModuleAddedInWriteAction(module);
|
||||
}
|
||||
};
|
||||
ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();
|
||||
app.invokeAndWait(swingRunnable, pi.getModalityState());
|
||||
}
|
||||
Runnable runnableWithProgress = () -> {
|
||||
for (final Module module : myModuleModel.myModules.values()) {
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, () -> fireModuleAddedInWriteAction(module));
|
||||
}
|
||||
};
|
||||
|
||||
ProgressIndicator progressIndicator = myProgressManager.getProgressIndicator();
|
||||
if (progressIndicator == null) {
|
||||
myProgressManager.runProcessWithProgressSynchronously(runnableWithProgress, "Initializing modules...", false, myProject);
|
||||
myProgressManager.runProcessWithProgressSynchronously(runnableWithProgress, "Initializing Modules...", false, myProject);
|
||||
}
|
||||
else {
|
||||
runnableWithProgress.run();
|
||||
|
||||
+11
-14
@@ -22,6 +22,7 @@ package com.intellij.openapi.roots.impl;
|
||||
import com.intellij.ProjectTopics;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.ExtensionException;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
@@ -49,7 +50,6 @@ import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.util.indexing.FileBasedIndexProjectHandler;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -408,20 +408,17 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
|
||||
private static void reloadPsi(final VirtualFile file, final Project project) {
|
||||
final FileManagerImpl fileManager = (FileManagerImpl)((PsiManagerEx)PsiManager.getInstance(project)).getFileManager();
|
||||
if (fileManager.findCachedViewProvider(file) != null) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (project.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fileManager.forceReload(file);
|
||||
}
|
||||
});
|
||||
Runnable runnable = () -> {
|
||||
if (project.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
ApplicationManager.getApplication().runWriteAction(() -> fileManager.forceReload(file));
|
||||
};
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
TransactionGuard.submitTransaction(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,9 @@ public class PsiDocumentManagerImpl extends PsiDocumentManagerBase implements Se
|
||||
protected boolean finishCommitInWriteAction(@NotNull Document document,
|
||||
@NotNull List<Processor<Document>> finishProcessors,
|
||||
boolean synchronously) {
|
||||
EditorWindowImpl.disposeInvalidEditors(); // in write action
|
||||
if (ApplicationManager.getApplication().isWriteAccessAllowed()) { // can be false for non-physical PSI
|
||||
EditorWindowImpl.disposeInvalidEditors();
|
||||
}
|
||||
return super.finishCommitInWriteAction(document, finishProcessors, synchronously);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
@@ -80,15 +81,10 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
public void run() {
|
||||
PushedFilePropertiesUpdater.getInstance(project).initializeProperties();
|
||||
|
||||
// dumb mode should start before post-startup activities
|
||||
// only when queueTask is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!project.isDisposed() && FileBasedIndex.getInstance() instanceof FileBasedIndexImpl) {
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, true));
|
||||
}
|
||||
// schedule dumb mode start after the read action we're currently in
|
||||
TransactionGuard.submitTransaction(() -> {
|
||||
if (!project.isDisposed() && FileBasedIndex.getInstance() instanceof FileBasedIndexImpl) {
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, true));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -19,20 +19,15 @@ package com.intellij.util.ui;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public abstract class Animator implements Disposable {
|
||||
// allow only one animation run at a time
|
||||
private final ScheduledExecutorService scheduler = AppExecutorUtil.createBoundedScheduledExecutorService(1);
|
||||
|
||||
private final String myName;
|
||||
private final int myTotalFrames;
|
||||
private final int myCycleDuration;
|
||||
@@ -147,20 +142,10 @@ public abstract class Animator implements Disposable {
|
||||
animationDone();
|
||||
}
|
||||
else if (myTicker == null) {
|
||||
myTicker = scheduler.scheduleWithFixedDelay(new Runnable() {
|
||||
private final AtomicBoolean scheduled = new AtomicBoolean(false);
|
||||
|
||||
myTicker = EdtExecutorService.getScheduledExecutorInstance().scheduleWithFixedDelay(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (scheduled.compareAndSet(false, true) && !isDisposed()) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scheduled.set(false);
|
||||
onTick();
|
||||
}
|
||||
});
|
||||
}
|
||||
onTick();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,8 +168,8 @@ public abstract class Animator implements Disposable {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myDisposed = true;
|
||||
stopTicker();
|
||||
myDisposed = true;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package com.intellij.internal;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.WrapInTransaction;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.DumbModeTask;
|
||||
import com.intellij.openapi.project.DumbServiceImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -30,7 +30,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class ToggleDumbModeAction extends AnAction implements DumbAware {
|
||||
@WrapInTransaction
|
||||
public class ToggleDumbModeAction extends DumbAwareAction {
|
||||
private volatile boolean myDumb = false;
|
||||
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
|
||||
+8
-8
@@ -308,12 +308,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
}
|
||||
}
|
||||
runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Disposer.dispose(ApplicationImpl.this);
|
||||
}
|
||||
});
|
||||
TransactionGuard.syncTransaction(TransactionKind.ANY_CHANGE, () -> runWriteAction(() -> Disposer.dispose(this)));
|
||||
|
||||
Disposer.assertIsEmpty();
|
||||
return true;
|
||||
@@ -376,6 +371,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
@Override
|
||||
public Future<?> executeOnPooledThread(@NotNull final Runnable action) {
|
||||
return ourThreadExecutorsService.submit(new Runnable() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return action.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
assert !isReadAccessAllowed(): describe(Thread.currentThread());
|
||||
@@ -864,7 +864,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
private boolean doExit(boolean allowListenersToCancel, boolean restart) {
|
||||
saveSettings();
|
||||
TransactionGuard.syncTransaction(TransactionKind.ANY_CHANGE, this::saveSettings);
|
||||
|
||||
if (allowListenersToCancel && !canExit()) {
|
||||
return false;
|
||||
@@ -1230,8 +1230,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
assertIsDispatchThread(getStatus(), "Write access is allowed from event dispatch thread only");
|
||||
HeavyProcessLatch.INSTANCE.stopThreadPrioritizing(); // let non-cancellable read actions complete faster, if present
|
||||
if (!TransactionGuard.getInstance().isInsideTransaction() && Registry.is("ide.require.transaction.for.model.changes", false)) {
|
||||
// please assign exceptions that occur here to Peter
|
||||
LOG.error("Write access is allowed from model transactions only, see TransactionGuard documentation for details");
|
||||
//todo throw new IllegalStateException("Write access is allowed from model transactions only, see TransactionGuard documentation for details");
|
||||
}
|
||||
boolean writeActionPending = myWriteActionPending;
|
||||
myWriteActionPending = true;
|
||||
|
||||
+12
-5
@@ -51,9 +51,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
@State(
|
||||
name = "EditorColorsManagerImpl",
|
||||
@@ -233,8 +231,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
@NotNull
|
||||
@Override
|
||||
public EditorColorsScheme[] getAllSchemes() {
|
||||
List<EditorColorsScheme> schemes = mySchemeManager.getAllSchemes();
|
||||
EditorColorsScheme[] result = schemes.toArray(new EditorColorsScheme[schemes.size()]);
|
||||
EditorColorsScheme[] result = getAllVisibleSchemes(mySchemeManager.getAllSchemes());
|
||||
Arrays.sort(result, new Comparator<EditorColorsScheme>() {
|
||||
@Override
|
||||
public int compare(@NotNull EditorColorsScheme s1, @NotNull EditorColorsScheme s2) {
|
||||
@@ -248,6 +245,16 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
return result;
|
||||
}
|
||||
|
||||
private static EditorColorsScheme[] getAllVisibleSchemes(@NotNull Collection<EditorColorsScheme> schemes) {
|
||||
List<EditorColorsScheme> visibleSchemes = new ArrayList<>(schemes.size() - 1);
|
||||
for (EditorColorsScheme scheme : schemes) {
|
||||
if (!(scheme instanceof EmptyColorScheme)) {
|
||||
visibleSchemes.add(scheme);
|
||||
}
|
||||
}
|
||||
return visibleSchemes.toArray(new EditorColorsScheme[visibleSchemes.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlobalScheme(@Nullable EditorColorsScheme scheme) {
|
||||
mySchemeManager.setCurrent(scheme == null ? getDefaultScheme() : scheme);
|
||||
|
||||
+7
-13
@@ -31,6 +31,7 @@ import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.dnd.*;
|
||||
import com.intellij.ide.ui.customization.CustomActionsSchema;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -1570,13 +1571,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
: renderer.getClickAction();
|
||||
}
|
||||
if (clickAction != null) {
|
||||
if (checkDumbAware(clickAction)) {
|
||||
performAction(clickAction, e, "ICON_NAVIGATION", myEditor.getDataContext());
|
||||
repaint();
|
||||
}
|
||||
else {
|
||||
notifyNotDumbAware();
|
||||
}
|
||||
performAction(clickAction, e, "ICON_NAVIGATION", myEditor.getDataContext());
|
||||
repaint();
|
||||
e.consume();
|
||||
}
|
||||
else {
|
||||
@@ -1608,7 +1604,9 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
private static void performAction(@NotNull AnAction action, @NotNull InputEvent e, @NotNull String place, @NotNull DataContext context) {
|
||||
AnActionEvent actionEvent = AnActionEvent.createFromAnAction(action, e, place, context);
|
||||
action.update(actionEvent);
|
||||
if (actionEvent.getPresentation().isEnabledAndVisible()) action.actionPerformed(actionEvent);
|
||||
if (actionEvent.getPresentation().isEnabledAndVisible()) {
|
||||
ActionUtil.performActionDumbAware(action, actionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1778,11 +1776,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
|
||||
else {
|
||||
AnAction rightButtonAction = renderer.getRightButtonClickAction();
|
||||
if (rightButtonAction != null) {
|
||||
if (checkDumbAware(rightButtonAction)) {
|
||||
performAction(rightButtonAction, e, "ICON_NAVIGATION_SECONDARY_BUTTON", myEditor.getDataContext());
|
||||
} else {
|
||||
notifyNotDumbAware();
|
||||
}
|
||||
performAction(rightButtonAction, e, "ICON_NAVIGATION_SECONDARY_BUTTON", myEditor.getDataContext());
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.hint.DocumentFragmentTooltipRenderer;
|
||||
import com.intellij.codeInsight.hint.EditorFragmentComponent;
|
||||
import com.intellij.codeInsight.hint.TooltipController;
|
||||
import com.intellij.codeInsight.hint.TooltipGroup;
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.diagnostic.Dumpable;
|
||||
import com.intellij.diagnostic.LogMessageEx;
|
||||
import com.intellij.ide.*;
|
||||
@@ -31,8 +30,7 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
|
||||
import com.intellij.openapi.actionSystem.impl.MouseGestureManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -75,6 +73,7 @@ import com.intellij.ui.components.JBLayeredPane;
|
||||
import com.intellij.ui.components.JBScrollBar;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
@@ -990,8 +989,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (event.isConsumed()) {
|
||||
return;
|
||||
}
|
||||
if (processKeyTyped(event)) {
|
||||
event.consume();
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.TEXT_EDITING)) {
|
||||
if (processKeyTyped(event)) {
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4685,7 +4686,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (mySchedulerHandle != null) {
|
||||
mySchedulerHandle.cancel(false);
|
||||
}
|
||||
mySchedulerHandle = JobScheduler.getScheduler().scheduleWithFixedDelay(this, mySleepTime, mySleepTime, TimeUnit.MILLISECONDS);
|
||||
mySchedulerHandle = EdtExecutorService.getScheduledExecutorInstance().scheduleWithFixedDelay(this, mySleepTime, mySleepTime, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void setBlinkPeriod(int blinkPeriod) {
|
||||
@@ -4716,7 +4717,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
if (toRepaint) {
|
||||
SwingUtilities.invokeLater(myRepaintRunnable);
|
||||
activeCursor.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ public class ActionsTreeUtil {
|
||||
final Shortcut[] actionShortcuts =
|
||||
keymap.getShortcuts(action instanceof ActionStub ? ((ActionStub)action).getId() : actionManager.getId(action));
|
||||
for (Shortcut actionShortcut : actionShortcuts) {
|
||||
if (shortcut.equals(actionShortcut)) {
|
||||
if (actionShortcut != null && actionShortcut.startsWith(shortcut)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,7 @@ package com.intellij.openapi.project;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
|
||||
@@ -188,7 +185,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
return;
|
||||
}
|
||||
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) {
|
||||
@@ -251,7 +248,13 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
}, ModalityState.any(), myProject.getDisposed());
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
if (application.isDispatchThread()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(() -> TransactionGuard.submitTransaction(runnable));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -530,16 +533,25 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
|
||||
private static void invokeAndWaitIfNeeded(Runnable runnable) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(runnable);
|
||||
}
|
||||
catch (InterruptedException ignore) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
//todo remove invokeLater when transactions are executed in "any" modality state
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(
|
||||
() -> TransactionGuard.getInstance().submitMergeableTransaction(TransactionKind.ANY_CHANGE, () -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
semaphore.up();
|
||||
}
|
||||
}));
|
||||
try {
|
||||
semaphore.waitFor();
|
||||
}
|
||||
catch (ProcessCanceledException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-20
@@ -28,10 +28,7 @@ import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
@@ -351,9 +348,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
}
|
||||
|
||||
fireProjectOpened(project);
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.ANY_CHANGE)) {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, () ->
|
||||
DumbService.getInstance(project).queueTask(new DumbModeTask() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
@@ -364,9 +360,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
public String toString() {
|
||||
return "wait for file watcher";
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(project);
|
||||
boolean ok = myProgressManager.runProcessWithProgressSynchronously(new Runnable() {
|
||||
@@ -374,15 +370,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
public void run() {
|
||||
startupManager.runStartupActivities();
|
||||
|
||||
// dumb mode should start before post-startup activities
|
||||
// only when startCacheUpdate is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startupManager.startCacheUpdate();
|
||||
}
|
||||
});
|
||||
// Startup activities (e.g. the one in FileBasedIndexProjectHandler) have scheduled dumb mode to begin "later"
|
||||
// Now we schedule-and-wait to the same event queue to guarantee that the dumb mode really begins now:
|
||||
// Post-startup activities should not ever see unindexed and at the same time non-dumb state
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, startupManager::startCacheUpdate);
|
||||
|
||||
startupManager.runPostStartupActivitiesFromExtensions();
|
||||
|
||||
@@ -615,7 +606,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
if (checkCanClose && !canClose(project)) return false;
|
||||
final ShutDownTracker shutDownTracker = ShutDownTracker.getInstance();
|
||||
shutDownTracker.registerStopperThread(Thread.currentThread());
|
||||
try {
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.ANY_CHANGE)) {
|
||||
if (save) {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
project.save();
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.ui.FocusTrackback;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
import com.intellij.util.containers.WeakValueHashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
@@ -56,6 +57,7 @@ import java.lang.ref.WeakReference;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
private static final Logger LOG = Logger.getInstance(FocusManagerImpl.class);
|
||||
@@ -85,8 +87,6 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
private final EdtAlarm myFocusedComponentAlarm;
|
||||
private final EdtAlarm myForcedFocusRequestsAlarm;
|
||||
|
||||
private final SimpleTimer myTimer = SimpleTimer.newInstance("FocusManager timer");
|
||||
|
||||
private final EdtAlarm myIdleAlarm;
|
||||
private final Set<Runnable> myIdleRequests = new LinkedHashSet<Runnable>();
|
||||
|
||||
@@ -1040,7 +1040,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
}
|
||||
|
||||
|
||||
class EdtAlarm {
|
||||
static class EdtAlarm {
|
||||
private final Set<EdtRunnable> myRequests = new HashSet<EdtRunnable>();
|
||||
|
||||
public void cancelAllRequests() {
|
||||
@@ -1052,7 +1052,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
public void addRequest(@NotNull EdtRunnable runnable, int delay) {
|
||||
myRequests.add(runnable);
|
||||
myTimer.setUp(runnable, delay);
|
||||
EdtExecutorService.getScheduledExecutorInstance().schedule(runnable, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.wm.impl.status;
|
||||
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -71,12 +70,7 @@ public class ClockPanel extends JComponent {
|
||||
myScheduledFuture.cancel(false);
|
||||
}
|
||||
myCalendar.setTimeInMillis(System.currentTimeMillis());
|
||||
myScheduledFuture = JobScheduler.getScheduler().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
UIUtil.invokeLaterIfNeeded(myRepaintRunnable);
|
||||
}
|
||||
}, 60 - myCalendar.get(SECOND), TimeUnit.SECONDS);
|
||||
myScheduledFuture = EdtExecutorService.getScheduledExecutorInstance().schedule(myRepaintRunnable, 60 - myCalendar.get(SECOND), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-14
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.openapi.wm.impl.status;
|
||||
|
||||
import com.intellij.concurrency.JobScheduler;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.wm.CustomStatusBarWidget;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
@@ -23,6 +22,7 @@ import com.intellij.openapi.wm.StatusBarWidget;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.UIBundle;
|
||||
import com.intellij.util.concurrency.EdtExecutorService;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.update.Activatable;
|
||||
@@ -75,13 +75,8 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
|
||||
|
||||
@Override
|
||||
public void showNotify() {
|
||||
myFuture = JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() {
|
||||
public void run() {
|
||||
if (isDisplayable()) {
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
}, 1, 5, TimeUnit.SECONDS);
|
||||
myFuture = EdtExecutorService.getScheduledExecutorInstance().scheduleWithFixedDelay(MemoryUsagePanel.this::updateState,
|
||||
1, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,12 +226,9 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
|
||||
if (total != myLastTotal || used != myLastUsed) {
|
||||
myLastTotal = total;
|
||||
myLastUsed = used;
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myBufferedImage = null;
|
||||
repaint();
|
||||
}
|
||||
UIUtil.invokeLaterIfNeeded(() -> {
|
||||
myBufferedImage = null;
|
||||
repaint();
|
||||
});
|
||||
|
||||
setToolTipText(UIBundle.message("memory.usage.panel.statistics.message", total, used));
|
||||
|
||||
@@ -660,4 +660,43 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
|
||||
System.out.println("i = " + i);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCommitNonPhysicalPsiWithoutWriteAction() throws IOException {
|
||||
assertFalse(ApplicationManager.getApplication().isWriteAccessAllowed());
|
||||
|
||||
PsiFile original = getPsiManager().findFile(getVirtualFile(createTempFile("X.txt", "")));
|
||||
assertNotNull(original);
|
||||
assertTrue(original.getViewProvider().isEventSystemEnabled());
|
||||
|
||||
long modCount = getPsiManager().getModificationTracker().getModificationCount();
|
||||
|
||||
PsiFile copy = (PsiFile)original.copy();
|
||||
assertFalse(copy.getViewProvider().isEventSystemEnabled());
|
||||
|
||||
Document document = copy.getViewProvider().getDocument();
|
||||
assertNotNull(document);
|
||||
document.setText("class A{}");
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(document);
|
||||
assertEquals(modCount, getPsiManager().getModificationTracker().getModificationCount());
|
||||
assertEquals(document.getText(), copy.getText());
|
||||
assertTrue(PsiDocumentManager.getInstance(myProject).isCommitted(document));
|
||||
}
|
||||
|
||||
public void testCommitNonPhysicalCopyOnPerformWhenAllCommitted() throws Exception {
|
||||
assertFalse(ApplicationManager.getApplication().isWriteAccessAllowed());
|
||||
|
||||
PsiFile original = getPsiManager().findFile(getVirtualFile(createTempFile("X.txt", "")));
|
||||
assertNotNull(original);
|
||||
PsiFile copy = (PsiFile)original.copy();
|
||||
assertEquals("", copy.getText());
|
||||
Document document = copy.getViewProvider().getDocument();
|
||||
assertNotNull(document);
|
||||
|
||||
document.setText("class A{}");
|
||||
PsiDocumentManager.getInstance(myProject).performWhenAllCommitted(() -> assertEquals(document.getText(), copy.getText()));
|
||||
DocumentCommitThread.getInstance().waitForAllCommits();
|
||||
assertTrue(PsiDocumentManager.getInstance(myProject).isCommitted(document));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-20
@@ -26,7 +26,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.ZipperUpdater;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.FileStatusManager;
|
||||
@@ -34,6 +33,7 @@ import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.EditorNotifications;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
@@ -79,26 +79,18 @@ public class ChangelistConflictTracker {
|
||||
myCheckSet = new HashSet<VirtualFile>();
|
||||
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
final ZipperUpdater zipperUpdater = new ZipperUpdater(300, myProject);
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (application.runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return application.isDisposed() || myProject.isDisposed() || !myProject.isOpen();
|
||||
}
|
||||
})) {
|
||||
return;
|
||||
}
|
||||
final Set<VirtualFile> localSet;
|
||||
synchronized (myCheckSetLock) {
|
||||
localSet = new HashSet<VirtualFile>();
|
||||
localSet.addAll(myCheckSet);
|
||||
myCheckSet.clear();
|
||||
}
|
||||
checkFiles(localSet);
|
||||
final ZipperUpdater zipperUpdater = new ZipperUpdater(300, Alarm.ThreadToUse.SWING_THREAD, myProject);
|
||||
final Runnable runnable = () -> {
|
||||
if (application.isDisposed() || myProject.isDisposed() || !myProject.isOpen()) {
|
||||
return;
|
||||
}
|
||||
final Set<VirtualFile> localSet;
|
||||
synchronized (myCheckSetLock) {
|
||||
localSet = new HashSet<VirtualFile>();
|
||||
localSet.addAll(myCheckSet);
|
||||
myCheckSet.clear();
|
||||
}
|
||||
checkFiles(localSet);
|
||||
};
|
||||
myDocumentListener = new DocumentAdapter() {
|
||||
@Override
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<foo xmlns="myns1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="myns1 ./8.xsd"
|
||||
visibility="<caret>" />
|
||||
Reference in New Issue
Block a user