Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir.Orlov
2016-03-10 17:19:03 +03:00
37 changed files with 375 additions and 317 deletions
@@ -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
@@ -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
@@ -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());
}
@@ -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) {
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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
@@ -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()) {
@@ -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);
}
}
@@ -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();
@@ -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) {
@@ -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;
@@ -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);
@@ -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) {
}
}
@@ -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
@@ -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));
}
}
@@ -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
-3
View File
@@ -1,3 +0,0 @@
<foo xmlns="myns1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="myns1 ./8.xsd"
visibility="<caret>" />