diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index ceeef8a6c781..d2ae0f0f4fe4 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -995,11 +995,6 @@ public class BuildManager implements ApplicationComponent{
cmdLine.addParameter("-Djava.net.preferIPv4Stack=true");
}
- final String isFSCaseSensitive = System.getProperty("idea.case.sensitive.fs", null);
- if (isFSCaseSensitive != null) {
- cmdLine.addParameter("-Didea.case.sensitive.fs=" + isFSCaseSensitive);
- }
-
// this will make netty initialization faster on some systems
cmdLine.addParameter("-Dio.netty.initialSeedUniquifier=" + ThreadLocalRandom.getInitialSeedUniquifier());
@@ -1035,7 +1030,8 @@ public class BuildManager implements ApplicationComponent{
cmdLine.setCharset(mySystemCharset);
cmdLine.addParameter("-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + mySystemCharset.name());
cmdLine.addParameter("-D" + JpsGlobalLoader.FILE_TYPES_COMPONENT_NAME_KEY + "=" + FileTypeManagerImpl.getFileTypeComponentName());
- for (String name : new String[]{"user.language", "user.country", "user.region", PathManager.PROPERTY_PATHS_SELECTOR}) {
+ String[] propertiesToPass = {"user.language", "user.country", "user.region", PathManager.PROPERTY_PATHS_SELECTOR, "idea.case.sensitive.fs"};
+ for (String name : propertiesToPass) {
final String value = System.getProperty(name);
if (value != null) {
cmdLine.addParameter("-D" + name + "=" + value);
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java
index 1be1fb56557d..a344abf98881 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java
@@ -93,12 +93,14 @@ public abstract class JavaLineBreakpointTypeBase
> result = Ref.create();
XDebuggerUtil.getInstance().iterateLine(project, document, line, new Processor() {
@Override
public boolean process(PsiElement element) {
// avoid comments
- if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
+ if ((element instanceof PsiWhiteSpace)
+ || (PsiTreeUtil.getParentOfType(element, PsiComment.class, PsiImportStatementBase.class, PsiPackageStatement.class) != null)) {
return true;
}
PsiElement parent = element;
diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
index 2a8f8d0eb960..8e46b571bdc3 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SmartPointerManagerImpl.java
@@ -237,14 +237,20 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
}
PsiFile containingFile = pointer.getContainingFile();
if (containingFile == null) return false;
- Set pointers = getPointers(containingFile.getViewProvider().getVirtualFile());
+
+ VirtualFile vFile = containingFile.getViewProvider().getVirtualFile();
+ Set pointers = getPointers(vFile);
if (pointers == null) return false;
+
SmartPointerElementInfo info = ((SmartPsiElementPointerImpl)pointer).getElementInfo();
info.cleanup();
for (Iterator iterator = pointers.iterator(); iterator.hasNext(); ) {
if (pointer == iterator.next().get()) {
iterator.remove();
+ if (pointers.isEmpty()) {
+ vFile.putUserData(POINTERS_KEY, null);
+ }
return true;
}
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java b/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java
index cae58b89dddd..1ce7dd9a66a3 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/daemon/MergeableLineMarkerInfo.java
@@ -62,7 +62,7 @@ public abstract class MergeableLineMarkerInfo extends Line
}
public int getCommonUpdatePass(@NotNull List infos) {
- return 4; //TODO move Pass to lang-api and make it enum
+ return updatePass;
}
public boolean configurePopupAndRenderer(@NotNull PopupChooserBuilder builder,
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
index 758ee72f46c8..6eb3c9f3bcaa 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
@@ -79,6 +79,7 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -132,7 +133,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
ContainerUtil.newConcurrentMap(ContainerUtil.identityStrategy());
private final PropertyChangeListener myLookupManagerListener;
private final Queue myAdvertiserChanges = new ConcurrentLinkedQueue();
- private final List myDelayedMiddleMatches = ContainerUtil.createEmptyCOWList();
+ private final List myDelayedMiddleMatches = ContainerUtil.newArrayList();
private final int myStartCaret;
public CompletionProgressIndicator(final Editor editor,
@@ -399,7 +400,9 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (item.isStartMatch() || allowMiddleMatches) {
addItemToLookup(item);
} else {
- myDelayedMiddleMatches.add(item);
+ synchronized (myDelayedMiddleMatches) {
+ myDelayedMiddleMatches.add(item);
+ }
}
}
@@ -421,11 +424,16 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
}
void addDelayedMiddleMatches() {
- for (CompletionResult item : myDelayedMiddleMatches) {
+ ArrayList delayed;
+ synchronized (myDelayedMiddleMatches) {
+ if (myDelayedMiddleMatches.isEmpty()) return;
+ delayed = ContainerUtil.newArrayList(myDelayedMiddleMatches);
+ myDelayedMiddleMatches.clear();
+ }
+ for (CompletionResult item : delayed) {
ProgressManager.checkCanceled();
addItemToLookup(item);
}
- myDelayedMiddleMatches.clear();
}
public void closeAndFinish(boolean hideLookup) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
index d59f6188fe40..040a4522f5d1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
@@ -55,21 +55,26 @@ public class LiftShorterItemsClassifier extends Classifier {
myCount++;
final Set strings = added.getAllLookupStrings();
- for (String string : strings) {
- if (string.length() == 0) continue;
-
- myElements.putValue(string, added);
- mySortedStrings.add(string);
- final NavigableSet after = mySortedStrings.tailSet(string, false);
- for (String s : after) {
- if (!s.startsWith(string)) {
- break;
- }
- for (LookupElement longer : myElements.get(s)) {
- updateLongerItem(added, longer);
+ try {
+ for (String string : strings) {
+ if (string.length() == 0) continue;
+
+ myElements.putValue(string, added);
+ mySortedStrings.add(string);
+ final NavigableSet after = mySortedStrings.tailSet(string, false);
+ for (String s : after) {
+ if (!s.startsWith(string)) {
+ break;
+ }
+ for (LookupElement longer : myElements.get(s)) {
+ updateLongerItem(added, longer);
+ }
}
}
}
+ catch (ConcurrentModificationException e) {
+ throw new RuntimeException("Error while traversing lookup strings of " + added + " of " + added.getClass(), e);
+ }
myNext.addElement(added, context);
calculateToLift(added);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandlerBase.java
index 913552134ae5..bd1b4c45aba8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/ExtendWordSelectionHandlerBase.java
@@ -16,6 +16,8 @@
package com.intellij.codeInsight.editorActions;
+import com.intellij.diagnostic.LogEventException;
+import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
@@ -42,12 +44,14 @@ public abstract class ExtendWordSelectionHandlerBase implements ExtendWordSelect
public List select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) {
final TextRange originalRange = e.getTextRange();
if (originalRange.getEndOffset() > editorText.length()) {
- throw new AssertionError("Invalid element range in " + getClass() +
- "; element=" + e +
- "; range=" + originalRange +
- "; length=" + editorText +
- "; editor=" + editor +
- "; committed=" + PsiDocumentManager.getInstance(e.getProject()).isCommitted(editor.getDocument()));
+ throw new LogEventException("Invalid element range in " + getClass(),
+ "element=" + e +
+ "; range=" + originalRange +
+ "; text length=" + editorText.length() +
+ "; editor=" + editor +
+ "; committed=" + PsiDocumentManager.getInstance(e.getProject()).isCommitted(editor.getDocument()),
+ new Attachment("editor_text.txt", editorText.toString()),
+ new Attachment("psi_text.txt", e.getText()));
}
List ranges = expandToWholeLine(editorText, originalRange, true);
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
index 155158367d7e..5a18d9f36adb 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
@@ -38,6 +38,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
@@ -133,7 +134,7 @@ public class ConsoleHistoryController {
}
public boolean hasHistory() {
- return getModel().getHistory().isEmpty();
+ return !getModel().getEntries().isEmpty();
}
private static String fixNullPersistenceId(@Nullable String persistenceId, @NotNull LanguageConsoleView console) {
@@ -236,7 +237,9 @@ public class ConsoleHistoryController {
@Override
public void run() {
if (storeUserText) {
- myHelper.setContent(document.getText());
+ String text = document.getText();
+ if (Comparing.equal(command, text) && myHelper.getContent() != null) return;
+ myHelper.setContent(text);
}
String text = StringUtil.notNullize(command);
int offset;
@@ -290,22 +293,23 @@ public class ConsoleHistoryController {
@Override
public void actionPerformed(final AnActionEvent e) {
- final String command;
+ String command;
if (myNext) {
command = getModel().getHistoryNext();
if (!myMultiline && command == null) return;
}
else {
- if (!myMultiline && getModel().getHistoryCursor() < 0) return;
command = ObjectUtils.chooseNotNull(getModel().getHistoryPrev(), myMultiline ? "" : StringUtil.notNullize(myHelper.getContent()));
}
- setConsoleText(command, myNext && getModel().getHistoryCursor() == 0, true);
+ setConsoleText(command, myNext && !getModel().hasHistory(false), true);
}
@Override
public void update(final AnActionEvent e) {
super.update(e);
- e.getPresentation().setEnabled(myMultiline || !isUpDownKey(e) || canMoveInEditor(myNext));
+ boolean enabled = myMultiline || !isUpDownKey(e) || canMoveInEditor(myNext);
+ //enabled &= getModel().hasHistory(myNext);
+ e.getPresentation().setEnabled(enabled);
}
private boolean isUpDownKey(AnActionEvent e) {
@@ -340,12 +344,13 @@ public class ConsoleHistoryController {
private class MyBrowseAction extends AnAction {
@Override
- public void update(final AnActionEvent e) {
- e.getPresentation().setEnabled(getModel().getHistorySize() > 0);
+ public void update(AnActionEvent e) {
+ boolean enabled = hasHistory();
+ e.getPresentation().setEnabled(enabled);
}
@Override
- public void actionPerformed(final AnActionEvent e) {
+ public void actionPerformed(AnActionEvent e) {
String s1 = KeymapUtil.getFirstKeyboardShortcutText(myHistoryNext);
String s2 = KeymapUtil.getFirstKeyboardShortcutText(myHistoryPrev);
String title = myConsole.getTitle() + " History" +
@@ -364,7 +369,9 @@ public class ConsoleHistoryController {
@Override
protected List getContents() {
- return getModel().getHistory();
+ List entries = getModel().getEntries();
+ Collections.reverse(entries);
+ return entries;
}
@Override
@@ -394,7 +401,7 @@ public class ConsoleHistoryController {
};
chooser.setContentIcon(null);
chooser.setSplitterOrientation(false);
- chooser.setSelectedIndex(Math.max(getModel().getHistoryCursor(), 0));
+ chooser.setSelectedIndex(Math.max(0, getModel().getHistorySize() - getModel().getCurrentIndex() - 1));
if (chooser.showAndGet() && myConsole.getCurrentEditor().getComponent().isShowing()) {
setConsoleText(chooser.getSelectedText(), false, true);
}
@@ -455,11 +462,8 @@ public class ConsoleHistoryController {
}
return false;
}
- List entries = Arrays.asList(VfsUtilCore.loadText(file).split(myRootType.getEntrySeparator()));
- for (ListIterator iterator = entries.listIterator(entries.size()); iterator.hasPrevious(); ) {
- String entry = iterator.previous();
- getModel().addToHistory(entry);
- }
+ String[] split = VfsUtilCore.loadText(file).split(myRootType.getEntrySeparator());
+ getModel().resetEntries(Arrays.asList(split));
return true;
}
catch (Exception ignored) {
@@ -537,7 +541,7 @@ public class ConsoleHistoryController {
private void saveHistory() {
try {
- if (getModel().getHistory().isEmpty()) return;
+ if (getModel().getEntries().isEmpty()) return;
if (myRootType.isHidden()) {
saveHistoryOld();
return;
@@ -545,7 +549,7 @@ public class ConsoleHistoryController {
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
try {
VirtualFile file = HistoryRootType.getInstance().findFile(null, getHistoryName(myRootType, myId), ScratchFileService.Option.create_if_missing);
- VfsUtil.saveText(file, StringUtil.join(getModel().getHistory(), myRootType.getEntrySeparator()));
+ VfsUtil.saveText(file, StringUtil.join(getModel().getEntries(), myRootType.getEntrySeparator()));
}
finally {
token.finish();
@@ -573,10 +577,7 @@ public class ConsoleHistoryController {
}
in.moveUp();
}
- for (ListIterator iterator = entries.listIterator(entries.size()); iterator.hasPrevious(); ) {
- String entry = iterator.previous();
- getModel().addToHistory(entry);
- }
+ getModel().resetEntries(entries);
return consoleContent;
}
@@ -586,7 +587,7 @@ public class ConsoleHistoryController {
out.attribute(null, "version", "1");
out.attribute(null, "id", myId);
try {
- for (String s : getModel().getHistory()) {
+ for (String s : getModel().getEntries()) {
textTag(out, "history-entry", s);
}
String current = myContent;
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java
index 415d0acd47e0..9cc7e6079654 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java
@@ -18,6 +18,7 @@ package com.intellij.execution.console;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -30,95 +31,86 @@ import java.util.List;
class ConsoleHistoryModel extends SimpleModificationTracker {
/** @noinspection FieldCanBeLocal*/
private final ConsoleHistoryModel myMasterModel; // hard ref
- private int myHistoryCursor = -1;
- private final LinkedList myHistory;
+ private int myIndex;
+ private final LinkedList myEntries;
ConsoleHistoryModel(ConsoleHistoryModel masterModel) {
myMasterModel = masterModel;
- myHistory = myMasterModel == null ? new LinkedList() : myMasterModel.myHistory;
+ myEntries = myMasterModel == null ? new LinkedList() : myMasterModel.myEntries;
+ resetIndex();
}
ConsoleHistoryModel copy() {
return new ConsoleHistoryModel(this);
}
- public void addToHistory(@Nullable String statement) {
+ public synchronized void resetEntries(@NotNull List entries) {
+ myEntries.clear();
+ myEntries.addAll(entries.subList(0, Math.min(entries.size(), getMaxHistorySize())));
+ incModificationCount();
+ }
+
+ public synchronized void addToHistory(@Nullable String statement) {
if (StringUtil.isEmptyOrSpaces(statement)) return;
int maxHistorySize = getMaxHistorySize();
- synchronized (myHistory) {
- incModificationCount();
- myHistoryCursor = -1;
-
- myHistory.remove(statement);
- int size = myHistory.size();
- if (size >= maxHistorySize && size > 0) {
- myHistory.removeLast();
- }
- myHistory.addFirst(statement);
+ myEntries.remove(statement);
+ int size = myEntries.size();
+ if (size >= maxHistorySize && size > 0) {
+ myEntries.removeFirst();
}
+ myEntries.addLast(statement);
+ incModificationCount();
+ }
+
+ @Override
+ public void incModificationCount() {
+ resetIndex();
+ super.incModificationCount();
+ }
+
+ protected synchronized void resetIndex() {
+ myIndex = myEntries.size();
}
public int getMaxHistorySize() {
return UISettings.getInstance().CONSOLE_COMMAND_HISTORY_LIMIT;
}
- public void removeFromHistory(final String statement) {
- synchronized (myHistory) {
- incModificationCount();
- myHistoryCursor = -1;
-
- myHistory.remove(statement);
- }
+ public synchronized void removeFromHistory(String statement) {
+ myEntries.remove(statement);
+ incModificationCount();
}
- public List getHistory() {
- synchronized (myHistory) {
- return new ArrayList(myHistory);
- }
+ public synchronized List getEntries() {
+ return new ArrayList(myEntries);
}
- public int getHistorySize() {
- synchronized (myHistory) {
- return myHistory.size();
- }
+ public synchronized int getHistorySize() {
+ return myEntries.size();
}
@Nullable
- public String getHistoryNext() {
- synchronized (myHistory) {
- if (myHistoryCursor < myHistory.size() - 1) {
- return myHistory.get(++myHistoryCursor);
- }
- else {
- if (myHistoryCursor == myHistory.size() - 1) myHistoryCursor++;
- return null;
- }
- }
+ public synchronized String getHistoryNext() {
+ if (myIndex >= 0) --myIndex;
+ return getCurrentEntry();
}
@Nullable
- public String getHistoryPrev() {
- synchronized (myHistory) {
- if (myHistoryCursor > 0) {
- return myHistory.get(--myHistoryCursor);
- }
- else {
- if (myHistoryCursor == 0) myHistoryCursor--;
- return null;
- }
- }
+ public synchronized String getHistoryPrev() {
+ if (myIndex <= myEntries.size() - 1) ++myIndex;
+ return getCurrentEntry();
}
- public boolean hasHistory(final boolean next) {
- synchronized (myHistory) {
- return next ? myHistoryCursor <= myHistory.size() - 1 : myHistoryCursor >= 0;
- }
+ public synchronized boolean hasHistory(final boolean next) {
+ return next ? myIndex > 0 : myIndex < myEntries.size() - 1;
}
- public int getHistoryCursor() {
- synchronized (myHistory) {
- return myHistoryCursor;
- }
+ synchronized String getCurrentEntry() {
+ return myIndex >= 0 && myIndex < myEntries.size() ? myEntries.get(myIndex) : null;
+ }
+
+ synchronized int getCurrentIndex() {
+ return myIndex;
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java
index 1be1903bf18b..98f97cb75819 100644
--- a/platform/platform-api/src/com/intellij/ui/table/TableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java
@@ -36,6 +36,9 @@ import java.util.Collections;
import java.util.List;
public class TableView- extends BaseTableView implements ItemsProvider, SelectionProvider {
+
+ private boolean myInStopEditing = false;
+
public TableView() {
this(new ListTableModel
- (ColumnInfo.EMPTY_ARRAY));
}
@@ -59,7 +62,7 @@ public class TableView
- extends BaseTableView implements ItemsProvider, Sel
public void setModel(final ListTableModel
- model) {
setModelAndUpdateColumns(model);
}
-
+
public void setModelAndUpdateColumns(final ListTableModel
- model) {
super.setModel(model);
createDefaultColumnsFromModel();
@@ -264,7 +267,15 @@ public class TableView
- extends BaseTableView implements ItemsProvider, Sel
}
public void stopEditing() {
- TableUtil.stopEditing(this);
+ if (!myInStopEditing) {
+ try {
+ myInStopEditing = true;
+ TableUtil.stopEditing(this);
+ }
+ finally {
+ myInStopEditing = false;
+ }
+ }
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
index 88884e8c9b52..76c6505b508a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
@@ -64,7 +64,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
private final Queue myRunWhenSmartQueue = new Queue(5);
private final Project myProject;
- private ThreadLocal myAlternativeResolution = new ThreadLocal();
+ private ThreadLocal myAlternativeResolution = new ThreadLocal();
public DumbServiceImpl(Project project) {
myProject = project;
@@ -108,13 +108,15 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
@Override
public boolean isAlternativeResolveEnabled() {
- return Boolean.TRUE.equals(myAlternativeResolution.get());
+ return myAlternativeResolution.get() != null;
}
@Override
public void setAlternativeResolveEnabled(boolean enabled) {
- assert isAlternativeResolveEnabled() != enabled : "Nested alternative resolution mode is not supported";
- myAlternativeResolution.set(enabled);
+ Integer oldValue = myAlternativeResolution.get();
+ int newValue = (oldValue == null ? 0 : oldValue) + (enabled ? 1 : -1);
+ assert newValue >= 0 : "Non-paired alternative resolution mode";
+ myAlternativeResolution.set(newValue == 0 ? null : newValue);
}
@Override
diff --git a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
index 3bd8027a9f09..5be52011e2da 100644
--- a/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
+++ b/platform/util/src/com/intellij/util/lang/UrlClassLoader.java
@@ -64,7 +64,10 @@ public class UrlClassLoader extends ClassLoader {
}
}
- @NotNull private final Builder myBuilder;
+ @NotNull
+ protected ClassPath getClassPath() {
+ return myClassPath;
+ }
public static final class Builder {
private List myURLs = ContainerUtil.emptyList();
@@ -130,7 +133,7 @@ public class UrlClassLoader extends ClassLoader {
}
private final List myURLs;
- private ClassPath myClassPath;
+ private final ClassPath myClassPath;
private final boolean myAllowBootstrapResources;
/** @deprecated use {@link #build()}, left for compatibility with java.system.class.loader setting */
@@ -161,17 +164,22 @@ public class UrlClassLoader extends ClassLoader {
protected UrlClassLoader(@NotNull Builder builder) {
super(builder.myParent);
- myBuilder = builder;
myURLs = ContainerUtil.map(builder.myURLs, new Function() {
@Override
public URL fun(URL url) {
return internProtocol(url);
}
});
- resetCache();
+ myClassPath = createClassPath(builder);
myAllowBootstrapResources = builder.myAllowBootstrapResources;
}
+ @NotNull
+ protected final ClassPath createClassPath(@NotNull Builder builder) {
+ return new ClassPath(myURLs, builder.myLockJars, builder.myUseCache, builder.myAcceptUnescaped, builder.myPreload,
+ builder.myUsePersistentClasspathIndex, builder.myCachePool, builder.myCachingCondition);
+ }
+
public static URL internProtocol(@NotNull URL url) {
try {
final String protocol = url.getProtocol();
@@ -189,7 +197,7 @@ public class UrlClassLoader extends ClassLoader {
/** @deprecated to be removed in IDEA 15 */
@SuppressWarnings({"unused", "deprecation"})
public void addURL(URL url) {
- myClassPath.addURL(url);
+ getClassPath().addURL(url);
myURLs.add(url);
}
@@ -197,18 +205,9 @@ public class UrlClassLoader extends ClassLoader {
return Collections.unmodifiableList(myURLs);
}
- /**
- * Reset the internal cache. This can be useful after the loader has already tried to find some classes and remembered that they don't exist,
- * and then new class files appear under some of its directory URLs.
- */
- public void resetCache() {
- myClassPath = new ClassPath(myURLs, myBuilder.myLockJars, myBuilder.myUseCache, myBuilder.myAcceptUnescaped, myBuilder.myPreload,
- myBuilder.myUsePersistentClasspathIndex, myBuilder.myCachePool, myBuilder.myCachingCondition);
- }
-
@Override
protected Class findClass(final String name) throws ClassNotFoundException {
- Resource res = myClassPath.getResource(name.replace('.', '/').concat(CLASS_EXTENSION), false);
+ Resource res = getClassPath().getResource(name.replace('.', '/').concat(CLASS_EXTENSION), false);
if (res == null) {
throw new ClassNotFoundException(name);
}
@@ -223,7 +222,7 @@ public class UrlClassLoader extends ClassLoader {
@Nullable
protected Class _findClass(@NotNull String name) {
- Resource res = myClassPath.getResource(name.replace('.', '/').concat(CLASS_EXTENSION), false);
+ Resource res = getClassPath().getResource(name.replace('.', '/').concat(CLASS_EXTENSION), false);
if (res == null) {
return null;
}
@@ -275,7 +274,7 @@ public class UrlClassLoader extends ClassLoader {
private Resource _getResource(final String name) {
String n = name;
if (n.startsWith("/")) n = n.substring(1);
- return myClassPath.getResource(n, true);
+ return getClassPath().getResource(n, true);
}
@Nullable
@@ -295,7 +294,7 @@ public class UrlClassLoader extends ClassLoader {
// Accessed from PluginClassLoader via reflection // TODO do we need it?
@Override
protected Enumeration findResources(String name) throws IOException {
- return myClassPath.getResources(name, true);
+ return getClassPath().getResources(name, true);
}
public static void loadPlatformLibrary(@NotNull String libName) {
@@ -356,7 +355,6 @@ public class UrlClassLoader extends ClassLoader {
public interface CachingCondition {
/**
- * @param url
* @return whether the internal information should be cached for files in a specific classpath component URL: inside the directory or
* a jar.
*/
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
index 83809327be4b..570bd2f84ed3 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.issueLinks.LinkMouseListenerBase;
@@ -81,6 +82,8 @@ public class XValueHint extends AbstractValueHint {
private final ExpressionInfo myExpressionInfo;
private Disposable myDisposable;
+ private static final Key HINT_KEY = Key.create("allows only one value hint per editor");
+
public XValueHint(@NotNull Project project, @NotNull Editor editor, @NotNull Point point, @NotNull ValueHintType type,
@NotNull ExpressionInfo expressionInfo, @NotNull XDebuggerEvaluator evaluator,
@NotNull XDebugSession session) {
@@ -125,12 +128,24 @@ public class XValueHint extends AbstractValueHint {
}
}.registerCustomShortcutSet(shortcut, getEditor().getContentComponent(), myDisposable);
}
+ if (result) {
+ XValueHint prev = getEditor().getUserData(HINT_KEY);
+ if (prev != null) {
+ prev.hideHint();
+ }
+ HINT_KEY.set(getEditor(), this);
+ getEditor().putUserData(HINT_KEY, this);
+ }
return result;
}
@Override
protected void onHintHidden() {
super.onHintHidden();
+ XValueHint prev = getEditor().getUserData(HINT_KEY);
+ if (prev == this) {
+ getEditor().putUserData(HINT_KEY, null);
+ }
if (myDisposable != null) {
Disposer.dispose(myDisposable);
myDisposable = null;
diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java
index 0ff5ca6b8590..854d1826d74b 100644
--- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java
+++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/InProcessGroovyc.java
@@ -68,7 +68,7 @@ class InProcessGroovyc implements GroovycFlavor {
final LinkedBlockingQueue mailbox = forStubs && SystemProperties.getBooleanProperty("groovyc.joint.compilation", true)
? new LinkedBlockingQueue() : null;
- final UrlClassLoader loader = createCompilationClassLoader(compilationClassPath);
+ final JointCompilationClassLoader loader = createCompilationClassLoader(compilationClassPath);
final Future future = ourExecutor.submit(new Callable() {
@Override
@@ -89,7 +89,7 @@ class InProcessGroovyc implements GroovycFlavor {
private static GroovycContinuation waitForStubGeneration(final Future future,
final LinkedBlockingQueue mailbox,
final GroovycOutputParser parser,
- UrlClassLoader loader) throws InterruptedException {
+ JointCompilationClassLoader loader) throws InterruptedException {
while (true) {
if (future.isDone()) {
return null;
@@ -161,9 +161,9 @@ class InProcessGroovyc implements GroovycFlavor {
}
@NotNull
- private UrlClassLoader createCompilationClassLoader(Collection compilationClassPath) throws MalformedURLException {
+ private JointCompilationClassLoader createCompilationClassLoader(Collection compilationClassPath) throws MalformedURLException {
ClassLoader parent = obtainParentLoader(compilationClassPath);
- return UrlClassLoader.build().
+ return new JointCompilationClassLoader(UrlClassLoader.build().
urls(toUrls(compilationClassPath)).parent(parent).allowLock().
useCache(ourLoaderCachePool, new UrlClassLoader.CachingCondition() {
@Override
@@ -182,7 +182,7 @@ class InProcessGroovyc implements GroovycFlavor {
return false;
}
}
- }).get();
+ }));
}
@Nullable
diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JointCompilationClassLoader.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JointCompilationClassLoader.java
new file mode 100644
index 000000000000..00e5fc8af2cd
--- /dev/null
+++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JointCompilationClassLoader.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2015 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 org.jetbrains.jps.incremental.groovy;
+
+import com.intellij.util.lang.ClassPath;
+import com.intellij.util.lang.UrlClassLoader;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+class JointCompilationClassLoader extends UrlClassLoader {
+ @NotNull private final Builder myBuilder;
+ @NotNull private ClassPath myClassPath;
+
+ public JointCompilationClassLoader(@NotNull Builder builder) {
+ super(builder);
+ myBuilder = builder;
+ myClassPath = super.getClassPath();
+ }
+
+ @NotNull
+ @Override
+ protected ClassPath getClassPath() {
+ return myClassPath;
+ }
+
+ void resetCache() {
+ myClassPath = createClassPath(myBuilder);
+ }
+}