From ff7e85c3b046271b4afc237eaae7340e9557b57d Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Wed, 4 Mar 2015 15:50:22 +0100 Subject: [PATCH 01/14] IDEA-136006 - StackOverflowError when selecting tomcat logs --- .../src/com/intellij/ui/table/TableView.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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 From e9ea38d0f729a3b662003953ad17a10c2b77bde8 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 4 Mar 2015 18:14:22 +0300 Subject: [PATCH 02/14] IDEA-137255 Debugger Hints go crazy This fix allows to have only one value hint per editor. --- .../xdebugger/impl/evaluate/quick/XValueHint.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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; From 188e44f12c6e797f3a752b9c327ba0ed4090a52a Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 4 Mar 2015 18:56:03 +0300 Subject: [PATCH 03/14] BuildManager: simplification --- .../src/com/intellij/compiler/server/BuildManager.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) 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); From 80aa5f1f840bdc2565b3403a9a935ffa0b577eec Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 16:00:41 +0100 Subject: [PATCH 04/14] a more civilized diagnostics (EA-65788 - assert: ExtendWordSelectionHandlerBase.select) --- .../ExtendWordSelectionHandlerBase.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) 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); From ba226034970513ff44d42d6760d4d8b9af1658af Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 16:03:21 +0100 Subject: [PATCH 05/14] diagnose EA-65770 - CME: LiftShorterItemsClassifier.addElement --- .../impl/LiftShorterItemsClassifier.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) 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); From 24f709d4bac562a244825b9e6d26208156fae46d Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 16:20:05 +0100 Subject: [PATCH 06/14] support nested alternative resolve (EA-65685) --- .../com/intellij/openapi/project/DumbServiceImpl.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 From 95baa39d12a8b053661c48d0db0ecfa3f149518c Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 16:31:22 +0100 Subject: [PATCH 07/14] IDEA-136783 Completion: delay showing middle-matched items until at least some (or all) start-matching ones are shown use a more addition-efficient collection for delayed items --- .../completion/CompletionProgressIndicator.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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..d754c0421ebf 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,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } void addDelayedMiddleMatches() { - for (CompletionResult item : myDelayedMiddleMatches) { + ArrayList delayed; + synchronized (myDelayedMiddleMatches) { + delayed = ContainerUtil.newArrayList(myDelayedMiddleMatches); + myDelayedMiddleMatches.clear(); + } + for (CompletionResult item : delayed) { ProgressManager.checkCanceled(); addItemToLookup(item); } - myDelayedMiddleMatches.clear(); } public void closeAndFinish(boolean hideLookup) { From b0cebde5bcaffbbb969563f62eda7a4e04d799c9 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 16:50:02 +0100 Subject: [PATCH 08/14] move cache resetting to UrlClassLoader subclass --- .../intellij/util/lang/UrlClassLoader.java | 36 +++++++-------- .../incremental/groovy/InProcessGroovyc.java | 10 ++--- .../groovy/JointCompilationClassLoader.java | 44 +++++++++++++++++++ 3 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/JointCompilationClassLoader.java 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/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); + } +} From 29038e5e868c5f686c63649462b44cb6496ab2cf Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 18:10:13 +0100 Subject: [PATCH 09/14] release smart pointer storage when disposing the last smart pointer in file explicitly --- .../psi/impl/smartPointers/SmartPointerManagerImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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; } } From 15fa559d416b3a5d7db5baa979ccf9204d71de83 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 4 Mar 2015 18:19:14 +0100 Subject: [PATCH 10/14] IDEA-136783 Completion: delay showing middle-matched items until at least some (or all) start-matching ones are shown avoid useless allocations --- .../codeInsight/completion/CompletionProgressIndicator.java | 1 + 1 file changed, 1 insertion(+) 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 d754c0421ebf..6eb3c9f3bcaa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -426,6 +426,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement void addDelayedMiddleMatches() { ArrayList delayed; synchronized (myDelayedMiddleMatches) { + if (myDelayedMiddleMatches.isEmpty()) return; delayed = ContainerUtil.newArrayList(myDelayedMiddleMatches); myDelayedMiddleMatches.clear(); } From c5c15f7cadead580f14eb5a39ab6ac0786c3ee98 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 4 Mar 2015 20:19:19 +0300 Subject: [PATCH 11/14] IDEA-92332 Breakpoints alowed on import and package statments. --- .../debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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..5ac0b1a58517 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 @@ -98,7 +98,8 @@ public abstract class JavaLineBreakpointTypeBase

Date: Wed, 4 Mar 2015 20:26:57 +0300 Subject: [PATCH 12/14] avoid NPE --- .../debugger/ui/breakpoints/JavaLineBreakpointTypeBase.java | 1 + 1 file changed, 1 insertion(+) 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 5ac0b1a58517..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,6 +93,7 @@ public abstract class JavaLineBreakpointTypeBase

> result = Ref.create(); XDebuggerUtil.getInstance().iterateLine(project, document, line, new Processor() { @Override From 6937ba67f24b4cfb5ea3e03ff9a9a453d456c3b8 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 4 Mar 2015 21:06:26 +0300 Subject: [PATCH 13/14] History: natural console history ordering and DBE-1149 fix --- .../console/ConsoleHistoryController.java | 47 ++++---- .../console/ConsoleHistoryModel.java | 106 ++++++++---------- 2 files changed, 73 insertions(+), 80 deletions(-) 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; } } From c7b0417f1e9c8b8e5124cc813f61a42b0ec5bd51 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Wed, 4 Mar 2015 21:17:43 +0300 Subject: [PATCH 14/14] OC-11478 Navigate to super and overriding methods in Swift (fix blinking test on server - global) --- .../intellij/codeInsight/daemon/MergeableLineMarkerInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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,