From dcbce7453919e5bf688f4d02cd8ac0776d73f4d2 Mon Sep 17 00:00:00 2001 From: Oleg Sukhodolsky Date: Wed, 20 Nov 2013 13:48:45 +0400 Subject: [PATCH 01/30] RUBY-14570: fixing strings according to proofreading results. --- .../src/inspectionDescriptions/Annotator.html | 2 +- .../src/inspectionDescriptions/SyntaxError.html | 2 +- .../src/messages/ApplicationBundle.properties | 2 +- .../src/codeStyle/preview/preview.xml.template | 2 +- .../inspectionDescriptions/HtmlFormInputWithoutLabel.html | 2 +- .../inspectionDescriptions/HtmlPresentationalElement.html | 2 +- .../resources/inspectionDescriptions/XmlUnboundNsPrefix.html | 2 +- .../application/options/editor/WebEditorOptionsForm.form | 2 +- xml/relaxng/src/inspectionDescriptions/UnusedDefine.html | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html b/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html index ce63baf76ae2..5003474700c6 100644 --- a/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html +++ b/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html @@ -1,5 +1,5 @@ -Allows to see problems reported by language annotators in the results of batch code inspection. +Allows you to see problems reported by language annotators in the results of batch code inspection. \ No newline at end of file diff --git a/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html b/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html index 398a7b8a0e03..d60b5db0e39e 100644 --- a/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html +++ b/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html @@ -1,5 +1,5 @@ -Allows to see syntax errors in the results of batch code inspection. +Allows you to see syntax errors in the results of batch code inspection. \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 577a0766460c..0b45e230e88a 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -505,7 +505,7 @@ title.colors.and.fonts=Colors \\& Fonts progress.analysing.font=Analysing font: {0} button.edit.scopes=Edit Scopes... group.editor.font=Editor Font -label.fallback.fonts.list.description=If primary font fails IDE tries to use the secondary one +label.fallback.fonts.list.description=If primary font fails, IDE tries to use the secondary one quickdoc.tooltip.font.size.by.wheel=Slider or Ctrl+Wheel change font size label.font.size=Font size: label.font.name=Name: diff --git a/platform/platform-resources/src/codeStyle/preview/preview.xml.template b/platform/platform-resources/src/codeStyle/preview/preview.xml.template index 6edd0817d215..ca848fe23595 100644 --- a/platform/platform-resources/src/codeStyle/preview/preview.xml.template +++ b/platform/platform-resources/src/codeStyle/preview/preview.xml.template @@ -10,7 +10,7 @@ Our product makes development a real pleasure. It decreases the time you spend on routine, repetitive handwork, giving you more time to focus on the task at hand. Its robust set of features for automatic error-checking and code correction cuts development time and increases your efficiency. You'll find that our product quickly - pays back it's cost in increased developer productivity and improved code quality. + pays back its cost in increased developer productivity and improved code quality. diff --git a/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html b/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html index 680c983342d4..52947834a6ae 100644 --- a/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html +++ b/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html @@ -1,6 +1,6 @@ -This inspection highlights form elements without required associated label and provides ability to create a new label.
+This inspection highlights form elements without required associated label and provides the ability to create a new label.
\ No newline at end of file diff --git a/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html b/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html index 3a0609aa95fc..46257d041b1b 100644 --- a/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html +++ b/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html @@ -1,6 +1,6 @@ -This inspection highlights pure presentational HTML tags and provides ability to replace them with CSS or with other tags.
+This inspection highlights pure presentational HTML tags and provides the ability to replace them with CSS or with other tags.
\ No newline at end of file diff --git a/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html b/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html index 2821e9fe15b0..c2d3c150ad28 100644 --- a/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html +++ b/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html @@ -1,6 +1,6 @@ -This inspection checks for unbound namespace prefixes in XML +This inspection checks for unbound namespace prefixes in XML. \ No newline at end of file diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form index 4dd9851442ca..dca1e251f80e 100644 --- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form +++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form @@ -65,7 +65,7 @@ - +
diff --git a/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html b/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html index 1a59a9063112..8c22875b4e81 100644 --- a/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html +++ b/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html @@ -18,7 +18,7 @@

This inspections checks for any unused named patterns ("define") in a RELAX-NG file (XML or Compact Syntax) and highlights them as unused symbols. This is done with respect to includes from other files, i.e. a define is not - marked as unused if is is used through an include in another file. + marked as unused if it is used through an include in another file.

