vcs: do not access DataContext from pooled thread

This commit is contained in:
Aleksey Pivovarov
2016-11-30 15:11:59 +03:00
committed by Aleksey Pivovarov
parent 323b3eef00
commit b744932138
4 changed files with 50 additions and 36 deletions
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeList;
@@ -31,6 +30,8 @@ import com.intellij.psi.PsiFile;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Dmitry Avdeev
*/
@@ -40,21 +41,17 @@ public class CommitCompletionContributor extends CompletionContributor {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document == null) {
return;
}
DataContext dataContext = document.getUserData(CommitMessage.DATA_CONTEXT_KEY);
if (dataContext == null) {
return;
}
if (document == null) return;
CommitMessage commitMessage = document.getUserData(CommitMessage.DATA_KEY);
if (commitMessage == null) return;
result.stopHere();
if (parameters.getInvocationCount() <= 0) {
return;
}
ChangeList[] lists = VcsDataKeys.CHANGE_LISTS.getData(dataContext);
if (lists == null) {
return;
}
if (parameters.getInvocationCount() <= 0) return;
List<ChangeList> lists = commitMessage.getChangeLists();
if (lists.isEmpty()) return;
String prefix = TextFieldWithAutoCompletionListProvider.getCompletionPrefix(parameters);
CompletionResultSet insensitive = result.caseInsensitive().withPrefixMatcher(new CamelHumpMatcher(prefix));
for (ChangeList list : lists) {
@@ -66,6 +66,8 @@ import java.io.File;
import java.util.*;
import java.util.List;
import static com.intellij.util.containers.ContainerUtil.createMaybeSingletonList;
public class CommitChangeListDialog extends DialogWrapper implements CheckinProjectPanel, TypeSafeDataProvider {
private static final String HELP_ID = "reference.dialogs.vcs.commit";
private static final String TITLE = VcsBundle.message("commit.dialog.title");
@@ -267,12 +269,16 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
myAllOfDefaultChangeListChangesIncluded =
ContainerUtil.newHashSet(changes).containsAll(ContainerUtil.newHashSet(defaultChangeList.getChanges()));
myCommitMessageArea = new CommitMessage(project);
myIsAlien = isAlien;
if (isAlien) {
myCommitMessageArea.setChangeLists(ContainerUtil.newArrayList(changeLists));
myBrowser = new AlienChangeListBrowser(project, changeLists, changes, initialSelection, true, true, singleVcs);
} else {
//noinspection unchecked
myCommitMessageArea.setChangeLists(createMaybeSingletonList(initialSelection));
boolean unversionedFilesEnabled = myShowVcsCommit && Registry.is("vcs.unversioned.files.in.commit");
//noinspection unchecked
MultipleChangeListBrowser browser = new MultipleChangeListBrowser(project, changeLists, (List)changes, initialSelection, true, true,
new Runnable() {
@Override
@@ -291,6 +297,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
browser.addSelectedListChangeListener(new SelectedListChangeListener() {
@Override
public void selectedListChanged() {
myCommitMessageArea.setChangeLists(createMaybeSingletonList(browser.getSelectedChangeList()));
updateOnListSelection();
}
});
@@ -308,8 +315,6 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
});
}
});
myCommitMessageArea = new CommitMessage(project);
myBrowser.setDiffBottomComponent(new DiffCommitMessageEditor(myProject, myCommitMessageArea));
mySplitter = new Splitter(true);
@@ -1209,8 +1214,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj
private static class DiffCommitMessageEditor extends CommitMessage implements Disposable {
public DiffCommitMessageEditor(@NotNull Project project, @NotNull CommitMessage commitMessage) {
super(project);
getEditorField().setDocument(commitMessage.getEditorField().getDocument());
super(project, commitMessage);
}
@Override
@@ -15,9 +15,9 @@
*/
package com.intellij.openapi.vcs.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.SpellCheckingEditorCustomizationProvider;
import com.intellij.openapi.fileTypes.FileTypes;
@@ -28,33 +28,39 @@ import com.intellij.openapi.vcs.CommitMessageI;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.VcsDataKeys;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.ui.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.*;
import javax.swing.*;
import java.awt.*;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CommitMessage extends JPanel implements Disposable, DataProvider, CommitMessageI {
public static final Key<DataContext> DATA_CONTEXT_KEY = Key.create("commit message data context");
public static final Key<CommitMessage> DATA_KEY = Key.create("commit message data context");
private final EditorTextField myEditorField;
private final TitledSeparator mySeparator;
@NotNull private List<ChangeList> myChangeLists = Collections.emptyList(); // guarded with WriteLock
public CommitMessage(@NotNull Project project) {
this(project, true);
}
public CommitMessage(@NotNull Project project, @NotNull CommitMessage commitMessage) {
this(project);
myEditorField.setDocument(commitMessage.getEditorField().getDocument());
}
public CommitMessage(@NotNull Project project, final boolean withSeparator) {
super(new BorderLayout());
myEditorField = createEditorField(project);
// Note that we assume here that editor used for commit message processing uses font family implied by LAF (in contrast,
// IJ code editor uses monospaced font). Hence, we don't need any special actions here
// (myEditorField.setFontInheritedFromLAF(true) should be used instead).
myEditorField = createCommitTextEditor(project, false);
myEditorField.getDocument().putUserData(DATA_KEY, this);
add(myEditorField, BorderLayout.CENTER);
@@ -103,12 +109,6 @@ public class CommitMessage extends JPanel implements Disposable, DataProvider, C
setText(currentDescription);
}
private static EditorTextField createEditorField(final Project project) {
EditorTextField editorField = createCommitTextEditor(project, false);
editorField.getDocument().putUserData(DATA_CONTEXT_KEY, DataManager.getInstance().getDataContext(editorField.getComponent()));
return editorField;
}
/**
* Creates a text editor appropriate for creating commit messages.
*
@@ -168,4 +168,17 @@ public class CommitMessage extends JPanel implements Disposable, DataProvider, C
@Override
public void dispose() {
}
@CalledInAwt
public void setChangeLists(@NotNull List<ChangeList> value) {
WriteAction.run(() -> {
myChangeLists = value;
});
}
@NotNull
@CalledWithReadLock
public List<ChangeList> getChangeLists() {
return myChangeLists;
}
}
@@ -90,7 +90,7 @@ public class TaskCompletionTest extends LightCodeInsightFixtureTestCase {
TextFieldWithAutoCompletion.installCompletion(document, project,
new TaskAutoCompletionListProvider(project),
false);
document.putUserData(CommitMessage.DATA_CONTEXT_KEY, new MapDataContext());
document.putUserData(CommitMessage.DATA_KEY, new CommitMessage(project));
}
private TestRepository configureRepository(LocalTaskImpl... tasks) {