From 3629c77998bb879e890cff659e2f5de7d08d5871 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 20 Nov 2013 13:50:23 +0400 Subject: [PATCH 02/30] do not try to merge stubs if version changed --- .../api/indexer/CompilerOutputBaseIndex.java | 2 +- .../com/intellij/index/StringIndex.java | 2 +- .../com/intellij/psi/stubs/StubIndexImpl.java | 9 ++++-- .../intellij/psi/stubs/StubUpdatingIndex.java | 12 +++++--- .../util/indexing/FileBasedIndexImpl.java | 30 +++++++++++-------- .../intellij/util/indexing/IndexingStamp.java | 19 ++++++++---- .../util/indexing/MapReduceIndex.java | 9 ++++-- .../util/indexing/UpdatableIndex.java | 7 +++-- 8 files changed, 58 insertions(+), 32 deletions(-) diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java index cf4de2562378..6eb9fc8c789d 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java @@ -149,7 +149,7 @@ public abstract class CompilerOutputBaseIndex { } public final void update(final int id, final ClassNode inputData) { - final Boolean result = myIndex.update(id, inputData).compute(); + final Boolean result = myIndex.update(id, inputData, true).compute(); if (result == Boolean.FALSE) throw new RuntimeException(); } diff --git a/java/java-tests/testSrc/com/intellij/index/StringIndex.java b/java/java-tests/testSrc/com/intellij/index/StringIndex.java index a12f58fbf137..cc9e7001a446 100644 --- a/java/java-tests/testSrc/com/intellij/index/StringIndex.java +++ b/java/java-tests/testSrc/com/intellij/index/StringIndex.java @@ -33,7 +33,7 @@ public class StringIndex { } public void update(final String path, @Nullable String content, @Nullable String oldContent) throws StorageException { - myIndex.update(path.hashCode(), toInput(path, content)).compute(); + myIndex.update(path.hashCode(), toInput(path, content), true).compute(); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java index 8ae32826414d..06f4e2703252 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java @@ -429,7 +429,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe public Collection call() throws Exception { return oldValues.keySet(); } - }); + }, true); } catch (StorageException e) { LOG.info(e); @@ -443,8 +443,11 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe } @Override - public void updateWithMap(final int inputId, @NotNull final Map newData, @NotNull Callable> oldKeysGetter) throws StorageException { - super.updateWithMap(inputId, newData, oldKeysGetter); + public void updateWithMap(final int inputId, + @NotNull final Map newData, + @NotNull Callable> oldKeysGetter, + boolean merge) throws StorageException { + super.updateWithMap(inputId, newData, oldKeysGetter, merge); } } diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 10b088935885..22730e2cfdc9 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -89,7 +89,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi return true; } final ID indexId = IndexInfrastructure.getStubId(INDEX_ID, fileType); - if (IndexingStamp.isFileIndexed(file, indexId, IndexInfrastructure.getIndexCreationStamp(indexId))) { + if (IndexingStamp.getIndexingState(file, indexId) == IndexingStamp.State.INDEXED) { return true; } } @@ -298,7 +298,10 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi } @Override - protected void updateWithMap(final int inputId, @NotNull final Map newData, @NotNull Callable> oldKeysGetter) + protected void updateWithMap(final int inputId, + @NotNull final Map newData, + @NotNull Callable> oldKeysGetter, + boolean merge) throws StorageException { checkNameStorage(); @@ -321,7 +324,8 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi try { getWriteLock().lock(); - final Map oldData = readOldData(inputId); + final Map oldData = + merge ? readOldData(inputId) : Collections.emptyMap(); final Map> oldStubTree; try { oldStubTree = getStubTree(oldData); @@ -330,7 +334,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi throw new StorageException(e); } - super.updateWithMap(inputId, newData, oldKeysGetter); + super.updateWithMap(inputId, newData, oldKeysGetter, merge); updateStubIndices(getAffectedIndices(oldStubTree, newStubTree), inputId, oldStubTree, newStubTree); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 15d4fdf9a089..f6a857483d5a 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1573,7 +1573,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { final int inputId = Math.abs(getFileId(vFile)); try { - getIndex(requestedIndexId).update(inputId, newFc).compute(); + getIndex(requestedIndexId).update(inputId, newFc, true).compute(); } catch (ProcessCanceledException pce) { myLastIndexedDocStamps.getAndSet(document, requestedIndexId, previousDocStamp); throw pce; @@ -1709,7 +1709,9 @@ public class FileBasedIndexImpl extends FileBasedIndex { //noinspection ForLoopReplaceableByForEach for (int i = 0, size = affectedIndexCandidates.size(); i < size; ++i) { final ID indexId = affectedIndexCandidates.get(i); - if (shouldIndexFile(file, indexId)) { + if (!getInputFilter(indexId).acceptInput(file)) continue; + IndexingStamp.State state = isMock(file) ? IndexingStamp.State.FILE_CONTENT_CHANGED : getIndexingState(file, indexId); + if (state != IndexingStamp.State.INDEXED) { if (fc == null) { byte[] currentBytes; try { @@ -1729,7 +1731,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { ProgressManager.checkCanceled(); - updateSingleIndex(indexId, file, fc); + updateSingleIndex(indexId, file, fc, state == IndexingStamp.State.FILE_CONTENT_CHANGED); } catch (ProcessCanceledException e) { cleanFileContent(fc, psiFile); @@ -1777,7 +1779,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { fc.putUserData(IndexingDataKeys.PROJECT, project); } - private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC) + private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC, boolean merge) throws StorageException { if (ourRebuildStatus.get(indexId).get() == REQUIRES_REBUILD) { return; // the index is scheduled for rebuild, no need to update @@ -1789,7 +1791,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { assert index != null; // important: no hard referencing currentFC to avoid OOME, the methods introduced for this purpose! - final Computable update = index.update(inputId, currentFC); + final Computable update = index.update(inputId, currentFC, merge); final FileType fileType = file.getFileType(); scheduleUpdate(indexId, @@ -1975,7 +1977,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { if (fileContent == null) { fileContent = new FileContentImpl(file); } - updateSingleIndex(indexId, file, fileContent); + updateSingleIndex(indexId, file, fileContent, true); } catch (StorageException e) { LOG.info(e); @@ -1998,7 +2000,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { final ID indexId = candidates.get(i); if (needsFileContentLoading(indexId) && getInputFilter(indexId).acceptInput(file)) { ID id = IndexInfrastructure.getStubId(indexId, fileType); - if (IndexingStamp.isFileIndexed(file, id, IndexInfrastructure.getIndexCreationStamp(id))) { + if (IndexingStamp.getIndexingState(file, id) != IndexingStamp.State.INDEXED) { IndexingStamp.update(file, id, IndexInfrastructure.INVALID_STAMP2); resetStamp = true; } @@ -2066,7 +2068,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { if (!needsFileContentLoading(indexId)) { if (shouldUpdateIndex(file, indexId)) { - updateSingleIndex(indexId, file, null); + updateSingleIndex(indexId, file, null, true); // todo: set merge to false? } } else { // the index requires file content @@ -2130,7 +2132,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { Throwable unexpectedError = null; for (ID indexId : affectedIndices) { try { - updateSingleIndex(indexId, file, null); + updateSingleIndex(indexId, file, null, true); // todo: set merge to false? } catch (StorageException e) { LOG.info(e); @@ -2398,7 +2400,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { if (fileContent == null) { fileContent = new FileContentImpl(file); } - updateSingleIndex(indexId, file, fileContent); + updateSingleIndex(indexId, file, fileContent, true); } catch (StorageException e) { LOG.info(e); @@ -2425,6 +2427,11 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } + private static IndexingStamp.State getIndexingState(VirtualFile file, ID indexId) { + ID id = IndexInfrastructure.getStubId(indexId, file.getFileType()); + return IndexingStamp.getIndexingState(file, id); + } + private boolean shouldUpdateIndex(final VirtualFile file, final ID indexId) { return getInputFilter(indexId).acceptInput(file) && (isMock(file) || isFileIndexed(file, indexId)); @@ -2436,8 +2443,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } private static boolean isFileIndexed(VirtualFile file, ID indexId) { - ID id = IndexInfrastructure.getStubId(indexId, file.getFileType()); - return IndexingStamp.isFileIndexed(file, id, IndexInfrastructure.getIndexCreationStamp(id)); + return getIndexingState(file, indexId) == IndexingStamp.State.INDEXED; } private static long getIndexCreationStamp(ID indexId, FileType fileType) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java index 8531bcf688eb..27170ce020e2 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java @@ -18,7 +18,6 @@ package com.intellij.util.indexing; import com.intellij.openapi.vfs.InvalidVirtualFileAccessException; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.util.containers.ConcurrentHashMap; @@ -58,7 +57,7 @@ public class IndexingStamp { if (id != null) { long stamp = IndexInfrastructure.getIndexCreationStamp(id); if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); - if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp); + myIndexStamps.put(id, stamp <= dominatingIndexStamp ? stamp : INDEX_VERSION_CHANGED_STAMP); } } } @@ -126,10 +125,20 @@ public class IndexingStamp { private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap(); private static final int CAPACITY = 100; private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY); + private static final long INDEX_VERSION_CHANGED_STAMP = 1l; - public static boolean isFileIndexed(VirtualFile file, ID indexName, final long indexCreationStamp) { + public enum State { + INDEXED, INDEX_VERSION_CHANGED, FILE_CONTENT_CHANGED + } + + public static State getIndexingState(VirtualFile file, ID indexName) { try { - return getIndexStamp(file, indexName) == indexCreationStamp; + long stamp = getIndexStamp(file, indexName); + if (stamp == INDEX_VERSION_CHANGED_STAMP) { + return State.INDEX_VERSION_CHANGED; + } + long indexCreationStamp = IndexInfrastructure.getIndexCreationStamp(indexName); + return stamp == indexCreationStamp ? State.INDEXED : State.FILE_CONTENT_CHANGED; } catch (RuntimeException e) { final Throwable cause = e.getCause(); @@ -138,7 +147,7 @@ public class IndexingStamp { } } - return false; + return State.FILE_CONTENT_CHANGED; } public static long getIndexStamp(VirtualFile file, ID indexName) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java index 98b62a5b3ffc..008aa3fd43a0 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java @@ -202,7 +202,7 @@ public class MapReduceIndex implements UpdatableIndex update(final int inputId, @Nullable Input content) { + public final Computable update(final int inputId, @Nullable final Input content, final boolean merge) { assert myInputsIndex != null; final Map data = content != null ? myIndexer.map(content) : Collections.emptyMap(); @@ -224,7 +224,7 @@ public class MapReduceIndex implements UpdatableIndex oldKeys = myInputsIndex.get(inputId); return oldKeys == null? Collections.emptyList() : oldKeys; } - }); + }, merge); } catch (StorageException ex) { exRef.set(ex); } @@ -242,7 +242,10 @@ public class MapReduceIndex implements UpdatableIndex newData, @NotNull Callable> oldKeysGetter) throws StorageException { + protected void updateWithMap(final int inputId, + @NotNull Map newData, + @NotNull Callable> oldKeysGetter, + boolean merge) throws StorageException { getWriteLock().lock(); try { try { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java index 51b2330ca36f..78704703a0d1 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java @@ -17,10 +17,8 @@ package com.intellij.util.indexing; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.ThrowableComputable; import org.jetbrains.annotations.Nullable; -import java.util.concurrent.Callable; import java.util.concurrent.locks.Lock; /** @@ -33,7 +31,10 @@ public interface UpdatableIndex extends AbstractIndex update(int inputId, @Nullable Input content); + /** + * @param merge true if merge with old data needed (e.g. file content changed), false if not needed (e.g. index version changed) + */ + Computable update(int inputId, @Nullable Input content, boolean merge); Lock getReadLock(); From 2ba69f0c31228cda43ca9937029b4ad87cefee1d Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 20 Nov 2013 13:55:20 +0400 Subject: [PATCH 03/30] EA-45917 - IAE: RangeMarkerImpl. --- .../execution/console/LanguageConsoleImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index d66de2d8abb0..5817e1ab10af 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -404,8 +404,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { Document history = myHistoryViewer.getDocument(); MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true); - int offset = history.getTextLength(); - appendToHistoryDocument(history, text); + int offset = appendToHistoryDocument(history, text); if (attributes == null) return; markupModel.addRangeHighlighter(offset, offset + text.length(), HighlighterLayer.SYNTAX, attributes, HighlighterTargetArea.EXACT_RANGE); } @@ -482,8 +481,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { highlighter = consoleEditor.getHighlighter(); } //offset can be changed after text trimming after insert due to buffer constraints - appendToHistoryDocument(history, text); - int offset = history.getTextLength() - text.length(); + int offset = appendToHistoryDocument(history, text); final HighlighterIterator iterator = highlighter.createIterator(localStartOffset); final int localEndOffset = textRange.getEndOffset(); @@ -514,9 +512,11 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes()); } - protected void appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) { + // returns the real (cyclic-buffer-aware) start offset of the inserted text + protected int appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) { ApplicationManager.getApplication().assertIsDispatchThread(); history.insertString(history.getTextLength(), text); + return history.getTextLength() - text.length(); } private static void duplicateHighlighters(@NotNull MarkupModel to, @NotNull MarkupModel from, int offset, @NotNull TextRange textRange) { From 267e10ad458255b0102ac5f3bef0a2436cd0e64b Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 20 Nov 2013 11:06:41 +0100 Subject: [PATCH 04/30] IDEA-116346 IntelliJ theme: comboboxes have darker background --- .../src/com/intellij/ide/ui/laf/intellijlaf.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties index 7128c5c3c85d..773bd46e5ddd 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties @@ -26,7 +26,7 @@ Menu.border=com.intellij.ide.ui.laf.darcula.ui.DarculaMenuItemBorder EditorPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaEditorPaneUI -control=cccccc +control=e0e0e0 link.foreground=589df6 ScrollBarUI=com.intellij.ide.ui.laf.darcula.ui.DarculaScrollBarUI From 3538fec72429591d807a1e901b84c4a7bb1540e5 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Wed, 20 Nov 2013 14:19:52 +0400 Subject: [PATCH 05/30] filter out artificial 'documentChanged' events from FileDocumentManager#saveAllDocuments --- .../execution/DelayedDocumentWatcher.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 149c11e37749..4951dc814179 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -16,17 +16,22 @@ package com.intellij.execution; import com.google.common.collect.ImmutableSet; +import com.intellij.AppTopics; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.problems.WolfTheProblemSolver; import com.intellij.util.Alarm; import com.intellij.util.Consumer; +import com.intellij.util.messages.MessageBusConnection; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +48,8 @@ public class DelayedDocumentWatcher { private final Runnable myAlarmRunnable; private final Set myChangedFiles = new THashSet(); - + private boolean myDocumentSavingInProgress = false; + private MessageBusConnection myConnection; public DelayedDocumentWatcher(@NotNull Project project, int delayMillis, @@ -65,15 +71,41 @@ public class DelayedDocumentWatcher { public void activate() { EditorFactory.getInstance().getEventMulticaster().addDocumentListener(myListener, myProject); + if (myConnection == null) { + myConnection = ApplicationManager.getApplication().getMessageBus().connect(myProject); + myConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() { + @Override + public void beforeAllDocumentsSaving() { + myDocumentSavingInProgress = true; + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + myDocumentSavingInProgress = false; + } + }, ModalityState.any()); + } + }); + } } public void deactivate() { EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(myListener); + if (myConnection != null) { + myConnection.disconnect(); + myConnection = null; + } } private class MyDocumentAdapter extends DocumentAdapter { @Override public void documentChanged(DocumentEvent event) { + if (myDocumentSavingInProgress) { + /** When {@link FileDocumentManager#saveAllDocuments} is called, + * {@link com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper} can change a document. + * These needless 'documentChanged' events should be filtered out. + */ + return; + } final Document document = event.getDocument(); final VirtualFile file = FileDocumentManager.getInstance().getFile(document); if (file == null) { From 2e7e757c2108ed82840b23eede2b524271b5e162 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 20 Nov 2013 11:39:01 +0100 Subject: [PATCH 06/30] IDEA-116343 IntelliJ theme: selected radio button is misplaced --- .../laf/darcula/ui/DarculaRadioButtonUI.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java index f2a2efd511fd..e6674a643331 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java @@ -17,7 +17,6 @@ package com.intellij.ide.ui.laf.darcula.ui; import com.intellij.ide.ui.laf.darcula.DarculaUIUtil; import com.intellij.openapi.ui.GraphicsConfig; -import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.ColorUtil; import com.intellij.ui.Gray; import com.intellij.util.ui.EmptyIcon; @@ -88,14 +87,21 @@ public class DarculaRadioButtonUI extends MetalRadioButtonUI { //setup AA for lines final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); - g.setPaint( - UIUtil.getGradientPaint(0, 0, ColorUtil.shift(c.getBackground(), 1.5), 0, c.getHeight(), ColorUtil.shift(c.getBackground(), 1.2))); - g.fillOval(0, 1, w - 1, h - 1); + final boolean focus = b.hasFocus(); + g.setPaint(UIUtil.getGradientPaint(0, 0, ColorUtil.shift(c.getBackground(), 1.5), + 0, c.getHeight(), ColorUtil.shift(c.getBackground(), 1.2))); + if (focus) { + g.fillOval(0, 1, w, h); + } else { + g.fillOval(0, 1, w - 1, h - 1); + } - if (b.hasFocus()) { - int sysOffX = SystemInfo.isMac ? 0 : 1; - int sysOffY = SystemInfo.isMac ? 0 : -1; - DarculaUIUtil.paintFocusOval(g, w/2 - rad - sysOffX, y- (rad + 1)/2 + sysOffY, w-2, h-2); + if (focus) { + if (UIUtil.isRetina()) { + DarculaUIUtil.paintFocusOval(g, 1, 2, w-2, h-2); + } else { + DarculaUIUtil.paintFocusOval(g, 0, 1, w, h); + } } else { if (UIUtil.isUnderDarcula()) { g.setPaint(UIUtil.getGradientPaint(w / 2, 1, Gray._160.withAlpha(90), w / 2, h, Gray._100.withAlpha(90))); From 07e864db2e65155096700406596e431b7c94c968 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 15:39:51 +0400 Subject: [PATCH 07/30] moved to core-impl to prevent abuse --- .../src/com/intellij/concurrency/JobLauncher.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/{core-api => core-impl}/src/com/intellij/concurrency/JobLauncher.java (100%) diff --git a/platform/core-api/src/com/intellij/concurrency/JobLauncher.java b/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java similarity index 100% rename from platform/core-api/src/com/intellij/concurrency/JobLauncher.java rename to platform/core-impl/src/com/intellij/concurrency/JobLauncher.java From eb73e5dac4b1393b7a216dc4d27abd219796d74a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 17:47:33 +0400 Subject: [PATCH 08/30] moved to core-impl --- .../src/com/intellij/openapi/application/ex/ApplicationEx.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/{platform-impl => core-impl}/src/com/intellij/openapi/application/ex/ApplicationEx.java (100%) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java similarity index 100% rename from platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java rename to platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java From f37078b69f1286faee4a5ddce48fd9d118158f09 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 17:48:14 +0400 Subject: [PATCH 09/30] use ApplicationEx for mock application --- .../src/com/intellij/core/CoreApplicationEnvironment.java | 3 ++- .../src/com/intellij/mock/MockApplicationEx.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) rename platform/{testFramework => core-impl}/src/com/intellij/mock/MockApplicationEx.java (98%) diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java index fed68c5688bc..60560a349f95 100644 --- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java +++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java @@ -19,6 +19,7 @@ import com.intellij.concurrency.*; import com.intellij.lang.*; import com.intellij.lang.impl.PsiBuilderFactoryImpl; import com.intellij.mock.MockApplication; +import com.intellij.mock.MockApplicationEx; import com.intellij.mock.MockFileDocumentManagerImpl; import com.intellij.mock.MockReferenceProvidersRegistry; import com.intellij.openapi.Disposable; @@ -135,7 +136,7 @@ public class CoreApplicationEnvironment { } protected MockApplication createApplication(Disposable parentDisposable) { - return new MockApplication(parentDisposable); + return new MockApplicationEx(parentDisposable); } protected JobLauncher createJobLauncher() { diff --git a/platform/testFramework/src/com/intellij/mock/MockApplicationEx.java b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java similarity index 98% rename from platform/testFramework/src/com/intellij/mock/MockApplicationEx.java rename to platform/core-impl/src/com/intellij/mock/MockApplicationEx.java index b33427096827..2636faeec21e 100644 --- a/platform/testFramework/src/com/intellij/mock/MockApplicationEx.java +++ b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java @@ -118,6 +118,7 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx @Override public boolean tryRunReadAction(@NotNull Runnable runnable) { - return false; + runReadAction(runnable); + return true; } } From 4e298bcdb58023f153c31dbb484e7e6e1c5b392e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 17:52:25 +0400 Subject: [PATCH 10/30] use indicator which is less dependencies demanding --- .../testSrc/com/intellij/concurrency/JobUtilTest.java | 3 ++- .../src/com/intellij/concurrency/JobLauncherImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java b/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java index 5df9119932da..fd68abd89066 100644 --- a/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java +++ b/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.testFramework.PlatformTestCase; import com.intellij.util.Processor; @@ -177,7 +178,7 @@ public class JobUtilTest extends PlatformTestCase { ProgressIndicator actualIndicator = ProgressManager.getInstance().getProgressIndicator(); if (progress == null) { assertNotNull(actualIndicator); - assertTrue(actualIndicator instanceof ProgressIndicatorBase); + assertTrue(actualIndicator instanceof AbstractProgressIndicatorBase); } else { assertTrue(actualIndicator instanceof SensitiveProgressWrapper); diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java index d87b9aeb0449..4e9a9b948d5b 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java @@ -19,7 +19,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; @@ -120,7 +120,7 @@ public class JobLauncherImpl extends JobLauncher { @NotNull final Processor thingProcessor) throws ProcessCanceledException { if (things.isEmpty()) return true; // supply our own indicator even if we haven't given one - to support cancellation - final ProgressIndicator wrapper = progress == null ? new ProgressIndicatorBase() : new SensitiveProgressWrapper(progress); + final ProgressIndicator wrapper = progress == null ? new AbstractProgressIndicatorBase() : new SensitiveProgressWrapper(progress); if (things.size() <= 1 || JobSchedulerImpl.CORES_COUNT <= CORES_FORK_THRESHOLD) { final AtomicBoolean result = new AtomicBoolean(true); From 7acfa4a4e916e017f81482b04d1a549e508e194f Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 17:53:28 +0400 Subject: [PATCH 11/30] cleanup --- .../find/impl/FindResultUsageInfo.java | 55 ++++++++++++++----- .../concurrency/ApplierCompleter.java | 2 +- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java index 138af2cbb285..2c372795ea85 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 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.find.impl; import com.intellij.find.FindManager; @@ -16,14 +31,14 @@ import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.NotNull; public class FindResultUsageInfo extends UsageInfo { - private FindManager myFindManager; - private FindModel myFindModel; + private final FindManager myFindManager; + private final FindModel myFindModel; private SmartPsiFileRange myAnchor; private Boolean myCachedResult; private long myTimestamp = 0; - private static Key ourDocumentTimestampKey = Key.create("com.intellij.find.impl.FindResultUsageInfo.documentTimestamp"); + private static final Key ourDocumentTimestampKey = Key.create("com.intellij.find.impl.FindResultUsageInfo.documentTimestamp"); @Override public boolean isValid() { @@ -35,40 +50,52 @@ public class FindResultUsageInfo extends UsageInfo { return false; } - if (document.getModificationStamp() == myTimestamp && myCachedResult != null) { - return myCachedResult; - } else { - myTimestamp = document.getModificationStamp(); + Boolean cachedResult = myCachedResult; + if (document.getModificationStamp() == myTimestamp && cachedResult != null) { + return cachedResult; } + myTimestamp = document.getModificationStamp(); - Segment segment = super.getSegment(); - if (segment == null) return myCachedResult = false; + Segment segment = getSegment(); + if (segment == null) { + myCachedResult = false; + return false; + } VirtualFile file = getPsiFile().getVirtualFile(); Segment searchOffset; if (myAnchor != null) { searchOffset = myAnchor.getRange(); - if (searchOffset == null) return myCachedResult = false; - } else { + if (searchOffset == null) { + myCachedResult = false; + return false; + } + } + else { searchOffset = segment; } int offset = searchOffset.getStartOffset(); - FindResult result; Long data = myFindModel.getUserData(ourDocumentTimestampKey); if (data == null || data != myTimestamp) { data = myTimestamp; myFindModel.putUserData(FindManagerImpl.ourCommentsLiteralsSearchDataKey, null); } myFindModel.putUserData(ourDocumentTimestampKey, data); + FindResult result; do { result = myFindManager.findString(document.getCharsSequence(), offset, myFindModel, file); offset = result.getEndOffset() == offset ? offset + 1 : result.getEndOffset(); - if (!result.isStringFound()) return myCachedResult = false; + if (!result.isStringFound()) { + myCachedResult = false; + return false; + } } while (result.getStartOffset() < segment.getStartOffset()); - return myCachedResult = (segment.getStartOffset() == result.getStartOffset() && segment.getEndOffset() == result.getEndOffset()); + boolean ret = segment.getStartOffset() == result.getStartOffset() && segment.getEndOffset() == result.getEndOffset(); + myCachedResult = ret; + return ret; } private PsiFile getPsiFile() { diff --git a/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java b/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java index 1644e54df8b1..4db4b3c67407 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java +++ b/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java @@ -219,7 +219,7 @@ public class ApplierCompleter extends CountedCompleter { } } }); - assert task.failedSubTasks == null; + assert task.failedSubTasks == null : task.failedSubTasks; } return result[0]; } From a6a900e3973154418015fb473df891a0d6e5436b Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Nov 2013 18:31:18 +0400 Subject: [PATCH 12/30] javadoc --- .../core-impl/src/com/intellij/concurrency/JobLauncher.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java b/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java index 2822832af85b..c5f6671ac126 100644 --- a/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java +++ b/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java @@ -26,6 +26,10 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.concurrent.Future; +/** + * Invitation-only service for running short-lived computing-intensive IO-free tasks on all available CPU cores. + * DO NOT USE for your tasks, IO-bound or long tasks, there is Application#executeOnPooledThread() for that. + */ public abstract class JobLauncher { public static JobLauncher getInstance() { return ServiceManager.getService(JobLauncher.class); From 31ddc7ee5bd55f1ac593c8a8419903f6282805cf Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Nov 2013 13:50:32 +0400 Subject: [PATCH 13/30] removed js-analysis-impl module --- build/scripts/layouts.gant | 1 - 1 file changed, 1 deletion(-) diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index e23b893019c4..fb0427ec800e 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -77,7 +77,6 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir "java-indexing-impl", "java-impl", "java-psi-impl", - "js-analysis-impl", "jsp-spi", "manifest", "platform-main", From 4ce8c5b19a8c88cac6c61e443462341765fe6ce3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Nov 2013 14:16:48 +0400 Subject: [PATCH 14/30] IDEA-115308 Find usages causes IDEA to hung forever --- .../psi/impl/search/PsiSearchHelperImpl.java | 194 ++++++++++-------- 1 file changed, 113 insertions(+), 81 deletions(-) diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index 27c595afa0b7..bc0fb118071a 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -20,6 +20,7 @@ import com.intellij.concurrency.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; @@ -27,10 +28,7 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.progress.util.TooManyUsagesStatus; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -60,7 +58,6 @@ import java.util.concurrent.atomic.AtomicInteger; public class PsiSearchHelperImpl implements PsiSearchHelper { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.PsiSearchHelperImpl"); - private final PsiManagerEx myManager; @Override @@ -76,8 +73,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return scope; } - - public PsiSearchHelperImpl(PsiManagerEx manager) { + public PsiSearchHelperImpl(@NotNull PsiManagerEx manager) { myManager = manager; } @@ -172,10 +168,22 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { PsiElement[] scopeElements = scope.getScope(); final StringSearcher searcher = new StringSearcher(text, caseSensitively, true, searchContext == UsageSearchContext.IN_STRINGS); Processor localProcessor = localProcessor(processor, progress, processInjectedPsi, searcher); - return JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(Arrays.asList(scopeElements), progress, false, localProcessor); + return wrapInFuture(Arrays.asList(scopeElements), progress, localProcessor); } - private boolean shouldProcessInjectedPsi(SearchScope scope) { + private static AsyncFuture wrapInFuture(@NotNull List files, final ProgressIndicator progress, @NotNull Processor processor) { + AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); + try { + boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, true, true, processor); + asyncFutureResult.set(result); + } + catch (Throwable t) { + asyncFutureResult.setException(t); + } + return asyncFutureResult; + } + + private static boolean shouldProcessInjectedPsi(SearchScope scope) { return scope instanceof LocalSearchScope ? !((LocalSearchScope)scope).isIgnoreInjectedPsi() : true; } @@ -265,7 +273,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { } AsyncFuture result = fileSet.isEmpty() - ? AsyncFutureFactory.wrap(true) + ? AsyncFutureFactory.wrap(Boolean.TRUE) : processPsiFileRootsAsync(new ArrayList(fileSet), fileSet.size(), 0, progress, localProcessor); return popStateAfter(result, progress); } @@ -299,32 +307,25 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return totalResult; } - // splits mainList into 2 lists: outIntersection containing elements from both mainList and list2 and outRest with all the rest elements from mainList - private static void splitSortedLists(@NotNull List mainList, - @NotNull List list2, - @NotNull Comparator comparator, - @NotNull List outIntersection, - @NotNull List outRest) { - int index1 = 0; - int index2 = 0; - while (index1 != mainList.size()) { - T element1 = mainList.get(index1); - T element2 = index2 == list2.size() ? null : list2.get(index2); - int c = element2 == null ? -1 : comparator.compare(element1, element2); - if (c == 0) { - outIntersection.add(element1); - index1++; - index2++; - } - else if (c < 0) { - index1++; - outRest.add(element1); - } - else { - index2++; - } + private static class CannotRunReadActionException extends RuntimeException{ + @Override + public Throwable fillInStackTrace() { + return this; } } + // throws exception if can't grab read action right now + private static T tryRead(final Computable computable) throws CannotRunReadActionException { + final Ref result = new Ref(); + if (((ApplicationEx)ApplicationManager.getApplication()).tryRunReadAction(new Runnable() { + @Override + public void run() { + result.set(computable.compute()); + } + })) { + return result.get(); + } + throw new CannotRunReadActionException(); + } /** * @param files to scan for references in this pass. @@ -337,64 +338,95 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final int totalSize, int alreadyProcessedFiles, final ProgressIndicator progress, - @NotNull final Processor psiRootProcessor) { + @NotNull final Processor localProcessor) { myManager.startBatchFilesProcessingMode(); final AtomicInteger counter = new AtomicInteger(alreadyProcessedFiles); final AtomicBoolean canceled = new AtomicBoolean(false); - AsyncFuture - completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor() { - @Override - public boolean process(final VirtualFile vfile) { - final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { + AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); + final List failedFiles = new ArrayList(); + try { + boolean completed = + JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor() { @Override - public PsiFile compute() { - return vfile.isValid() ? myManager.findFile(vfile) : null; + public boolean process(final VirtualFile vfile) { + try { + processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize); + } + catch (CannotRunReadActionException action) { + failedFiles.add(vfile); + } + return !canceled.get(); } }); - if (file != null && !(file instanceof PsiBinaryFile)) { - file.getViewProvider().getContents(); // load contents outside read action - if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); - List psiRoots = ApplicationManager.getApplication().runReadAction(new Computable>() { + if (!failedFiles.isEmpty()) { + for (final VirtualFile vfile : failedFiles) { + // we failed to run read action in job launcher thread + // run read action in our thread instead + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override - public List compute() { - return file.getViewProvider().getAllFiles(); + public void run() { + processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize); } }); - Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + } + } + asyncFutureResult.set(completed); + myManager.finishBatchFilesProcessingMode(); + } + catch (Throwable t) { + asyncFutureResult.setException(t); + } + + return asyncFutureResult; + } + + private void processVirtualFile(final VirtualFile vfile, + final ProgressIndicator progress, + final Processor localProcessor, + final AtomicBoolean canceled, AtomicInteger counter, int totalSize) { + final PsiFile file = tryRead(new Computable() { + @Override + public PsiFile compute() { + return vfile.isValid() ? myManager.findFile(vfile) : null; + } + }); + if (file != null && !(file instanceof PsiBinaryFile)) { + file.getViewProvider().getContents(); // load contents outside read action + if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); + final List psiRoots = tryRead(new Computable>() { + @Override + public List compute() { + return file.getViewProvider().getAllFiles(); + } + }); + final Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); + tryRead(new Computable() { + @Override + public Void compute() { for (final PsiFile psiRoot : psiRoots) { checkCanceled(progress); assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); if (!processed.add(psiRoot)) continue; - if (!ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return psiRoot.isValid(); - } - })) { + if (!psiRoot.isValid()) { continue; } - if (!psiRootProcessor.process(psiRoot)) { + + if (!localProcessor.process(psiRoot)) { canceled.set(true); break; } } + return null; } - if (progress != null && progress.isRunning()) { - double fraction = (double)counter.incrementAndGet() / totalSize; - progress.setFraction(fraction); - } - return !canceled.get(); - } - }); - - return new FinallyFuture(completed, new Runnable() { - @Override - public void run() { - myManager.finishBatchFilesProcessingMode(); - } - }); + }); + } + if (progress != null && progress.isRunning()) { + double fraction = (double)counter.incrementAndGet() / totalSize; + progress.setFraction(fraction); + } } private static void checkCanceled(ProgressIndicator progress) { @@ -769,6 +801,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return popStateAfter(result, progress); } + @NotNull private AsyncFuture processCandidatesAsync(final ProgressIndicator progress, @NotNull final Map> localProcessors, @NotNull final MultiMap candidateFiles, @@ -779,20 +812,19 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return processPsiFileRootsAsync(files, totalSize, alreadyProcessedFiles, progress, new Processor() { @Override public boolean process(final PsiFile psiRoot) { - final VirtualFile vfile = ApplicationManager.getApplication().runReadAction(new Computable() { + return tryRead(new Computable() { @Override - public VirtualFile compute() { - return psiRoot.getVirtualFile(); + public Boolean compute() { + final VirtualFile vfile = psiRoot.getVirtualFile(); + for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { + Processor localProcessor = localProcessors.get(singleRequest); + if (!localProcessor.process(psiRoot)) { + return false; + } + } + return true; } }); - for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { - Processor localProcessor = localProcessors.get(singleRequest); - TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); - if (!localProcessor.process(psiRoot)) { - return false; - } - } - return true; } }); } From ceafea25aa023d2f2bd7437b537e205abc8655e4 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 20 Nov 2013 15:31:13 +0400 Subject: [PATCH 15/30] do not try to merge stubs if version changed: reverted --- .../api/indexer/CompilerOutputBaseIndex.java | 2 +- .../com/intellij/index/StringIndex.java | 2 +- .../com/intellij/psi/stubs/StubIndexImpl.java | 9 ++---- .../intellij/psi/stubs/StubUpdatingIndex.java | 12 +++----- .../util/indexing/FileBasedIndexImpl.java | 30 ++++++++----------- .../intellij/util/indexing/IndexingStamp.java | 19 ++++-------- .../util/indexing/MapReduceIndex.java | 9 ++---- .../util/indexing/UpdatableIndex.java | 7 ++--- 8 files changed, 32 insertions(+), 58 deletions(-) diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java index 6eb9fc8c789d..cf4de2562378 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java @@ -149,7 +149,7 @@ public abstract class CompilerOutputBaseIndex { } public final void update(final int id, final ClassNode inputData) { - final Boolean result = myIndex.update(id, inputData, true).compute(); + final Boolean result = myIndex.update(id, inputData).compute(); if (result == Boolean.FALSE) throw new RuntimeException(); } diff --git a/java/java-tests/testSrc/com/intellij/index/StringIndex.java b/java/java-tests/testSrc/com/intellij/index/StringIndex.java index cc9e7001a446..a12f58fbf137 100644 --- a/java/java-tests/testSrc/com/intellij/index/StringIndex.java +++ b/java/java-tests/testSrc/com/intellij/index/StringIndex.java @@ -33,7 +33,7 @@ public class StringIndex { } public void update(final String path, @Nullable String content, @Nullable String oldContent) throws StorageException { - myIndex.update(path.hashCode(), toInput(path, content), true).compute(); + myIndex.update(path.hashCode(), toInput(path, content)).compute(); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java index 06f4e2703252..8ae32826414d 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java @@ -429,7 +429,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe public Collection call() throws Exception { return oldValues.keySet(); } - }, true); + }); } catch (StorageException e) { LOG.info(e); @@ -443,11 +443,8 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe } @Override - public void updateWithMap(final int inputId, - @NotNull final Map newData, - @NotNull Callable> oldKeysGetter, - boolean merge) throws StorageException { - super.updateWithMap(inputId, newData, oldKeysGetter, merge); + public void updateWithMap(final int inputId, @NotNull final Map newData, @NotNull Callable> oldKeysGetter) throws StorageException { + super.updateWithMap(inputId, newData, oldKeysGetter); } } diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 22730e2cfdc9..10b088935885 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -89,7 +89,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi return true; } final ID indexId = IndexInfrastructure.getStubId(INDEX_ID, fileType); - if (IndexingStamp.getIndexingState(file, indexId) == IndexingStamp.State.INDEXED) { + if (IndexingStamp.isFileIndexed(file, indexId, IndexInfrastructure.getIndexCreationStamp(indexId))) { return true; } } @@ -298,10 +298,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi } @Override - protected void updateWithMap(final int inputId, - @NotNull final Map newData, - @NotNull Callable> oldKeysGetter, - boolean merge) + protected void updateWithMap(final int inputId, @NotNull final Map newData, @NotNull Callable> oldKeysGetter) throws StorageException { checkNameStorage(); @@ -324,8 +321,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi try { getWriteLock().lock(); - final Map oldData = - merge ? readOldData(inputId) : Collections.emptyMap(); + final Map oldData = readOldData(inputId); final Map> oldStubTree; try { oldStubTree = getStubTree(oldData); @@ -334,7 +330,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi throw new StorageException(e); } - super.updateWithMap(inputId, newData, oldKeysGetter, merge); + super.updateWithMap(inputId, newData, oldKeysGetter); updateStubIndices(getAffectedIndices(oldStubTree, newStubTree), inputId, oldStubTree, newStubTree); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index f6a857483d5a..15d4fdf9a089 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1573,7 +1573,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { final int inputId = Math.abs(getFileId(vFile)); try { - getIndex(requestedIndexId).update(inputId, newFc, true).compute(); + getIndex(requestedIndexId).update(inputId, newFc).compute(); } catch (ProcessCanceledException pce) { myLastIndexedDocStamps.getAndSet(document, requestedIndexId, previousDocStamp); throw pce; @@ -1709,9 +1709,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { //noinspection ForLoopReplaceableByForEach for (int i = 0, size = affectedIndexCandidates.size(); i < size; ++i) { final ID indexId = affectedIndexCandidates.get(i); - if (!getInputFilter(indexId).acceptInput(file)) continue; - IndexingStamp.State state = isMock(file) ? IndexingStamp.State.FILE_CONTENT_CHANGED : getIndexingState(file, indexId); - if (state != IndexingStamp.State.INDEXED) { + if (shouldIndexFile(file, indexId)) { if (fc == null) { byte[] currentBytes; try { @@ -1731,7 +1729,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { ProgressManager.checkCanceled(); - updateSingleIndex(indexId, file, fc, state == IndexingStamp.State.FILE_CONTENT_CHANGED); + updateSingleIndex(indexId, file, fc); } catch (ProcessCanceledException e) { cleanFileContent(fc, psiFile); @@ -1779,7 +1777,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { fc.putUserData(IndexingDataKeys.PROJECT, project); } - private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC, boolean merge) + private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC) throws StorageException { if (ourRebuildStatus.get(indexId).get() == REQUIRES_REBUILD) { return; // the index is scheduled for rebuild, no need to update @@ -1791,7 +1789,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { assert index != null; // important: no hard referencing currentFC to avoid OOME, the methods introduced for this purpose! - final Computable update = index.update(inputId, currentFC, merge); + final Computable update = index.update(inputId, currentFC); final FileType fileType = file.getFileType(); scheduleUpdate(indexId, @@ -1977,7 +1975,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { if (fileContent == null) { fileContent = new FileContentImpl(file); } - updateSingleIndex(indexId, file, fileContent, true); + updateSingleIndex(indexId, file, fileContent); } catch (StorageException e) { LOG.info(e); @@ -2000,7 +1998,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { final ID indexId = candidates.get(i); if (needsFileContentLoading(indexId) && getInputFilter(indexId).acceptInput(file)) { ID id = IndexInfrastructure.getStubId(indexId, fileType); - if (IndexingStamp.getIndexingState(file, id) != IndexingStamp.State.INDEXED) { + if (IndexingStamp.isFileIndexed(file, id, IndexInfrastructure.getIndexCreationStamp(id))) { IndexingStamp.update(file, id, IndexInfrastructure.INVALID_STAMP2); resetStamp = true; } @@ -2068,7 +2066,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { if (!needsFileContentLoading(indexId)) { if (shouldUpdateIndex(file, indexId)) { - updateSingleIndex(indexId, file, null, true); // todo: set merge to false? + updateSingleIndex(indexId, file, null); } } else { // the index requires file content @@ -2132,7 +2130,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { Throwable unexpectedError = null; for (ID indexId : affectedIndices) { try { - updateSingleIndex(indexId, file, null, true); // todo: set merge to false? + updateSingleIndex(indexId, file, null); } catch (StorageException e) { LOG.info(e); @@ -2400,7 +2398,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { if (fileContent == null) { fileContent = new FileContentImpl(file); } - updateSingleIndex(indexId, file, fileContent, true); + updateSingleIndex(indexId, file, fileContent); } catch (StorageException e) { LOG.info(e); @@ -2427,11 +2425,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - private static IndexingStamp.State getIndexingState(VirtualFile file, ID indexId) { - ID id = IndexInfrastructure.getStubId(indexId, file.getFileType()); - return IndexingStamp.getIndexingState(file, id); - } - private boolean shouldUpdateIndex(final VirtualFile file, final ID indexId) { return getInputFilter(indexId).acceptInput(file) && (isMock(file) || isFileIndexed(file, indexId)); @@ -2443,7 +2436,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { } private static boolean isFileIndexed(VirtualFile file, ID indexId) { - return getIndexingState(file, indexId) == IndexingStamp.State.INDEXED; + ID id = IndexInfrastructure.getStubId(indexId, file.getFileType()); + return IndexingStamp.isFileIndexed(file, id, IndexInfrastructure.getIndexCreationStamp(id)); } private static long getIndexCreationStamp(ID indexId, FileType fileType) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java index 27170ce020e2..8531bcf688eb 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java @@ -18,6 +18,7 @@ package com.intellij.util.indexing; import com.intellij.openapi.vfs.InvalidVirtualFileAccessException; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.openapi.vfs.newvfs.FileAttribute; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.util.containers.ConcurrentHashMap; @@ -57,7 +58,7 @@ public class IndexingStamp { if (id != null) { long stamp = IndexInfrastructure.getIndexCreationStamp(id); if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f); - myIndexStamps.put(id, stamp <= dominatingIndexStamp ? stamp : INDEX_VERSION_CHANGED_STAMP); + if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp); } } } @@ -125,20 +126,10 @@ public class IndexingStamp { private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap(); private static final int CAPACITY = 100; private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY); - private static final long INDEX_VERSION_CHANGED_STAMP = 1l; - public enum State { - INDEXED, INDEX_VERSION_CHANGED, FILE_CONTENT_CHANGED - } - - public static State getIndexingState(VirtualFile file, ID indexName) { + public static boolean isFileIndexed(VirtualFile file, ID indexName, final long indexCreationStamp) { try { - long stamp = getIndexStamp(file, indexName); - if (stamp == INDEX_VERSION_CHANGED_STAMP) { - return State.INDEX_VERSION_CHANGED; - } - long indexCreationStamp = IndexInfrastructure.getIndexCreationStamp(indexName); - return stamp == indexCreationStamp ? State.INDEXED : State.FILE_CONTENT_CHANGED; + return getIndexStamp(file, indexName) == indexCreationStamp; } catch (RuntimeException e) { final Throwable cause = e.getCause(); @@ -147,7 +138,7 @@ public class IndexingStamp { } } - return State.FILE_CONTENT_CHANGED; + return false; } public static long getIndexStamp(VirtualFile file, ID indexName) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java index 008aa3fd43a0..98b62a5b3ffc 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java @@ -202,7 +202,7 @@ public class MapReduceIndex implements UpdatableIndex update(final int inputId, @Nullable final Input content, final boolean merge) { + public final Computable update(final int inputId, @Nullable Input content) { assert myInputsIndex != null; final Map data = content != null ? myIndexer.map(content) : Collections.emptyMap(); @@ -224,7 +224,7 @@ public class MapReduceIndex implements UpdatableIndex oldKeys = myInputsIndex.get(inputId); return oldKeys == null? Collections.emptyList() : oldKeys; } - }, merge); + }); } catch (StorageException ex) { exRef.set(ex); } @@ -242,10 +242,7 @@ public class MapReduceIndex implements UpdatableIndex newData, - @NotNull Callable> oldKeysGetter, - boolean merge) throws StorageException { + protected void updateWithMap(final int inputId, @NotNull Map newData, @NotNull Callable> oldKeysGetter) throws StorageException { getWriteLock().lock(); try { try { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java index 78704703a0d1..51b2330ca36f 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableIndex.java @@ -17,8 +17,10 @@ package com.intellij.util.indexing; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.ThrowableComputable; import org.jetbrains.annotations.Nullable; +import java.util.concurrent.Callable; import java.util.concurrent.locks.Lock; /** @@ -31,10 +33,7 @@ public interface UpdatableIndex extends AbstractIndex update(int inputId, @Nullable Input content, boolean merge); + Computable update(int inputId, @Nullable Input content); Lock getReadLock(); From 0bc2bc65adec362018083821b51cf47d2cef1c5d Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Wed, 20 Nov 2013 15:36:02 +0400 Subject: [PATCH 16/30] Double sets property value for one change --- .../designer/propertyTable/PropertyTable.java | 16 ++++++++++++---- .../propertyTable/editors/BooleanEditor.java | 2 +- .../propertyTable/editors/TextEditor.java | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java index 3470d77047f1..7b3b22b6c756 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java @@ -308,7 +308,13 @@ public abstract class PropertyTable extends JBTable { } public void update(@NotNull List containers, @Nullable Property initialSelection) { - finishEditing(); + update(containers, initialSelection, true); + } + + private void update(@NotNull List containers, @Nullable Property initialSelection, boolean finishEditing) { + if (finishEditing) { + finishEditing(); + } if (mySkipUpdate) { return; @@ -316,7 +322,7 @@ public abstract class PropertyTable extends JBTable { mySkipUpdate = true; try { - if (isEditing()) { + if (finishEditing && isEditing()) { cellEditor.stopCellEditing(); } @@ -841,7 +847,7 @@ public abstract class PropertyTable extends JBTable { if (isSetValue) { if (property.needRefreshPropertyList() || needRefresh[0]) { - update(); + update(myContainers, null, false); } else { myModel.fireTableRowsUpdated(row, row); @@ -1107,7 +1113,9 @@ public abstract class PropertyTable extends JBTable { if (setValueAtRow(editingRow, value)) { if (!continueEditing) { - tableCellEditor.stopCellEditing(); + PropertyEditor editor = myProperties.get(editingRow).getEditor(); + editor.removePropertyEditorListener(myPropertyEditorListener); + removeEditor(); } } else if (closeEditorOnError) { diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java index 984eb245e62f..145f2a9e9b7d 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java @@ -40,7 +40,7 @@ public class BooleanEditor extends PropertyEditor { myCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { if (!myInsideChange) { - fireValueCommitted(true, false); + fireValueCommitted(false, true); } } }); diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java index 6dbe4057bc81..c6ddc0ae484a 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java @@ -40,7 +40,7 @@ public class TextEditor extends PropertyEditor { myTextField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - fireValueCommitted(true, false); + fireValueCommitted(true, true); } }); myTextField.getDocument().addDocumentListener( From 0c2e0b2f96ea29a38898d8a5012e8726a2e66353 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Nov 2013 15:39:14 +0400 Subject: [PATCH 17/30] read action --- .../intellij/psi/search/SearchRequestCollector.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java index f11b5fbf9b65..fef43be72ba5 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java +++ b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java @@ -16,6 +16,8 @@ package com.intellij.psi.search; import com.intellij.codeInsight.ContainerProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileSystemItem; @@ -82,9 +84,14 @@ public class SearchRequestCollector { searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), processor); } - private static String getContainerName(@NotNull PsiElement target) { - PsiElement container = getContainer(target); - return container instanceof PsiNamedElement ? ((PsiNamedElement)container).getName() : null; + private static String getContainerName(@NotNull final PsiElement target) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + PsiElement container = getContainer(target); + return container instanceof PsiNamedElement ? ((PsiNamedElement)container).getName() : null; + } + }); } private static PsiElement getContainer(@NotNull PsiElement refElement) { From 59ff22dc0554f199245cb86126c4f6ced8735583 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Nov 2013 13:47:02 +0400 Subject: [PATCH 18/30] disable 'mark directory as resource root' action for Flex modules (IDEA-114866) --- .../intellij/ide/projectView/actions/MarkSourceRootAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java index 08eabbb101f8..dca6d0599309 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java @@ -17,6 +17,7 @@ package com.intellij.ide.projectView.actions; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.SourceFolder; @@ -46,7 +47,7 @@ public class MarkSourceRootAction extends MarkRootActionBase { @Override protected boolean isEnabled(@NotNull RootsSelection selection, @NotNull Module module) { - if (selection.myHaveSelectedFilesUnderSourceRoots) { + if (!ModuleType.get(module).isSupportedRootType(myRootType) || selection.myHaveSelectedFilesUnderSourceRoots) { return false; } From 17c219c6f37f73af7984da9b15d94f80db139117 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Nov 2013 14:26:25 +0400 Subject: [PATCH 19/30] IDEA-115760: Spring: create class intentions should not create class in 'generated sources' roots --- .../codeInsight/daemon/quickFix/CreateClassOrPackageFix.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java index f29f21b42633..d3c4858ffc34 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java @@ -246,7 +246,9 @@ public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPs if (LOG.isDebugEnabled()) { LOG.debug("Package directory: " + directory); } - if (directory.isWritable() && scope.contains(directory.getVirtualFile())) { + VirtualFile virtualFile = directory.getVirtualFile(); + if (directory.isWritable() && scope.contains(virtualFile) + && !JavaProjectRootsUtil.isInGeneratedCode(virtualFile, psiManager.getProject())) { writableDirectoryList.add(directory); } } From dfb41991296722ab93807e3c837e4d6e234bfe50 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Nov 2013 14:54:45 +0400 Subject: [PATCH 20/30] IDEA-116708: Excluded library directories in jar: a) show what is excluded; b) allow to include them back --- .../src/com/intellij/openapi/vfs/VfsUtilCore.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index 68a9393f9d75..d594b7d993fb 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -88,7 +88,13 @@ public class VfsUtilCore { } public static boolean isEqualOrAncestor(@NotNull String ancestorUrl, @NotNull String fileUrl) { - return ancestorUrl.equals(fileUrl) || StringUtil.startsWithConcatenation(fileUrl, ancestorUrl, "/"); + if (ancestorUrl.equals(fileUrl)) return true; + if (StringUtil.endsWithChar(ancestorUrl, '/')) { + return fileUrl.startsWith(ancestorUrl); + } + else { + return StringUtil.startsWithConcatenation(fileUrl, ancestorUrl, "/"); + } } public static boolean isAncestor(@NotNull File ancestor, @NotNull File file, boolean strict) { From 76312cd15eb0dbe64ce6dab436cc97a3a203aeb7 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Nov 2013 15:00:01 +0400 Subject: [PATCH 21/30] IDEA-116713: Excluded library directories: it's possible to exclude the same directory twice --- .../configuration/libraryEditor/NewLibraryEditor.java | 11 ++++------- .../openapi/roots/impl/libraries/LibraryImpl.java | 5 ++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java index e94b4f5ca876..6183b8a27bd0 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java @@ -30,10 +30,7 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** * @author nik @@ -41,7 +38,7 @@ import java.util.List; public class NewLibraryEditor extends LibraryEditorBase { private String myLibraryName; private final MultiMap myRoots; - private final List myExcludedRoots; + private final Set myExcludedRoots; private final JarDirectories myJarDirectories = new JarDirectories(); private LibraryType myType; private LibraryProperties myProperties; @@ -54,7 +51,7 @@ public class NewLibraryEditor extends LibraryEditorBase { myType = type; myProperties = properties; myRoots = new MultiMap(); - myExcludedRoots = new ArrayList(); + myExcludedRoots = new LinkedHashSet(); } @Override @@ -94,7 +91,7 @@ public class NewLibraryEditor extends LibraryEditorBase { } private static String[] pointersToUrls(Collection pointers) { - List urls = new ArrayList(); + List urls = new ArrayList(pointers.size()); for (LightFilePointer pointer : pointers) { urls.add(pointer.getUrl()); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 954b254ae402..eb225e9a6912 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -379,7 +379,10 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi @Override public void addExcludedRoot(@NotNull String url) { - getOrCreateExcludedRoots().add(url); + VirtualFilePointerContainer roots = getOrCreateExcludedRoots(); + if (roots.findByUrl(url) == null) { + roots.add(url); + } } @Override From 278d4c879fe065d26dc960534bf879d983a68274 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Nov 2013 15:15:16 +0400 Subject: [PATCH 22/30] IDEA-116727: Excluded library directories: removing a root does not removes its excludes --- .../intellij/roots/libraries/LibraryTest.java | 73 ++++++++++++++----- .../roots/impl/libraries/LibraryImpl.java | 2 +- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java index 82e91fee8e33..e78308b4ae92 100644 --- a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java @@ -3,17 +3,19 @@ package com.intellij.roots.libraries; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; -import com.intellij.testFramework.IdeaTestCase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.roots.ModuleRootManagerTestCase; import org.jdom.Element; import org.jdom.output.XMLOutputter; /** * @author dsl */ -public class LibraryTest extends IdeaTestCase { +public class LibraryTest extends ModuleRootManagerTestCase { public void testModification() throws Exception { final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(); final Library library = libraryTable.createLibrary("NewLibrary"); @@ -25,27 +27,17 @@ public class LibraryTest extends IdeaTestCase { } }); - final Library.ModifiableModel modifyableModel = library.getModifiableModel(); - modifyableModel.addRoot("file://x.jar", OrderRootType.CLASSES); - modifyableModel.addRoot("file://x-src.jar", OrderRootType.SOURCES); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - modifyableModel.commit(); - } - }); + final Library.ModifiableModel model1 = library.getModifiableModel(); + model1.addRoot("file://x.jar", OrderRootType.CLASSES); + model1.addRoot("file://x-src.jar", OrderRootType.SOURCES); + commit(model1); assertTrue(listenerNotifiedOnChange[0]); listenerNotifiedOnChange[0] = false; - final Library.ModifiableModel modifyableModel1 = library.getModifiableModel(); - modifyableModel1.setName("library"); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - modifyableModel1.commit(); - } - }); + final Library.ModifiableModel model2 = library.getModifiableModel(); + model2.setName("library"); + commit(model2); assertFalse(listenerNotifiedOnChange[0]); final Element element = new Element("root"); @@ -60,4 +52,47 @@ public class LibraryTest extends IdeaTestCase { } }); } + + public void testAddRemoveExcludedRoot() { + VirtualFile jar = getJDomJar(); + LibraryEx library = (LibraryEx)createLibrary("junit", jar, null); + assertEmpty(library.getExcludedRoots()); + + LibraryEx.ModifiableModelEx model = library.getModifiableModel(); + model.addExcludedRoot(jar.getUrl()); + commit(model); + assertOrderedEquals(library.getExcludedRoots(), jar); + + LibraryEx.ModifiableModelEx model2 = library.getModifiableModel(); + model2.removeExcludedRoot(jar.getUrl()); + commit(model2); + assertEmpty(library.getExcludedRoots()); + } + + public void testRemoveExcludedRootWhenParentRootIsRemoved() { + VirtualFile jar = getJDomJar(); + LibraryEx library = (LibraryEx)createLibrary("junit", jar, null); + + LibraryEx.ModifiableModelEx model = library.getModifiableModel(); + VirtualFile excluded = jar.findChild("org"); + assertNotNull(excluded); + model.addExcludedRoot(excluded.getUrl()); + commit(model); + + assertOrderedEquals(library.getExcludedRoots(), excluded); + LibraryEx.ModifiableModelEx model2 = library.getModifiableModel(); + model2.removeRoot(jar.getUrl(), OrderRootType.CLASSES); + commit(model2); + + assertEmpty(library.getExcludedRoots()); + } + + private static void commit(final Library.ModifiableModel modifyableModel1) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + modifyableModel1.commit(); + } + }); + } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index eb225e9a6912..5bcb04f89955 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -495,7 +495,7 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi if (myExcludedRoots != null) { for (String excludedRoot : myExcludedRoots.getUrls()) { if (!isUnderRoots(excludedRoot)) { - VirtualFilePointer pointer = myExcludedRoots.findByUrl(url); + VirtualFilePointer pointer = myExcludedRoots.findByUrl(excludedRoot); if (pointer != null) { myExcludedRoots.remove(pointer); } From 4cfe198d3f9e532cde8bbead2cc6bd423acabc36 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 20 Nov 2013 16:26:36 +0400 Subject: [PATCH 23/30] fixed PY-11394 "no tests were found" with django 1.6 DiscoverRunner --- .../python/testing/PythonTestCommandLineStateBase.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java index ef16a65a7658..39e4e96b836b 100644 --- a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java +++ b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java @@ -106,9 +106,10 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt return cmd; } - private void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) { - if (!StringUtil.isEmptyOrSpaces(myConfiguration.getWorkingDirectory())) { - cmd.setWorkDirectory(myConfiguration.getWorkingDirectory()); + protected void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) { + final String workingDirectory = myConfiguration.getWorkingDirectory(); + if (!StringUtil.isEmptyOrSpaces(workingDirectory)) { + cmd.setWorkDirectory(workingDirectory); } else if (myConfiguration instanceof AbstractPythonTestRunConfiguration) { final String folderName = ((AbstractPythonTestRunConfiguration)myConfiguration).getFolderName(); From 0f79597ae1c66c607287a7223617bffb82f27132 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 20 Nov 2013 13:25:34 +0100 Subject: [PATCH 24/30] IDEA-116731 IntelliJ theme: Database Connections dialog: Scope combobox is too narrow IDEA-116768 IntelliJ theme: text end is too close to combobox button (cherry picked from commit 426f2cc934176472c4aaeb552fc1f8a57476e474) --- .../ui/laf/darcula/ui/DarculaComboBoxUI.java | 71 ++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index 87a260d3688e..39fcc8f76445 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -20,6 +20,7 @@ import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.util.ui.UIUtil; +import sun.swing.DefaultLookup; import javax.swing.*; import javax.swing.border.Border; @@ -27,7 +28,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.DimensionUIResource; import javax.swing.plaf.InsetsUIResource; import javax.swing.plaf.basic.BasicArrowButton; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import javax.swing.plaf.basic.BasicComboBoxUI; import java.awt.*; import java.awt.event.FocusAdapter; @@ -66,25 +66,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { myPadding = UIManager.getInsets("ComboBox.padding"); } - @Override - protected ListCellRenderer createRenderer() { - return new BasicComboBoxRenderer.UIResource() { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (c instanceof JComponent) { - final JComponent jc = (JComponent)c; - if (index == -1) { - jc.setOpaque(false); - jc.setForeground(list.getForeground()); - } else { - jc.setOpaque(true); - } - } - return c; - } - }; - } protected JButton createArrowButton() { final Color bg = myComboBox.getBackground(); @@ -144,10 +125,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { } protected Dimension getDisplaySize() { - if (!myDisplaySizeDirty) { - return new Dimension(myDisplaySizeCache); - } - Dimension display = new Dimension(); ListCellRenderer renderer = comboBox.getRenderer(); @@ -214,7 +191,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { return d; } - @Override public void paint(Graphics g, JComponent c) { final Container parent = c.getParent(); @@ -229,6 +205,51 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { paintCurrentValue(g, r, hasFocus); } + public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) { + ListCellRenderer renderer = comboBox.getRenderer(); + Component c; + + if (hasFocus && !isPopupVisible(comboBox)) { + c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false); + } + else { + c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false); + c.setBackground(UIManager.getColor("ComboBox.background")); + } + c.setFont(comboBox.getFont()); + if (hasFocus && !isPopupVisible(comboBox)) { + c.setForeground(listBox.getForeground()); + c.setBackground(listBox.getBackground()); + } + else { + if (comboBox.isEnabled()) { + c.setForeground(comboBox.getForeground()); + c.setBackground(comboBox.getBackground()); + } + else { + c.setForeground(DefaultLookup.getColor( + comboBox, this, "ComboBox.disabledForeground", null)); + c.setBackground(DefaultLookup.getColor( + comboBox, this, "ComboBox.disabledBackground", null)); + } + } + + boolean shouldValidate = false; + if (c instanceof JPanel) { + shouldValidate = true; + } + + Rectangle r = new Rectangle(bounds); + if (myPadding != null) { + r.x += myPadding.left; + r.y += myPadding.top; + r.width -= myPadding.left + myPadding.right; + r.height -= myPadding.top + myPadding.bottom; + } + + currentValuePane.paintComponent(g, c, comboBox, r.x-2, r.y, r.width, r.height, shouldValidate); + } + @Override protected void installKeyboardActions() { super.installKeyboardActions(); From 7459a38ba1c4436985346e4ec9fa57fff97fca7f Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Wed, 20 Nov 2013 16:39:27 +0400 Subject: [PATCH 25/30] avoid using WolfTheProblemSolver.hasSyntaxErrors is possible, because it isn't designed to be a public API --- .../execution/DelayedDocumentWatcher.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 4951dc814179..977efe24eb85 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -29,6 +29,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.problems.WolfTheProblemSolver; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Alarm; import com.intellij.util.Consumer; import com.intellij.util.messages.MessageBusConnection; @@ -128,9 +131,9 @@ public class DelayedDocumentWatcher { private class MyRunnable implements Runnable { @Override public void run() { - WolfTheProblemSolver problemSolver = WolfTheProblemSolver.getInstance(myProject); for (VirtualFile file : myChangedFiles) { - if (problemSolver.hasSyntaxErrors(file)) { + boolean hasErrors = hasErrors(file); + if (hasErrors) { // Do nothing, if some changed file has syntax errors. // This method will be invoked subsequently, when syntax errors are fixed. return; @@ -142,4 +145,16 @@ public class DelayedDocumentWatcher { } } + private boolean hasErrors(@NotNull VirtualFile file) { + // don't use 'WolfTheProblemSolver.hasSyntaxErrors(file)' if possible + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if (psiFile != null) { + return PsiTreeUtil.hasErrorElements(psiFile); + } + } + return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file); + } + } From d9a30c652089cc403ba9fba79556eccc5368a931 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Nov 2013 14:17:22 +0100 Subject: [PATCH 26/30] platform: detect case-only name changes in case-insensitive FS only --- .../vfs/newvfs/persistent/RefreshWorker.java | 16 ++++++++++------ .../util/text/FilePathHashingStrategy.java | 13 ++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 0178a8168347..6dfe3082fd57 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -32,6 +32,8 @@ import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.OpenTHashSet; import com.intellij.util.containers.Queue; +import com.intellij.util.text.FilePathHashingStrategy; +import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,6 +94,8 @@ public class RefreshWorker { } private void processQueue(NewVirtualFileSystem fs, PersistentFS persistence) throws RefreshCancelledException { + TObjectHashingStrategy strategy = FilePathHashingStrategy.create(fs.isCaseSensitive()); + while (!myRefreshQueue.isEmpty()) { checkCancelled(); @@ -120,13 +124,13 @@ public class RefreshWorker { if (fullSync) { String[] currentNames = persistence.list(file); String[] upToDateNames = VfsUtil.filterNames(fs.list(file)); - Set newNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, upToDateNames); + Set newNames = newTroveSet(strategy, upToDateNames); ContainerUtil.removeAll(newNames, currentNames); - Set deletedNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, currentNames); + Set deletedNames = newTroveSet(strategy, currentNames); ContainerUtil.removeAll(deletedNames, upToDateNames); OpenTHashSet actualNames = null; - if (!SystemInfo.isFileSystemCaseSensitive) { - actualNames = new OpenTHashSet(FileUtil.PATH_HASHING_STRATEGY, upToDateNames); + if (!fs.isCaseSensitive()) { + actualNames = new OpenTHashSet(strategy, upToDateNames); } debug(LOG, "current=%s +%s -%s", currentNames, newNames, deletedNames); @@ -163,8 +167,8 @@ public class RefreshWorker { else { Collection cachedChildren = file.getCachedChildren(); OpenTHashSet actualNames = null; - if (!SystemInfo.isFileSystemCaseSensitive) { - actualNames = new OpenTHashSet(FileUtil.PATH_HASHING_STRATEGY, VfsUtil.filterNames(fs.list(file))); + if (!fs.isCaseSensitive()) { + actualNames = new OpenTHashSet(strategy, VfsUtil.filterNames(fs.list(file))); } debug(LOG, "cached=%s actual=%s", cachedChildren, actualNames); diff --git a/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java b/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java index b91b718295eb..bad768477e58 100644 --- a/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java +++ b/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.text; import com.intellij.openapi.util.SystemInfo; @@ -25,11 +24,15 @@ import org.jetbrains.annotations.NotNull; * @author max */ public class FilePathHashingStrategy { - private FilePathHashingStrategy() { - } + private FilePathHashingStrategy() { } @NotNull public static TObjectHashingStrategy create() { - return SystemInfo.isFileSystemCaseSensitive ? ContainerUtil.canonicalStrategy() : new CaseInsensitiveStringHashingStrategy(); + return create(SystemInfo.isFileSystemCaseSensitive); + } + + @NotNull + public static TObjectHashingStrategy create(boolean caseSensitive) { + return caseSensitive ? ContainerUtil.canonicalStrategy() : new CaseInsensitiveStringHashingStrategy(); } } From 148ca983580c22edeb708c03c0c4be7eed4ef0cd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 20 Nov 2013 15:15:05 +0100 Subject: [PATCH 27/30] EA-52004 (NPE: CyclicClassDependencyInspection.checkElement) --- .../src/com/intellij/codeInspection/reference/RefClass.java | 4 +++- .../com/intellij/codeInspection/reference/RefClassImpl.java | 1 + .../ig/dependency/CyclicClassDependencyInspection.java | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java index da8a04fe7b7f..3e9044ec5eaf 100644 --- a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java +++ b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -17,6 +17,7 @@ package com.intellij.codeInspection.reference; import com.intellij.psi.PsiClass; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; @@ -65,6 +66,7 @@ public interface RefClass extends RefJavaElement { boolean isSelfInheritor(PsiClass psiClass); + @Nullable @Override PsiClass getElement(); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java index 17416a0b99de..1e2aee542e7f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java @@ -211,6 +211,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { return isSelfInheritor(psiClass, new ArrayList()); } + @Nullable @Override public PsiClass getElement() { return (PsiClass)super.getElement(); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java index 51a5a1a01d7a..355d5933d511 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class CyclicClassDependencyInspection extends BaseGlobalInspection { } final RefClass refClass = (RefClass)refEntity; final PsiClass aClass = refClass.getElement(); - if (aClass.getContainingClass() != null) { + if (aClass == null || aClass.getContainingClass() != null) { return null; } final Set dependencies = @@ -67,7 +67,7 @@ public class CyclicClassDependencyInspection extends BaseGlobalInspection { } final String errorString = InspectionGadgetsBundle.message( "cyclic.class.dependency.problem.descriptor", - refEntity.getName(), numMutualDependents - 1); + refEntity.getName(), Integer.valueOf(numMutualDependents - 1)); return new CommonProblemDescriptor[]{ inspectionManager.createProblemDescriptor(errorString) }; From b2f25d894fc7a0a5e3a21f475b19ea91e1cf2ea7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 20 Nov 2013 15:30:49 +0100 Subject: [PATCH 28/30] remove unnecessary setting --- .../migration/MethodCanBeVariableArityMethodInspection.java | 6 +----- .../MethodCanBeVariableArityMethodInspectionTest.java | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java index d6282386f5b4..7777d874c4ea 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java @@ -39,9 +39,6 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { @SuppressWarnings("PublicField") public boolean ignoreOverridingMethods = false; - @SuppressWarnings("PublicField") - public boolean ignoreNullableParameters = true; - @Nls @NotNull @Override @@ -61,7 +58,6 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { panel.addCheckbox(InspectionGadgetsBundle.message("method.can.be.variable.arity.method.ignore.byte.short.option"), "ignoreByteAndShortArrayParameters"); panel.addCheckbox(InspectionGadgetsBundle.message("ignore.methods.overriding.super.method"), "ignoreOverridingMethods"); - panel.addCheckbox(InspectionGadgetsBundle.message("ignore.nullable.parameters.option"), "ignoreNullableParameters"); return panel; } @@ -89,7 +85,7 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { } final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter lastParameter = parameters[parameters.length - 1]; - if (ignoreNullableParameters && NullableNotNullManager.isNullable(lastParameter)) { + if (NullableNotNullManager.isNullable(lastParameter)) { return; } final PsiType type = lastParameter.getType(); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java index d6fbed29e2e9..a54bd64d3b47 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java @@ -8,7 +8,6 @@ public class MethodCanBeVariableArityMethodInspectionTest extends IGInspectionTe final MethodCanBeVariableArityMethodInspection tool = new MethodCanBeVariableArityMethodInspection(); tool.ignoreByteAndShortArrayParameters = true; tool.ignoreOverridingMethods = true; - tool.ignoreNullableParameters = true; doTest("com/siyeh/igtest/migration/method_can_be_variable_arity_method", tool); } } \ No newline at end of file From d878e933a78acbe267b574b4a99382163b078684 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Wed, 20 Nov 2013 18:32:28 +0400 Subject: [PATCH 29/30] read access --- .../com/intellij/execution/DelayedDocumentWatcher.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 977efe24eb85..cfc84f4224d3 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -26,6 +26,7 @@ import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.problems.WolfTheProblemSolver; @@ -149,9 +150,14 @@ public class DelayedDocumentWatcher { // don't use 'WolfTheProblemSolver.hasSyntaxErrors(file)' if possible Document document = FileDocumentManager.getInstance().getDocument(file); if (document != null) { - PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); if (psiFile != null) { - return PsiTreeUtil.hasErrorElements(psiFile); + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public Boolean compute() { + return PsiTreeUtil.hasErrorElements(psiFile); + } + }); } } return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file); From eeba3546242029497e1d63191be72cfb77d3f54b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 20 Nov 2013 15:46:38 +0100 Subject: [PATCH 30/30] simplify visitors --- .../ig/errorhandling/ErrorRethrownInspection.java | 15 ++++----------- .../ThreadDeathRethrownInspection.java | 15 ++++----------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java index 793ad82b4e2f..2310d5380405 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java @@ -51,20 +51,13 @@ public class ErrorRethrownInspection extends BaseInspection { private static class ErrorRethrownVisitor extends BaseInspectionVisitor { @Override - public void visitTryStatement(@NotNull PsiTryStatement statement) { - super.visitTryStatement(statement); - final PsiCatchSection[] catchSections = statement.getCatchSections(); - for (PsiCatchSection catchSection : catchSections) { - checkCatchSection(catchSection); - } - } - - private void checkCatchSection(PsiCatchSection catchSection) { - final PsiParameter parameter = catchSection.getParameter(); + public void visitCatchSection(PsiCatchSection section) { + super.visitCatchSection(section); + final PsiParameter parameter = section.getParameter(); if (parameter == null) { return; } - final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); + final PsiCodeBlock catchBlock = section.getCatchBlock(); if (catchBlock == null) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java index a79b5b2f9e73..130ace79f489 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java @@ -51,20 +51,13 @@ public class ThreadDeathRethrownInspection extends BaseInspection { private static class ThreadDeathRethrownVisitor extends BaseInspectionVisitor { @Override - public void visitTryStatement(@NotNull PsiTryStatement statement) { - super.visitTryStatement(statement); - final PsiCatchSection[] catchSections = statement.getCatchSections(); - for (PsiCatchSection catchSection : catchSections) { - checkCatchSection(catchSection); - } - } - - private void checkCatchSection(PsiCatchSection catchSection) { - final PsiParameter parameter = catchSection.getParameter(); + public void visitCatchSection(PsiCatchSection section) { + super.visitCatchSection(section); + final PsiParameter parameter = section.getParameter(); if (parameter == null) { return; } - final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); + final PsiCodeBlock catchBlock = section.getCatchBlock(); if (catchBlock == null) { return; }