diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java
index b60b7bd85e19..c9f9b9bb8a09 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java
@@ -121,6 +121,7 @@ public interface RegExpTT {
ESC_CTRL_CHARACTER,
ESC_CHARACTER,
CTRL_CHARACTER,
+ CTRL,
UNICODE_CHAR,
HEX_CHAR, BAD_HEX_VALUE,
OCT_CHAR, BAD_OCT_VALUE,
diff --git a/RegExpSupport/testData/RETest.xml b/RegExpSupport/testData/RETest.xml
index 696057dc5826..10e04dcf80fa 100644
--- a/RegExpSupport/testData/RETest.xml
+++ b/RegExpSupport/testData/RETest.xml
@@ -603,6 +603,10 @@
\Q\j\E
OK
+
+ \c0
+ OK
+
diff --git a/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java b/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java
index 345383ea0326..0847c5412e54 100644
--- a/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java
+++ b/java/java-impl/src/com/intellij/codeEditor/JavaEditorFileSwapper.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.fileEditor.impl.EditorFileSwapper;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -66,7 +67,7 @@ public class JavaEditorFileSwapper extends EditorFileSwapper {
if (member != null) {
PsiElement navigationElement = member.getNavigationElement();
- if (navigationElement.getContainingFile().getVirtualFile() == sourceFile) {
+ if (Comparing.equal(navigationElement.getContainingFile().getVirtualFile(), sourceFile)) {
position = navigationElement.getTextOffset();
}
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
index 89a0bc7e0443..8b73ad6dd4ca 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
@@ -143,7 +143,7 @@ public class PostHighlightingPass extends TextEditorHighlightingPass {
myInLibrary = fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile);
myRefCountHolder = RefCountHolder.endUsing(myFile);
- if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo(new Runnable() {
+ if (myRefCountHolder == null || !myRefCountHolder.retrieveUnusedReferencesInfo((DaemonProgressIndicator)progress, new Runnable() {
@Override
public void run() {
boolean errorFound = collectHighlights(elementSet, highlights, progress);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
index 6f1260d77dd6..b763e4e6c9a8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
@@ -47,14 +47,9 @@ public class RefCountHolder {
private final Map myDclsUsedMap = new ConcurrentHashMap();
private final Map myImportStatements = new ConcurrentHashMap();
private final Map myPossiblyDuplicateElements = new ConcurrentHashMap();
- private final AtomicReference myState = new AtomicReference(State.VIRGIN);
-
- private enum State {
- VIRGIN, // just created or cleared
- BEING_WRITTEN_BY_GHP, // general highlighting pass is storing references during analysis
- READY, // may be used for highlighting unused stuff
- BEING_USED_BY_PHP, // post highlighting pass is retrieving info
- }
+ private final AtomicReference myState = new AtomicReference(VIRGIN);
+ private static final DaemonProgressIndicator VIRGIN = new DaemonProgressIndicator(); // just created or cleared
+ private static final DaemonProgressIndicator READY = new DaemonProgressIndicator();
private static class HolderReference extends SoftReference {
@SuppressWarnings("UnusedDeclaration")
@@ -122,20 +117,19 @@ public class RefCountHolder {
}
private void clear() {
- assertIsAnalyzing();
- myLocalRefsMap.clear();
+ synchronized (myLocalRefsMap) {
+ myLocalRefsMap.clear();
+ }
myImportStatements.clear();
myDclsUsedMap.clear();
myPossiblyDuplicateElements.clear();
}
public void registerLocallyReferenced(@NotNull PsiNamedElement result) {
- assertIsAnalyzing();
myDclsUsedMap.put(result,Boolean.TRUE);
}
public void registerReference(@NotNull PsiJavaReference ref, @NotNull JavaResolveResult resolveResult) {
- assertIsAnalyzing();
PsiElement refElement = resolveResult.getElement();
PsiFile psiFile = refElement == null ? null : refElement.getContainingFile();
if (psiFile != null) psiFile = (PsiFile)psiFile.getNavigationElement(); // look at navigation elements because all references resolve into Cls elements when highlighting library source
@@ -154,7 +148,6 @@ public class RefCountHolder {
}
public boolean isRedundant(@NotNull PsiImportStatementBase importStatement) {
- assertIsRetrieving();
return !myImportStatements.containsValue(importStatement);
}
@@ -167,7 +160,6 @@ public class RefCountHolder {
}
private void removeInvalidRefs() {
- assertIsAnalyzing();
synchronized (myLocalRefsMap) {
for(Iterator iterator = myLocalRefsMap.keySet().iterator(); iterator.hasNext();){
PsiReference ref = iterator.next();
@@ -197,8 +189,10 @@ public class RefCountHolder {
}
public boolean isReferenced(PsiNamedElement element) {
- assertIsRetrieving();
- List array = myLocalRefsMap.getKeysByValue(element);
+ List array;
+ synchronized (myLocalRefsMap) {
+ array = myLocalRefsMap.getKeysByValue(element);
+ }
if (array != null && !array.isEmpty() && !isParameterUsedRecursively(element, array)) return true;
Boolean usedStatus = myDclsUsedMap.get(element);
@@ -235,9 +229,11 @@ public class RefCountHolder {
}
public boolean isReferencedForRead(@NotNull PsiElement element) {
- assertIsRetrieving();
LOG.assertTrue(element instanceof PsiVariable);
- List array = myLocalRefsMap.getKeysByValue(element);
+ List array;
+ synchronized (myLocalRefsMap) {
+ array = myLocalRefsMap.getKeysByValue(element);
+ }
if (array == null) return false;
for (PsiReference ref : array) {
PsiElement refElement = ref.getElement();
@@ -257,9 +253,11 @@ public class RefCountHolder {
}
public boolean isReferencedForWrite(@NotNull PsiElement element) {
- assertIsRetrieving();
LOG.assertTrue(element instanceof PsiVariable);
- List array = myLocalRefsMap.getKeysByValue(element);
+ List array;
+ synchronized (myLocalRefsMap) {
+ array = myLocalRefsMap.getKeysByValue(element);
+ }
if (array == null) return false;
for (PsiReference ref : array) {
final PsiElement refElement = ref.getElement();
@@ -273,14 +271,14 @@ public class RefCountHolder {
return false;
}
- public boolean analyze(@NotNull PsiFile file, TextRange dirtyScope, @NotNull Runnable analyze) {
- State old = myState.get();
- myState.compareAndSet(State.READY, State.VIRGIN);
- if (!myState.compareAndSet(State.VIRGIN, State.BEING_WRITTEN_BY_GHP)) {
- log("a: failed to change " + old + "->" + State.BEING_WRITTEN_BY_GHP);
+ public boolean analyze(@NotNull PsiFile file, TextRange dirtyScope, @NotNull Runnable analyze, @NotNull DaemonProgressIndicator indicator) {
+ DaemonProgressIndicator old = myState.get();
+ if (old != VIRGIN && old != READY) return false;
+ if (!myState.compareAndSet(old, indicator)) {
+ log("a: failed to change " + old + "->" + indicator);
return false;
}
- log("a: changed " + old + "->" + State.BEING_WRITTEN_BY_GHP);
+ log("a: changed " + old + "->" + indicator);
boolean finished = false;
try {
if (dirtyScope != null) {
@@ -296,9 +294,9 @@ public class RefCountHolder {
finished = true;
}
finally {
- boolean set = myState.compareAndSet(State.BEING_WRITTEN_BY_GHP, finished ? State.READY : State.VIRGIN);
+ boolean set = myState.compareAndSet(indicator, finished ? READY : VIRGIN);
assert set : myState.get();
- log("a: changed back " + State.BEING_WRITTEN_BY_GHP + "->" + (finished ? State.READY : State.VIRGIN));
+ log("a: changed back " + indicator + "->" + (finished ? READY : VIRGIN));
}
return true;
}
@@ -307,31 +305,21 @@ public class RefCountHolder {
//System.err.println("RFC: "+s);
}
- public boolean retrieveUnusedReferencesInfo(@NotNull Runnable analyze) {
- State old = myState.get();
- if (!myState.compareAndSet(State.READY, State.BEING_USED_BY_PHP)) {
- log("r: failed to change " + old + "->" + State.BEING_USED_BY_PHP);
+ public boolean retrieveUnusedReferencesInfo(@NotNull DaemonProgressIndicator indicator, @NotNull Runnable analyze) {
+ DaemonProgressIndicator old = myState.get();
+ if (!myState.compareAndSet(READY, indicator)) {
+ log("r: failed to change " + old + "->" + indicator);
return false;
}
- log("r: changed " + old + "->" + State.BEING_USED_BY_PHP);
+ log("r: changed " + old + "->" + indicator);
try {
analyze.run();
}
finally {
- boolean set = myState.compareAndSet(State.BEING_USED_BY_PHP, State.READY);
+ boolean set = myState.compareAndSet(indicator, READY);
assert set : myState.get();
- log("r: changed back " + State.BEING_USED_BY_PHP + "->" + State.READY);
+ log("r: changed back " + indicator + "->" + READY);
}
return true;
}
-
- private void assertIsAnalyzing() {
- State state = myState.get();
- assert state == State.BEING_WRITTEN_BY_GHP : state;
- }
- private void assertIsRetrieving() {
- State state = myState.get();
- assert state == State.BEING_USED_BY_PHP : state;
- }
-
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index e1b1cbed1f8a..6924f7ab438c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -24,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.SetupJDKFix;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.IndexNotReadyException;
@@ -131,7 +132,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
myRefCountHolder = refCountHolder;
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
TextRange dirtyScope = document == null ? file.getTextRange() : fileStatusMap.getFileDirtyScope(document, Pass.UPDATE_ALL);
- success = refCountHolder.analyze(file, dirtyScope, action);
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ success = indicator instanceof DaemonProgressIndicator && refCountHolder.analyze(file, dirtyScope, action, (DaemonProgressIndicator)indicator);
}
else {
myRefCountHolder = null;
diff --git a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java
index 723be0258738..14291be2775d 100644
--- a/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java
+++ b/java/java-impl/src/com/intellij/ide/favoritesTreeView/PsiClassFavoriteNodeProvider.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
@@ -77,7 +78,7 @@ public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider {
public boolean elementContainsFile(final Object element, final VirtualFile vFile) {
if (element instanceof PsiClass) {
final PsiFile file = ((PsiClass)element).getContainingFile();
- if (file != null && file.getVirtualFile() == vFile) return true;
+ if (file != null && Comparing.equal(file.getVirtualFile(), vFile)) return true;
}
return false;
}
diff --git a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
index dca26c3a8b7c..7dfb138567b4 100644
--- a/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
+++ b/java/java-impl/src/com/intellij/openapi/roots/impl/ExcludeCompilerOutputPolicy.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.CompilerProjectExtension;
import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.util.io.FileUtil;
@@ -53,7 +54,8 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy
@Override
public boolean isExcludeRootForModule(final Module module, final VirtualFile excludeRoot) {
final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
- return compilerModuleExtension.getCompilerOutputPath() == excludeRoot || compilerModuleExtension.getCompilerOutputPathForTests() == excludeRoot;
+ return Comparing.equal(compilerModuleExtension.getCompilerOutputPath(), excludeRoot) ||
+ Comparing.equal(compilerModuleExtension.getCompilerOutputPathForTests(), excludeRoot);
}
@Override
@@ -87,7 +89,7 @@ public class ExcludeCompilerOutputPolicy implements DirectoryIndexExcludePolicy
private static boolean isEqualWithFileOrUrl(VirtualFile f, VirtualFile fileToCompareWith, String url) {
if (fileToCompareWith != null) {
- if (fileToCompareWith == f) return true;
+ if (Comparing.equal(fileToCompareWith, f)) return true;
}
else if (url != null) {
if (FileUtil.pathsEqual(url, f.getUrl())) return true;
diff --git a/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java b/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java
index cae9eb2b3df5..e11d03a93de4 100644
--- a/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java
+++ b/java/java-impl/src/com/intellij/packageDependencies/ui/TreeModelBuilder.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.LibraryUtil;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
@@ -172,7 +173,7 @@ public class TreeModelBuilder {
VirtualFile dir = null;
public boolean processFile(VirtualFile fileOrDir) {
if (!fileOrDir.isDirectory()) {
- if (lastParent != null && dir != fileOrDir.getParent()) {
+ if (lastParent != null && !Comparing.equal(dir, fileOrDir.getParent())) {
lastParent = null;
}
lastParent = buildFileNode(fileOrDir, lastParent);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
index 674b6b16fe65..0fdb5959f16c 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/JavaExtractSuperBaseDialog.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.vfs.VirtualFile;
@@ -111,7 +112,7 @@ public abstract class JavaExtractSuperBaseDialog extends ExtractSuperBaseDialog<
final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(sourceFile);
if (sourceRoot != null) {
for (PsiDirectory dir : directories) {
- if (fileIndex.getSourceRootForFile(dir.getVirtualFile()) == sourceRoot) {
+ if (Comparing.equal(fileIndex.getSourceRootForFile(dir.getVirtualFile()), sourceRoot)) {
return dir;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java
index 23feeb46c4a0..50c2c5fe1448 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/DestinationFolderComboBox.java
@@ -15,6 +15,8 @@
*/
package com.intellij.refactoring.move.moveClassesOrPackages;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ide.util.DirectoryChooser;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -122,7 +124,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
final ComboBoxModel model = getComboBox().getModel();
for (int i = 0; i < model.getSize(); i++) {
DirectoryChooser.ItemWrapper item = (DirectoryChooser.ItemWrapper)model.getElementAt(i);
- if (item != NULL_WRAPPER && fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()) == root) {
+ if (item != NULL_WRAPPER && Comparing.equal(fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()), root)) {
getComboBox().setSelectedItem(item);
getComboBox().repaint();
return;
@@ -164,7 +166,9 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
}
final PsiDirectory selectedPsiDirectory = selectedItem.getDirectory();
VirtualFile selectedDestination = selectedPsiDirectory.getVirtualFile();
- if (showChooserWhenDefault && selectedDestination == myInitialTargetDirectory.getVirtualFile() && mySourceRoots.length > 1) {
+ if (showChooserWhenDefault &&
+ Comparing.equal(selectedDestination, myInitialTargetDirectory.getVirtualFile()) &&
+ mySourceRoots.length > 1) {
selectedDestination = MoveClassesOrPackagesUtil.chooseSourceRoot(targetPackage, mySourceRoots, myInitialTargetDirectory);
}
if (selectedDestination == null) return null;
@@ -211,9 +215,10 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
DirectoryChooser.ItemWrapper itemWrapper = new DirectoryChooser.ItemWrapper(targetDirectory, pathsToCreate.get(targetDirectory));
items.add(itemWrapper);
final VirtualFile sourceRootForFile = fileIndex.getSourceRootForFile(targetDirectory.getVirtualFile());
- if (sourceRootForFile == initialTargetDirectorySourceRoot) {
+ if (Comparing.equal(sourceRootForFile, initialTargetDirectorySourceRoot)) {
initial = itemWrapper;
- } else if (sourceRootForFile == oldSelection) {
+ }
+ else if (Comparing.equal(sourceRootForFile, oldSelection)) {
oldOne = itemWrapper;
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
index 1d4afb77e665..901cac555ffb 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java
@@ -205,7 +205,7 @@ public class MoveInnerDialog extends RefactoringDialog {
final PsiDirectory[] directories = oldPackage.getDirectories();
final VirtualFile root = projectRootManager.getFileIndex().getContentRootForFile(psiDirectory.getVirtualFile());
for(PsiDirectory dir: directories) {
- if (projectRootManager.getFileIndex().getContentRootForFile(dir.getVirtualFile()) == root) {
+ if (Comparing.equal(projectRootManager.getFileIndex().getContentRootForFile(dir.getVirtualFile()), root)) {
initialDir = dir;
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java
index 3bb06f50eee1..2c4e64e36ff8 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java
@@ -20,6 +20,7 @@ import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -314,7 +315,7 @@ public abstract class JavaFileManagerBase implements JavaFileManager, Disposable
final VirtualFile root = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getClassRootForFile(vFile);
VirtualFile parent = vFile.getParent();
final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper();
- while (parent != null && parent != root) {
+ while (parent != null && !Comparing.equal(parent, root)) {
if (!nameHelper.isIdentifier(parent.getName())) return false;
parent = parent.getParent();
}
@@ -332,7 +333,7 @@ public abstract class JavaFileManagerBase implements JavaFileManager, Disposable
final ProjectFileIndex fileIndex = rootManager.getFileIndex();
for (final VirtualFile sourceRoot : sourceRoots) {
final String packageName = fileIndex.getPackageNameByDirectory(sourceRoot);
- if (packageName != null && packageName.length() > 0) {
+ if (packageName != null && !packageName.isEmpty()) {
names.add(packageName);
}
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
index b88ac9e77309..049c6feb304b 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.psi.impl.search;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -179,7 +195,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor guessFromContent(VirtualFile virtualFile, byte[] content, int length) {
+ public static Trinity guessFromContent(VirtualFile virtualFile, byte[] content, int length) {
EncodingRegistry settings = EncodingRegistry.getInstance();
boolean shouldGuess = settings != null && settings.isUseUTFGuessing(virtualFile);
CharsetToolkit toolkit = shouldGuess ? new CharsetToolkit(content, EncodingRegistry.getInstance().getDefaultCharset()) : null;
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java
index 0e613662a573..a34f18259b57 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/JdkScope.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.roots.JdkOrderEntry;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.ContainerUtil;
@@ -74,8 +75,8 @@ public class JdkScope extends GlobalSearchScope {
final VirtualFile r1 = getFileRoot(file1);
final VirtualFile r2 = getFileRoot(file2);
for (VirtualFile root : myEntries) {
- if (r1 == root) return 1;
- if (r2 == root) return -1;
+ if (Comparing.equal(r1, root)) return 1;
+ if (Comparing.equal(r2, root)) return -1;
}
return 0;
}
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java
index dfa53f3245ba..4e77639ad6fb 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/LibraryRuntimeClasspathScope.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
@@ -144,8 +145,8 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope {
final VirtualFile r1 = getFileRoot(file1);
final VirtualFile r2 = getFileRoot(file2);
for (VirtualFile root : myEntries) {
- if (r1 == root) return 1;
- if (r2 == root) return -1;
+ if (Comparing.equal(r1, root)) return 1;
+ if (Comparing.equal(r2, root)) return -1;
}
return 0;
}
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
index bd97a36bb5e8..ed52ba95b6b8 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependenciesScope.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.module.impl.scopes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiBundle;
import com.intellij.psi.search.GlobalSearchScope;
@@ -147,14 +148,14 @@ public class ModuleWithDependenciesScope extends GlobalSearchScope {
public int compare(VirtualFile file1, VirtualFile file2) {
VirtualFile r1 = getFileRoot(file1);
VirtualFile r2 = getFileRoot(file2);
- if (r1 == r2) return 0;
+ if (Comparing.equal(r1, r2)) return 0;
if (r1 == null) return -1;
if (r2 == null) return 1;
for (VirtualFile root : myRoots) {
- if (r1 == root) return 1;
- if (r2 == root) return -1;
+ if (Comparing.equal(r1, root)) return 1;
+ if (Comparing.equal(r2, root)) return -1;
}
return 0;
}
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 102d132e8193..bcb5e0b89808 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
@@ -26,10 +26,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.roots.FileIndexFacade;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.NullableComputable;
-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.*;
@@ -767,7 +764,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@Override
public boolean process(VirtualFile file) {
- if (file == fileToIgnoreOccurencesInVirtualFile) return true;
+ if (Comparing.equal(file, fileToIgnoreOccurencesInVirtualFile)) return true;
if (!index.shouldBeFound(scope, file)) return true;
final int value = count.incrementAndGet();
return value < 10;
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
index fff9c3bf551d..61df4cd82467 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementWeigher.java
@@ -16,15 +16,26 @@
package com.intellij.codeInsight.lookup;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author peter
*/
public abstract class LookupElementWeigher {
private final String myId;
+ private final boolean myNegated;
+
+ protected LookupElementWeigher(String id, boolean negated) {
+ myId = id;
+ myNegated = negated;
+ }
protected LookupElementWeigher(String id) {
- myId = id;
+ this(id, false);
+ }
+
+ public boolean isNegated() {
+ return myNegated;
}
@Override
@@ -32,7 +43,7 @@ public abstract class LookupElementWeigher {
return myId;
}
- @NotNull
+ @Nullable
public abstract Comparable weigh(@NotNull LookupElement element);
}
diff --git a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java
index f3aec40ed66c..355ee56803d9 100644
--- a/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java
+++ b/platform/lang-api/src/com/intellij/ide/projectView/ProjectViewNode.java
@@ -18,6 +18,7 @@ package com.intellij.ide.projectView;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
@@ -189,7 +190,7 @@ public abstract class ProjectViewNode extends AbstractTreeNode im
public boolean value(final VirtualFile virtualFile) {
return contains(virtualFile)
// in case of flattened packages, when package node a.b.c contains error file, node a.b might not.
- && (getValue() instanceof PsiElement && PsiUtilBase.getVirtualFile((PsiElement)getValue()) == virtualFile ||
+ && (getValue() instanceof PsiElement && Comparing.equal(PsiUtilBase.getVirtualFile((PsiElement)getValue()), virtualFile) ||
someChildContainsFile(virtualFile));
}
});
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java
index 643422517170..fe911cdde33a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java
@@ -1,371 +1,372 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.codeInsight.completion;
-
-import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementPresentation;
-import com.intellij.navigation.ChooseByNameContributor;
-import com.intellij.openapi.actionSystem.IdeActions;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.fileTypes.FileNameMatcher;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiFileSystemItem;
-import com.intellij.psi.PsiReference;
-import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
-import com.intellij.psi.impl.source.resolve.reference.impl.providers.*;
-import com.intellij.psi.search.FilenameIndex;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.ProjectScope;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.ProcessingContext;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import java.util.*;
-
-import static com.intellij.patterns.PlatformPatterns.psiElement;
-
-/**
- * @author spleaner
- */
-public class FilePathCompletionContributor extends CompletionContributor {
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.FilePathCompletionContributor");
-
- public FilePathCompletionContributor() {
- extend(CompletionType.BASIC, psiElement(), new CompletionProvider() {
- @Override
- protected void addCompletions(@NotNull CompletionParameters parameters,
- ProcessingContext context,
- @NotNull CompletionResultSet result) {
- final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
- if (getReference(psiReference) != null && parameters.getInvocationCount() == 1) {
- final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
- if (shortcut != null) {
- CompletionService.getCompletionService().setAdvertisementText(CodeInsightBundle.message("class.completion.file.path", shortcut));
- }
- }
- }
- });
-
- CompletionProvider provider = new CompletionProvider() {
- @Override
- protected void addCompletions(@NotNull final CompletionParameters parameters,
- ProcessingContext context,
- @NotNull final CompletionResultSet _result) {
- if (!parameters.isExtendedCompletion()) {
- return;
- }
-
- @NotNull final CompletionResultSet result = _result.caseInsensitive();
- final PsiElement e = parameters.getPosition();
- final Project project = e.getProject();
-
- final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
-
- final Pair fileReferencePair = getReference(psiReference);
- if (fileReferencePair != null) {
- final FileReference first = fileReferencePair.getFirst();
- if (first == null) return;
-
- final FileReferenceSet set = first.getFileReferenceSet();
- String prefix = set.getPathString()
- .substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement());
- final String textBeforePosition = e.getContainingFile().getText().substring(0, parameters.getOffset());
- if (!textBeforePosition.endsWith(prefix)) {
- final int len = textBeforePosition.length();
- final String fragment = len > 100 ? textBeforePosition.substring(len - 100) : textBeforePosition;
- throw new AssertionError("prefix should be some actual file string just before caret: " +
- prefix +
- "\n text=" +
- fragment +
- ";\npathString=" +
- set.getPathString() +
- ";\nelementText=" +
- e.getParent().getText());
- }
-
- List pathPrefixParts = null;
- int lastSlashIndex;
- if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) {
- pathPrefixParts = StringUtil.split(prefix.substring(0, lastSlashIndex), "/");
- prefix = prefix.substring(lastSlashIndex + 1);
- }
-
- final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive();
-
- final PsiFile originalFile = parameters.getOriginalFile();
- final VirtualFile contextFile = originalFile.getVirtualFile();
- if (contextFile != null) {
- final String[] fileNames = getAllNames(project);
- final Set resultNames = new TreeSet();
- for (String fileName : fileNames) {
- if (filenameMatchesPrefixOrType(fileName, prefix, set.getSuitableFileTypes(), parameters.getInvocationCount())) {
- resultNames.add(fileName);
- }
- }
-
- final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
-
- final Module contextModule = index.getModuleForFile(contextFile);
- if (contextModule != null) {
- final FileReferenceHelper contextHelper = FileReferenceHelperRegistrar.getNotNullHelper(originalFile);
-
- final GlobalSearchScope scope = ProjectScope.getProjectScope(project);
- for (final String name : resultNames) {
- ProgressManager.checkCanceled();
-
- final PsiFile[] files = FilenameIndex.getFilesByName(project, name, scope);
-
- if (files.length > 0) {
- for (final PsiFile file : files) {
- ProgressManager.checkCanceled();
-
- final VirtualFile virtualFile = file.getVirtualFile();
- if (virtualFile != null && virtualFile.isValid() && virtualFile != contextFile) {
- if (contextHelper.isMine(project, virtualFile)) {
- if (pathPrefixParts == null ||
- fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts)) {
- __result.addElement(new FilePathLookupItem(file, contextHelper));
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (set.getSuitableFileTypes().length > 0 && parameters.getInvocationCount() == 1) {
- final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
- if (shortcut != null) {
- CompletionService.getCompletionService()
- .setAdvertisementText(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut));
- }
- }
-
- if (fileReferencePair.getSecond()) result.stopHere();
- }
- }
- };
- extend(CompletionType.BASIC, psiElement(), provider);
- }
-
- private static boolean filenameMatchesPrefixOrType(final String fileName, final String prefix, final FileType[] suitableFileTypes, final int invocationCount) {
- final boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix);
- if (prefixMatched && (suitableFileTypes.length == 0 || invocationCount > 2)) return true;
-
- if (prefixMatched) {
- final String extension = FileUtil.getExtension(fileName);
- if (extension.length() == 0) return false;
-
- for (final FileType fileType : suitableFileTypes) {
- final List matchers = FileTypeManager.getInstance().getAssociations(fileType);
- for (final FileNameMatcher matcher : matchers) {
- if (matcher.accept(fileName)) return true;
- }
- }
- }
-
- return false;
- }
-
- private static boolean fileMatchesPathPrefix(@Nullable final PsiFileSystemItem file, @NotNull final List pathPrefix) {
- if (file == null) return false;
-
- final List contextParts = new ArrayList();
- PsiFileSystemItem parentFile = file;
- PsiFileSystemItem parent;
- while ((parent = parentFile.getParent()) != null) {
- if (parent.getName().length() > 0) contextParts.add(0, parent.getName().toLowerCase());
- parentFile = parent;
- }
-
- final String path = StringUtil.join(contextParts, "/");
-
- int nextIndex = 0;
- for (final String s : pathPrefix) {
- if ((nextIndex = path.indexOf(s.toLowerCase(), nextIndex)) == -1) return false;
- }
-
- return true;
- }
-
- private static String[] getAllNames(@NotNull final Project project) {
- Set names = new HashSet();
- final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions();
- for (final ChooseByNameContributor contributor : nameContributors) {
- try {
- names.addAll(Arrays.asList(contributor.getNames(project, false)));
- }
- catch (ProcessCanceledException ex) {
- // index corruption detected, ignore
- }
- catch (Exception ex) {
- LOG.error(ex);
- }
- }
-
- return ArrayUtil.toStringArray(names);
- }
-
- @Nullable
- private static Pair getReference(final PsiReference original) {
- if (original == null) {
- return null;
- }
-
- if (original instanceof PsiMultiReference) {
- final PsiMultiReference multiReference = (PsiMultiReference)original;
- for (PsiReference reference : multiReference.getReferences()) {
- if (reference instanceof FileReference) {
- return Pair.create((FileReference) reference, false);
- }
- }
- }
- else if (original instanceof FileReferenceOwner) {
- final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
- if (fileReference != null) {
- return Pair.create(fileReference, true);
- }
- }
-
- return null;
- }
-
- public class FilePathLookupItem extends LookupElement {
- private final String myName;
- private final String myPath;
- private final String myInfo;
- private final Icon myIcon;
- private final PsiFile myFile;
- private final FileReferenceHelper myReferenceHelper;
-
- public FilePathLookupItem(@NotNull final PsiFile file, @NotNull final FileReferenceHelper referenceHelper) {
- myName = file.getName();
- myPath = file.getVirtualFile().getPath();
-
- myReferenceHelper = referenceHelper;
-
- myInfo = FileInfoManager.getFileAdditionalInfo(file);
- myIcon = file.getFileType().getIcon();
-
- myFile = file;
- }
-
- @SuppressWarnings({"HardCodedStringLiteral"})
- @Override
- public String toString() {
- return String.format("%s%s", myName, myInfo == null ? "" : " (" + myInfo + ")");
- }
-
- @NotNull
- @Override
- public Object getObject() {
- return myFile;
- }
-
- @NotNull
- public String getLookupString() {
- return myName;
- }
-
- @Override
- public void handleInsert(InsertionContext context) {
- context.commitDocument();
- if (myFile.isValid()) {
- final PsiReference psiReference = context.getFile().findReferenceAt(context.getStartOffset());
- final Pair fileReferencePair = getReference(psiReference);
- LOG.assertTrue(fileReferencePair != null);
-
- FileReference ref = fileReferencePair.getFirst();
- context.setTailOffset(ref.getRangeInElement().getEndOffset() + ref.getElement().getTextRange().getStartOffset());
- ref.bindToElement(myFile, true);
- }
- }
-
- @Override
- public void renderElement(LookupElementPresentation presentation) {
- final VirtualFile virtualFile = myFile.getVirtualFile();
- LOG.assertTrue(virtualFile != null);
- final PsiFileSystemItem root = myReferenceHelper.findRoot(myFile.getProject(), virtualFile);
- final String relativePath = PsiFileSystemItemUtil.getRelativePath(root, myReferenceHelper.getPsiFileSystemItem(myFile.getProject(), virtualFile));
-
- final StringBuilder sb = new StringBuilder();
- if (myInfo != null) {
- sb.append(" (").append(myInfo);
- }
-
- if (relativePath != null && !relativePath.equals(myName)) {
- if (myInfo != null) {
- sb.append(", ");
- }
- else {
- sb.append(" (");
- }
-
- sb.append(relativePath);
- }
-
- if (sb.length() > 0) {
- sb.append(')');
- }
-
- presentation.setItemText(myName);
-
- if (sb.length() > 0) {
- presentation.setTailText(sb.toString(), true);
- }
-
- presentation.setIcon(myIcon);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- FilePathLookupItem that = (FilePathLookupItem)o;
-
- if (!myName.equals(that.myName)) return false;
- if (!myPath.equals(that.myPath)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = myName.hashCode();
- result = 31 * result + myPath.hashCode();
- return result;
- }
- }
-}
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.codeInsight.completion;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import com.intellij.navigation.ChooseByNameContributor;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileNameMatcher;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.*;
+import com.intellij.psi.search.FilenameIndex;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.*;
+
+import static com.intellij.patterns.PlatformPatterns.psiElement;
+
+/**
+ * @author spleaner
+ */
+public class FilePathCompletionContributor extends CompletionContributor {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.FilePathCompletionContributor");
+
+ public FilePathCompletionContributor() {
+ extend(CompletionType.BASIC, psiElement(), new CompletionProvider() {
+ @Override
+ protected void addCompletions(@NotNull CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull CompletionResultSet result) {
+ final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
+ if (getReference(psiReference) != null && parameters.getInvocationCount() == 1) {
+ final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
+ if (shortcut != null) {
+ CompletionService.getCompletionService().setAdvertisementText(CodeInsightBundle.message("class.completion.file.path", shortcut));
+ }
+ }
+ }
+ });
+
+ CompletionProvider provider = new CompletionProvider() {
+ @Override
+ protected void addCompletions(@NotNull final CompletionParameters parameters,
+ ProcessingContext context,
+ @NotNull final CompletionResultSet _result) {
+ if (!parameters.isExtendedCompletion()) {
+ return;
+ }
+
+ @NotNull final CompletionResultSet result = _result.caseInsensitive();
+ final PsiElement e = parameters.getPosition();
+ final Project project = e.getProject();
+
+ final PsiReference psiReference = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset());
+
+ final Pair fileReferencePair = getReference(psiReference);
+ if (fileReferencePair != null) {
+ final FileReference first = fileReferencePair.getFirst();
+ if (first == null) return;
+
+ final FileReferenceSet set = first.getFileReferenceSet();
+ String prefix = set.getPathString()
+ .substring(0, parameters.getOffset() - set.getElement().getTextRange().getStartOffset() - set.getStartInElement());
+ final String textBeforePosition = e.getContainingFile().getText().substring(0, parameters.getOffset());
+ if (!textBeforePosition.endsWith(prefix)) {
+ final int len = textBeforePosition.length();
+ final String fragment = len > 100 ? textBeforePosition.substring(len - 100) : textBeforePosition;
+ throw new AssertionError("prefix should be some actual file string just before caret: " +
+ prefix +
+ "\n text=" +
+ fragment +
+ ";\npathString=" +
+ set.getPathString() +
+ ";\nelementText=" +
+ e.getParent().getText());
+ }
+
+ List pathPrefixParts = null;
+ int lastSlashIndex;
+ if ((lastSlashIndex = prefix.lastIndexOf('/')) != -1) {
+ pathPrefixParts = StringUtil.split(prefix.substring(0, lastSlashIndex), "/");
+ prefix = prefix.substring(lastSlashIndex + 1);
+ }
+
+ final CompletionResultSet __result = result.withPrefixMatcher(prefix).caseInsensitive();
+
+ final PsiFile originalFile = parameters.getOriginalFile();
+ final VirtualFile contextFile = originalFile.getVirtualFile();
+ if (contextFile != null) {
+ final String[] fileNames = getAllNames(project);
+ final Set resultNames = new TreeSet();
+ for (String fileName : fileNames) {
+ if (filenameMatchesPrefixOrType(fileName, prefix, set.getSuitableFileTypes(), parameters.getInvocationCount())) {
+ resultNames.add(fileName);
+ }
+ }
+
+ final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
+
+ final Module contextModule = index.getModuleForFile(contextFile);
+ if (contextModule != null) {
+ final FileReferenceHelper contextHelper = FileReferenceHelperRegistrar.getNotNullHelper(originalFile);
+
+ final GlobalSearchScope scope = ProjectScope.getProjectScope(project);
+ for (final String name : resultNames) {
+ ProgressManager.checkCanceled();
+
+ final PsiFile[] files = FilenameIndex.getFilesByName(project, name, scope);
+
+ if (files.length > 0) {
+ for (final PsiFile file : files) {
+ ProgressManager.checkCanceled();
+
+ final VirtualFile virtualFile = file.getVirtualFile();
+ if (virtualFile != null && virtualFile.isValid() && !Comparing.equal(virtualFile, contextFile)) {
+ if (contextHelper.isMine(project, virtualFile)) {
+ if (pathPrefixParts == null ||
+ fileMatchesPathPrefix(contextHelper.getPsiFileSystemItem(project, virtualFile), pathPrefixParts)) {
+ __result.addElement(new FilePathLookupItem(file, contextHelper));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (set.getSuitableFileTypes().length > 0 && parameters.getInvocationCount() == 1) {
+ final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION);
+ if (shortcut != null) {
+ CompletionService.getCompletionService()
+ .setAdvertisementText(CodeInsightBundle.message("class.completion.file.path.all.variants", shortcut));
+ }
+ }
+
+ if (fileReferencePair.getSecond()) result.stopHere();
+ }
+ }
+ };
+ extend(CompletionType.BASIC, psiElement(), provider);
+ }
+
+ private static boolean filenameMatchesPrefixOrType(final String fileName, final String prefix, final FileType[] suitableFileTypes, final int invocationCount) {
+ final boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix);
+ if (prefixMatched && (suitableFileTypes.length == 0 || invocationCount > 2)) return true;
+
+ if (prefixMatched) {
+ final String extension = FileUtil.getExtension(fileName);
+ if (extension.length() == 0) return false;
+
+ for (final FileType fileType : suitableFileTypes) {
+ final List matchers = FileTypeManager.getInstance().getAssociations(fileType);
+ for (final FileNameMatcher matcher : matchers) {
+ if (matcher.accept(fileName)) return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean fileMatchesPathPrefix(@Nullable final PsiFileSystemItem file, @NotNull final List pathPrefix) {
+ if (file == null) return false;
+
+ final List contextParts = new ArrayList();
+ PsiFileSystemItem parentFile = file;
+ PsiFileSystemItem parent;
+ while ((parent = parentFile.getParent()) != null) {
+ if (parent.getName().length() > 0) contextParts.add(0, parent.getName().toLowerCase());
+ parentFile = parent;
+ }
+
+ final String path = StringUtil.join(contextParts, "/");
+
+ int nextIndex = 0;
+ for (final String s : pathPrefix) {
+ if ((nextIndex = path.indexOf(s.toLowerCase(), nextIndex)) == -1) return false;
+ }
+
+ return true;
+ }
+
+ private static String[] getAllNames(@NotNull final Project project) {
+ Set names = new HashSet();
+ final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions();
+ for (final ChooseByNameContributor contributor : nameContributors) {
+ try {
+ names.addAll(Arrays.asList(contributor.getNames(project, false)));
+ }
+ catch (ProcessCanceledException ex) {
+ // index corruption detected, ignore
+ }
+ catch (Exception ex) {
+ LOG.error(ex);
+ }
+ }
+
+ return ArrayUtil.toStringArray(names);
+ }
+
+ @Nullable
+ private static Pair getReference(final PsiReference original) {
+ if (original == null) {
+ return null;
+ }
+
+ if (original instanceof PsiMultiReference) {
+ final PsiMultiReference multiReference = (PsiMultiReference)original;
+ for (PsiReference reference : multiReference.getReferences()) {
+ if (reference instanceof FileReference) {
+ return Pair.create((FileReference) reference, false);
+ }
+ }
+ }
+ else if (original instanceof FileReferenceOwner) {
+ final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
+ if (fileReference != null) {
+ return Pair.create(fileReference, true);
+ }
+ }
+
+ return null;
+ }
+
+ public class FilePathLookupItem extends LookupElement {
+ private final String myName;
+ private final String myPath;
+ private final String myInfo;
+ private final Icon myIcon;
+ private final PsiFile myFile;
+ private final FileReferenceHelper myReferenceHelper;
+
+ public FilePathLookupItem(@NotNull final PsiFile file, @NotNull final FileReferenceHelper referenceHelper) {
+ myName = file.getName();
+ myPath = file.getVirtualFile().getPath();
+
+ myReferenceHelper = referenceHelper;
+
+ myInfo = FileInfoManager.getFileAdditionalInfo(file);
+ myIcon = file.getFileType().getIcon();
+
+ myFile = file;
+ }
+
+ @SuppressWarnings({"HardCodedStringLiteral"})
+ @Override
+ public String toString() {
+ return String.format("%s%s", myName, myInfo == null ? "" : " (" + myInfo + ")");
+ }
+
+ @NotNull
+ @Override
+ public Object getObject() {
+ return myFile;
+ }
+
+ @NotNull
+ public String getLookupString() {
+ return myName;
+ }
+
+ @Override
+ public void handleInsert(InsertionContext context) {
+ context.commitDocument();
+ if (myFile.isValid()) {
+ final PsiReference psiReference = context.getFile().findReferenceAt(context.getStartOffset());
+ final Pair fileReferencePair = getReference(psiReference);
+ LOG.assertTrue(fileReferencePair != null);
+
+ FileReference ref = fileReferencePair.getFirst();
+ context.setTailOffset(ref.getRangeInElement().getEndOffset() + ref.getElement().getTextRange().getStartOffset());
+ ref.bindToElement(myFile, true);
+ }
+ }
+
+ @Override
+ public void renderElement(LookupElementPresentation presentation) {
+ final VirtualFile virtualFile = myFile.getVirtualFile();
+ LOG.assertTrue(virtualFile != null);
+ final PsiFileSystemItem root = myReferenceHelper.findRoot(myFile.getProject(), virtualFile);
+ final String relativePath = PsiFileSystemItemUtil.getRelativePath(root, myReferenceHelper.getPsiFileSystemItem(myFile.getProject(), virtualFile));
+
+ final StringBuilder sb = new StringBuilder();
+ if (myInfo != null) {
+ sb.append(" (").append(myInfo);
+ }
+
+ if (relativePath != null && !relativePath.equals(myName)) {
+ if (myInfo != null) {
+ sb.append(", ");
+ }
+ else {
+ sb.append(" (");
+ }
+
+ sb.append(relativePath);
+ }
+
+ if (sb.length() > 0) {
+ sb.append(')');
+ }
+
+ presentation.setItemText(myName);
+
+ if (sb.length() > 0) {
+ presentation.setTailText(sb.toString(), true);
+ }
+
+ presentation.setIcon(myIcon);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ FilePathLookupItem that = (FilePathLookupItem)o;
+
+ if (!myName.equals(that.myName)) return false;
+ if (!myPath.equals(that.myPath)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = myName.hashCode();
+ result = 31 * result + myPath.hashCode();
+ return result;
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
index b05af5f6371e..e35d45803640 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java
@@ -1,356 +1,355 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.completion.impl;
-
-import com.intellij.codeInsight.CodeInsightSettings;
-import com.intellij.codeInsight.completion.*;
-import com.intellij.codeInsight.lookup.*;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.project.ProjectManagerAdapter;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Pair;
-import com.intellij.patterns.ElementPattern;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.Weigher;
-import com.intellij.psi.WeighingService;
-import com.intellij.psi.codeStyle.MinusculeMatcher;
-import com.intellij.psi.codeStyle.NameUtil;
-import com.intellij.psi.impl.DebugUtil;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.util.Consumer;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-
-/**
- * @author peter
- */
-public class CompletionServiceImpl extends CompletionService{
- private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl");
- private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion;
- private static String ourPhaseTrace;
- private static CodeInsightSettings ourSettings = CodeInsightSettings.getInstance();
-
- public CompletionServiceImpl() {
- ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() {
- @Override
- public void projectClosing(Project project) {
- CompletionProgressIndicator indicator = getCurrentCompletion();
- if (indicator != null && indicator.getProject() == project) {
- LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
- setCompletionPhase(CompletionPhase.NoCompletion);
- }
- else if (indicator == null) {
- setCompletionPhase(CompletionPhase.NoCompletion);
- }
- }
- });
- }
-
- @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"})
- public static CompletionServiceImpl getCompletionService() {
- return (CompletionServiceImpl)CompletionService.getCompletionService();
- }
-
- @Override
- public String getAdvertisementText() {
- final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion();
- return completion == null ? null : completion.getLookup().getAdvertisementText();
- }
-
- public void setAdvertisementText(@Nullable final String text) {
- final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion();
- if (completion != null) {
- completion.getLookup().setAdvertisementText(text);
- }
- }
-
- public CompletionResultSet createResultSet(final CompletionParameters parameters, final Consumer consumer,
- @NotNull final CompletionContributor contributor) {
- final PsiElement position = parameters.getPosition();
- final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset());
- final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset());
- ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
- if (!(indicator instanceof CompletionProgressIndicator)) {
- throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace);
- }
- CompletionProgressIndicator process = (CompletionProgressIndicator)indicator;
- CamelHumpMatcher matcher = new CamelHumpMatcher(prefix);
- CompletionSorterImpl sorter = defaultSorter(parameters, matcher);
- return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null);
- }
-
- @Override
- public CompletionProgressIndicator getCurrentCompletion() {
- if (isPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.CommittingDocuments.class,
- CompletionPhase.Synchronous.class)) {
- return ourPhase.indicator;
- }
- return null;
- }
-
- private static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) {
- final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item));
-
- int max = Integer.MIN_VALUE;
- for (String lookupString : item.getAllLookupStrings()) {
- max = Math.max(max, matcher.matchingDegree(lookupString));
- }
- return max;
- }
-
- private static volatile Pair lastMatcher;
-
- private static MinusculeMatcher getMinusculeMatcher(String prefix) {
- final int setting = ourSettings.COMPLETION_CASE_SENSITIVE;
- final NameUtil.MatchingCaseSensitivity sensitivity =
- setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
- setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
-
- Pair pair = lastMatcher;
- if (pair != null && pair.first.equals(prefix)) {
- return pair.second;
- }
-
- MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
- lastMatcher = Pair.create(prefix, matcher);
- return matcher;
- }
-
- private static class CompletionResultSetImpl extends CompletionResultSet {
- private final String myTextBeforePosition;
- private final CompletionParameters myParameters;
- private final CompletionSorterImpl mySorter;
- private final CompletionProgressIndicator myProcess;
- @Nullable private final CompletionResultSetImpl myOriginal;
-
- public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition,
- final PrefixMatcher prefixMatcher,
- CompletionContributor contributor,
- CompletionParameters parameters,
- @NotNull CompletionSorterImpl sorter,
- @NotNull CompletionProgressIndicator process,
- @Nullable CompletionResultSetImpl original) {
- super(prefixMatcher, consumer, contributor);
- myTextBeforePosition = textBeforePosition;
- myParameters = parameters;
- mySorter = sorter;
- myProcess = process;
- myOriginal = original;
- }
-
- public void addElement(@NotNull final LookupElement element) {
- CompletionResult matched = CompletionResult.wrap(element, getPrefixMatcher(), mySorter);
- if (matched != null) {
- passResult(matched);
- }
- }
-
- @NotNull
- public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) {
- if (!myTextBeforePosition.endsWith(matcher.getPrefix())) {
- final int len = myTextBeforePosition.length();
- final String fragment = len > 100 ? myTextBeforePosition.substring(len - 100) : myTextBeforePosition;
- PsiFile positionFile = myParameters.getPosition().getContainingFile();
- LOG.error("prefix should be some actual file string just before caret: " + matcher.getPrefix() +
- "\n text=" + fragment +
- "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) +
- "\nlang=" + positionFile.getLanguage());
- }
- return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
- }
-
- @Override
- public void stopHere() {
- super.stopHere();
- if (myOriginal != null) {
- myOriginal.stopHere();
- }
- }
-
- @NotNull
- public CompletionResultSet withPrefixMatcher(@NotNull final String prefix) {
- return withPrefixMatcher(new CamelHumpMatcher(prefix));
- }
-
- @NotNull
- @Override
- public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) {
- return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
- }
-
- @NotNull
- @Override
- public CompletionResultSet caseInsensitive() {
- return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false));
- }
-
- @Override
- public void restartCompletionOnPrefixChange(ElementPattern prefixCondition) {
- final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
- if (indicator != null) {
- indicator.addWatchedPrefix(myTextBeforePosition.length() - getPrefixMatcher().getPrefix().length(), prefixCondition);
- }
- }
-
- @Override
- public void restartCompletionWhenNothingMatches() {
- final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
- if (indicator != null) {
- indicator.getLookup().setStartCompletionWhenNothingMatches(true);
- }
- }
- }
-
- public static boolean assertPhase(Class extends CompletionPhase>... possibilities) {
- if (!isPhase(possibilities)) {
- LOG.error(ourPhase + "; set at " + ourPhaseTrace);
- return false;
- }
- return true;
- }
-
- public static boolean isPhase(Class extends CompletionPhase>... possibilities) {
- CompletionPhase phase = getCompletionPhase();
- for (Class extends CompletionPhase> possibility : possibilities) {
- if (possibility.isInstance(phase)) {
- return true;
- }
- }
- return false;
- }
-
- public static void setCompletionPhase(@NotNull CompletionPhase phase) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- CompletionPhase oldPhase = getCompletionPhase();
- CompletionProgressIndicator oldIndicator = oldPhase.indicator;
- if (oldIndicator != null && !(phase instanceof CompletionPhase.BgCalculation)) {
- LOG.assertTrue(!oldIndicator.isRunning() || oldIndicator.isCanceled(), "don't change phase during running completion: oldPhase=" + oldPhase);
- }
-
- Disposer.dispose(oldPhase);
- ourPhase = phase;
- ourPhaseTrace = DebugUtil.currentStackTrace();
- }
-
- public static CompletionPhase getCompletionPhase() {
-// ApplicationManager.getApplication().assertIsDispatchThread();
- CompletionPhase phase = getPhaseRaw();
- ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
- if (indicator != null) {
- indicator.checkCanceled();
- }
- return phase;
- }
-
- public static CompletionPhase getPhaseRaw() {
- return ourPhase;
- }
-
- public CompletionSorterImpl defaultSorter(CompletionParameters parameters, final PrefixMatcher matcher) {
- final CompletionLocation location = new CompletionLocation(parameters);
-
- CompletionSorterImpl sorter = emptySorter();
- sorter = sorter.withClassifier(new PreferStartMatching(location));
-
- for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) {
- final String id = weigher.toString();
- if ("prefix".equals(id)) {
- sorter = sorter.withClassifier(new PrefixMatchingClassifier(id, location));
- }
- else {
- sorter = sorter.weigh(new LookupElementWeigher(id) {
- @NotNull
- @Override
- public Comparable weigh(@NotNull LookupElement element) {
- return new NegatingComparable(weigher.weigh(element, location));
- }
- });
- }
-
- }
-
- if (parameters.getCompletionType() == CompletionType.SMART) {
- return sorter;
- }
-
- return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") {
- @Override
- public Classifier createClassifier(final Classifier next) {
- return new LiftShorterItemsClassifier(next, new LiftShorterItemsClassifier.LiftingCondition());
- }
- });
- }
-
- public CompletionSorterImpl emptySorter() {
- return new CompletionSorterImpl(new ArrayList>());
- }
-
- private static class PreferStartMatching extends ClassifierFactory {
- private final CompletionLocation myLocation;
-
- public PreferStartMatching(CompletionLocation location) {
- super("startMatching");
- myLocation = location;
- }
-
- @Override
- public Classifier createClassifier(Classifier next) {
- return new ComparingClassifier(next, "startMatching") {
- @NotNull
- @Override
- public Comparable getWeight(LookupElement element) {
- PrefixMatcher itemMatcher = myLocation.getCompletionParameters().getLookup().itemMatcher(element);
- for (String ls : element.getAllLookupStrings()) {
- if (itemMatcher.isStartMatch(ls)) {
- return false;
- }
- }
- return true;
- }
- };
- }
- }
-
- private static class PrefixMatchingClassifier extends ClassifierFactory {
- private final String myId;
- private final CompletionLocation myLocation;
-
- public PrefixMatchingClassifier(String id, CompletionLocation location) {
- super(id);
- myId = id;
- myLocation = location;
- }
-
- @Override
- public Classifier createClassifier(Classifier next) {
- return new ComparingClassifier(next, myId) {
- @NotNull
- @Override
- public Comparable getWeight(LookupElement element) {
- return -getPrefixMatchingDegree(element, myLocation);
- }
- };
- }
- }
-}
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.impl;
+
+import com.intellij.codeInsight.CodeInsightSettings;
+import com.intellij.codeInsight.completion.*;
+import com.intellij.codeInsight.lookup.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.patterns.ElementPattern;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.Weigher;
+import com.intellij.psi.WeighingService;
+import com.intellij.psi.codeStyle.MinusculeMatcher;
+import com.intellij.psi.codeStyle.NameUtil;
+import com.intellij.psi.impl.DebugUtil;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * @author peter
+ */
+public class CompletionServiceImpl extends CompletionService{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl");
+ private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion;
+ private static String ourPhaseTrace;
+ private static CodeInsightSettings ourSettings = CodeInsightSettings.getInstance();
+
+ public CompletionServiceImpl() {
+ ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() {
+ @Override
+ public void projectClosing(Project project) {
+ CompletionProgressIndicator indicator = getCurrentCompletion();
+ if (indicator != null && indicator.getProject() == project) {
+ LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
+ setCompletionPhase(CompletionPhase.NoCompletion);
+ }
+ else if (indicator == null) {
+ setCompletionPhase(CompletionPhase.NoCompletion);
+ }
+ }
+ });
+ }
+
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass"})
+ public static CompletionServiceImpl getCompletionService() {
+ return (CompletionServiceImpl)CompletionService.getCompletionService();
+ }
+
+ @Override
+ public String getAdvertisementText() {
+ final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion();
+ return completion == null ? null : completion.getLookup().getAdvertisementText();
+ }
+
+ public void setAdvertisementText(@Nullable final String text) {
+ final CompletionProgressIndicator completion = getCompletionService().getCurrentCompletion();
+ if (completion != null) {
+ completion.getLookup().setAdvertisementText(text);
+ }
+ }
+
+ public CompletionResultSet createResultSet(final CompletionParameters parameters, final Consumer consumer,
+ @NotNull final CompletionContributor contributor) {
+ final PsiElement position = parameters.getPosition();
+ final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset());
+ final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset());
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (!(indicator instanceof CompletionProgressIndicator)) {
+ throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace);
+ }
+ CompletionProgressIndicator process = (CompletionProgressIndicator)indicator;
+ CamelHumpMatcher matcher = new CamelHumpMatcher(prefix);
+ CompletionSorterImpl sorter = defaultSorter(parameters, matcher);
+ return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null);
+ }
+
+ @Override
+ public CompletionProgressIndicator getCurrentCompletion() {
+ if (isPhase(CompletionPhase.BgCalculation.class, CompletionPhase.ItemsCalculated.class, CompletionPhase.CommittingDocuments.class,
+ CompletionPhase.Synchronous.class)) {
+ return ourPhase.indicator;
+ }
+ return null;
+ }
+
+ private static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) {
+ final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item));
+
+ int max = Integer.MIN_VALUE;
+ for (String lookupString : item.getAllLookupStrings()) {
+ max = Math.max(max, matcher.matchingDegree(lookupString));
+ }
+ return max;
+ }
+
+ private static volatile Pair lastMatcher;
+
+ private static MinusculeMatcher getMinusculeMatcher(String prefix) {
+ final int setting = ourSettings.COMPLETION_CASE_SENSITIVE;
+ final NameUtil.MatchingCaseSensitivity sensitivity =
+ setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE :
+ setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL;
+
+ Pair pair = lastMatcher;
+ if (pair != null && pair.first.equals(prefix)) {
+ return pair.second;
+ }
+
+ MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity);
+ lastMatcher = Pair.create(prefix, matcher);
+ return matcher;
+ }
+
+ private static class CompletionResultSetImpl extends CompletionResultSet {
+ private final String myTextBeforePosition;
+ private final CompletionParameters myParameters;
+ private final CompletionSorterImpl mySorter;
+ private final CompletionProgressIndicator myProcess;
+ @Nullable private final CompletionResultSetImpl myOriginal;
+
+ public CompletionResultSetImpl(final Consumer consumer, final String textBeforePosition,
+ final PrefixMatcher prefixMatcher,
+ CompletionContributor contributor,
+ CompletionParameters parameters,
+ @NotNull CompletionSorterImpl sorter,
+ @NotNull CompletionProgressIndicator process,
+ @Nullable CompletionResultSetImpl original) {
+ super(prefixMatcher, consumer, contributor);
+ myTextBeforePosition = textBeforePosition;
+ myParameters = parameters;
+ mySorter = sorter;
+ myProcess = process;
+ myOriginal = original;
+ }
+
+ public void addElement(@NotNull final LookupElement element) {
+ CompletionResult matched = CompletionResult.wrap(element, getPrefixMatcher(), mySorter);
+ if (matched != null) {
+ passResult(matched);
+ }
+ }
+
+ @NotNull
+ public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) {
+ if (!myTextBeforePosition.endsWith(matcher.getPrefix())) {
+ final int len = myTextBeforePosition.length();
+ final String fragment = len > 100 ? myTextBeforePosition.substring(len - 100) : myTextBeforePosition;
+ PsiFile positionFile = myParameters.getPosition().getContainingFile();
+ LOG.error("prefix should be some actual file string just before caret: " + matcher.getPrefix() +
+ "\n text=" + fragment +
+ "\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) +
+ "\nlang=" + positionFile.getLanguage());
+ }
+ return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
+ }
+
+ @Override
+ public void stopHere() {
+ super.stopHere();
+ if (myOriginal != null) {
+ myOriginal.stopHere();
+ }
+ }
+
+ @NotNull
+ public CompletionResultSet withPrefixMatcher(@NotNull final String prefix) {
+ return withPrefixMatcher(new CamelHumpMatcher(prefix));
+ }
+
+ @NotNull
+ @Override
+ public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) {
+ return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
+ }
+
+ @NotNull
+ @Override
+ public CompletionResultSet caseInsensitive() {
+ return withPrefixMatcher(new CamelHumpMatcher(getPrefixMatcher().getPrefix(), false));
+ }
+
+ @Override
+ public void restartCompletionOnPrefixChange(ElementPattern prefixCondition) {
+ final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
+ if (indicator != null) {
+ indicator.addWatchedPrefix(myTextBeforePosition.length() - getPrefixMatcher().getPrefix().length(), prefixCondition);
+ }
+ }
+
+ @Override
+ public void restartCompletionWhenNothingMatches() {
+ final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
+ if (indicator != null) {
+ indicator.getLookup().setStartCompletionWhenNothingMatches(true);
+ }
+ }
+ }
+
+ public static boolean assertPhase(Class extends CompletionPhase>... possibilities) {
+ if (!isPhase(possibilities)) {
+ LOG.error(ourPhase + "; set at " + ourPhaseTrace);
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isPhase(Class extends CompletionPhase>... possibilities) {
+ CompletionPhase phase = getCompletionPhase();
+ for (Class extends CompletionPhase> possibility : possibilities) {
+ if (possibility.isInstance(phase)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void setCompletionPhase(@NotNull CompletionPhase phase) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ CompletionPhase oldPhase = getCompletionPhase();
+ CompletionProgressIndicator oldIndicator = oldPhase.indicator;
+ if (oldIndicator != null && !(phase instanceof CompletionPhase.BgCalculation)) {
+ LOG.assertTrue(!oldIndicator.isRunning() || oldIndicator.isCanceled(), "don't change phase during running completion: oldPhase=" + oldPhase);
+ }
+
+ Disposer.dispose(oldPhase);
+ ourPhase = phase;
+ ourPhaseTrace = DebugUtil.currentStackTrace();
+ }
+
+ public static CompletionPhase getCompletionPhase() {
+// ApplicationManager.getApplication().assertIsDispatchThread();
+ CompletionPhase phase = getPhaseRaw();
+ ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+ if (indicator != null) {
+ indicator.checkCanceled();
+ }
+ return phase;
+ }
+
+ public static CompletionPhase getPhaseRaw() {
+ return ourPhase;
+ }
+
+ public CompletionSorterImpl defaultSorter(CompletionParameters parameters, final PrefixMatcher matcher) {
+ final CompletionLocation location = new CompletionLocation(parameters);
+
+ CompletionSorterImpl sorter = emptySorter();
+ sorter = sorter.withClassifier(new PreferStartMatching(location));
+
+ for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) {
+ final String id = weigher.toString();
+ if ("prefix".equals(id)) {
+ sorter = sorter.withClassifier(new PrefixMatchingClassifier(id, location));
+ }
+ else {
+ sorter = sorter.weigh(new LookupElementWeigher(id, true) {
+ @Override
+ public Comparable weigh(@NotNull LookupElement element) {
+ return weigher.weigh(element, location);
+ }
+ });
+ }
+
+ }
+
+ if (parameters.getCompletionType() == CompletionType.SMART) {
+ return sorter;
+ }
+
+ return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") {
+ @Override
+ public Classifier createClassifier(final Classifier next) {
+ return new LiftShorterItemsClassifier(next, new LiftShorterItemsClassifier.LiftingCondition());
+ }
+ });
+ }
+
+ public CompletionSorterImpl emptySorter() {
+ return new CompletionSorterImpl(new ArrayList>());
+ }
+
+ private static class PreferStartMatching extends ClassifierFactory {
+ private final CompletionLocation myLocation;
+
+ public PreferStartMatching(CompletionLocation location) {
+ super("startMatching");
+ myLocation = location;
+ }
+
+ @Override
+ public Classifier createClassifier(Classifier next) {
+ return new ComparingClassifier(next, "startMatching") {
+ @NotNull
+ @Override
+ public Comparable getWeight(LookupElement element) {
+ PrefixMatcher itemMatcher = myLocation.getCompletionParameters().getLookup().itemMatcher(element);
+ for (String ls : element.getAllLookupStrings()) {
+ if (itemMatcher.isStartMatch(ls)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+ }
+ }
+
+ private static class PrefixMatchingClassifier extends ClassifierFactory {
+ private final String myId;
+ private final CompletionLocation myLocation;
+
+ public PrefixMatchingClassifier(String id, CompletionLocation location) {
+ super(id);
+ myId = id;
+ myLocation = location;
+ }
+
+ @Override
+ public Classifier createClassifier(Classifier next) {
+ return new ComparingClassifier(next, myId) {
+ @NotNull
+ @Override
+ public Comparable getWeight(LookupElement element) {
+ return -getPrefixMatchingDegree(element, myLocation);
+ }
+ };
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
index 7da9e8db5386..8c74a2250ed9 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java
@@ -22,7 +22,6 @@ import com.intellij.util.ProcessingContext;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
-import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.Nullable;
@@ -35,8 +34,8 @@ import java.util.*;
public class LiftShorterItemsClassifier extends Classifier {
private final TreeSet mySortedStrings = new TreeSet();
private final MultiMap myElements = new MultiMap();
- private final Map> myToLiftForSorting = new THashMap>(TObjectHashingStrategy.IDENTITY);
- private final Map> myToLiftForPreselection = new THashMap>(TObjectHashingStrategy.IDENTITY);
+ private final Map> myToLiftForSorting = new IdentityHashMap>();
+ private final Map> myToLiftForPreselection = new IdentityHashMap>();
private final MultiMap myPrefixes = new MultiMap();
private final Classifier myNext;
private final LiftingCondition myCondition;
@@ -122,14 +121,12 @@ public class LiftShorterItemsClassifier extends Classifier {
private List liftShorterElements(Iterable source, THashSet lifted, ProcessingContext context) {
final Set srcSet = new THashSet(TObjectHashingStrategy.IDENTITY);
ContainerUtil.addAll(srcSet, source);
- final Set processed = new THashSet(TObjectHashingStrategy.IDENTITY);
+ final Set processed = new THashSet(srcSet.size(), TObjectHashingStrategy.IDENTITY);
boolean forSorting = context.get(CompletionLookupArranger.PURE_RELEVANCE) != Boolean.TRUE;
- final List result = new ArrayList();
+ final List result = new ArrayList(srcSet.size());
for (LookupElement element : myNext.classify(source, context)) {
- assert srcSet.contains(element) : myNext;
if (processed.add(element)) {
- //System.out.println("element = " + element);
List shorter = addShorterElements(srcSet, processed, null, myToLiftForPreselection.get(element));
if (forSorting) {
shorter = addShorterElements(srcSet, processed, shorter, myToLiftForSorting.get(element));
@@ -151,7 +148,6 @@ public class LiftShorterItemsClassifier extends Classifier {
@Nullable Set from) {
if (from != null) {
for (LookupElement shorterElement : from) {
- //System.out.println("shorterElement = " + shorterElement);
if (srcSet.contains(shorterElement) && processed.add(shorterElement)) {
if (toLift == null) toLift = new SmartList();
toLift.add(shorterElement);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java
index 4931b22a5d75..972109e5907d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/AnnotationHolderImpl.java
@@ -22,6 +22,7 @@ import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.AnnotationSession;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
@@ -130,7 +131,7 @@ public class AnnotationHolderImpl extends SmartList implements Annot
LOG.assertTrue(containingFile != null, node);
VirtualFile containingVFile = containingFile.getVirtualFile();
VirtualFile myVFile = myFile.getVirtualFile();
- if (containingVFile != myVFile) {
+ if (!Comparing.equal(containingVFile, myVFile)) {
LOG.error(
"Annotation must be registered for an element inside '" + myFile + "' which is in '" + myVFile + "'.\n" +
"Element passed: '" + node + "' is inside the '" + containingFile + "' which is in '" + containingVFile + "'");
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
index 1a8b9ba856d2..6b957ac47126 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
@@ -200,7 +200,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
boolean unsplit = false;
if (mySplittedWindow != null && !mySplittedWindow.isDisposed()) {
final EditorWithProviderComposite[] editors = mySplittedWindow.getEditors();
- if (editors.length == 1 && editors[0].getFile() == myNewVirtualFile) {
+ if (editors.length == 1 && Comparing.equal(editors[0].getFile(), myNewVirtualFile)) {
unsplit = true;
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
index e5980778bc7f..683009d5da22 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java
@@ -15,36 +15,31 @@
*/
package com.intellij.codeInsight.lookup;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.ForceableComparable;
import com.intellij.util.ProcessingContext;
-import gnu.trove.THashMap;
-import gnu.trove.TObjectHashingStrategy;
-import org.jetbrains.annotations.NotNull;
+import java.util.IdentityHashMap;
import java.util.Map;
/**
* @author peter
*/
public class CachingComparingClassifier extends ComparingClassifier {
- private final Map myWeights = new THashMap(TObjectHashingStrategy.IDENTITY);
+ private final Map myWeights = new IdentityHashMap();
private final LookupElementWeigher myWeigher;
- private Comparable myFirstWeight;
+ private Ref myFirstWeight;
private boolean myPrimitive = true;
public CachingComparingClassifier(Classifier next, LookupElementWeigher weigher) {
- super(next, weigher.toString());
+ super(next, weigher.toString(), weigher.isNegated());
myWeigher = weigher;
}
- @NotNull
@Override
public final Comparable getWeight(LookupElement t) {
- final Comparable weight = myWeights.get(t);
- if (weight == null) {
- throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t);
- }
- return weight;
+ return myWeights.get(t);
}
@Override
@@ -64,8 +59,8 @@ public class CachingComparingClassifier extends ComparingClassifier extends Classifier {
protected final Classifier myNext;
protected final String myName;
+ private final boolean myNegated;
public ComparingClassifier(Classifier next, String name) {
- myNext = next;
- myName = name;
+ this(next, name, false);
}
- @NotNull
+ protected ComparingClassifier(Classifier next, String name, boolean negated) {
+ myNext = next;
+ myName = name;
+ myNegated = negated;
+ }
+
+ @Nullable
public abstract Comparable getWeight(T t);
public void addElement(T t) {
myNext.addElement(t);
}
- private TreeMap> groupByWeights(Iterable source) {
- TreeMap> map = new TreeMap>();
- for (T t : source) {
- final Comparable weight = getWeight(t);
- List list = map.get(weight);
- if (list == null) {
- map.put(weight, list = new SmartList());
- }
- list.add(t);
- }
- return map;
- }
-
@Override
public Iterable classify(Iterable source, ProcessingContext context) {
- List result = new ArrayList();
- for (List list : groupByWeights(source).values()) {
- ContainerUtil.addAll(result, myNext.classify(list, context));
+ List nulls = null;
+ TreeMap> map = new TreeMap>();
+ int count = 0;
+ for (T t : myNext.classify(source, context)) {
+ count++;
+ final Comparable weight = getWeight(t);
+ if (weight == null) {
+ if (nulls == null) nulls = new SmartList();
+ nulls.add(t);
+ } else {
+ List list = map.get(weight);
+ if (list == null) {
+ map.put(weight, list = new SmartList());
+ }
+ list.add(t);
+ }
+ }
+
+ ArrayList result = new ArrayList(count);
+ Collection> values = myNegated ? map.descendingMap().values() : map.values();
+ for (List value : values) {
+ result.addAll(value);
+ }
+ if (nulls != null) {
+ result.addAll(nulls);
}
return result;
}
@Override
public void describeItems(LinkedHashMap map, ProcessingContext context) {
- final Map> treeMap = groupByWeights(new ArrayList(map.keySet()));
- if (treeMap.size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) {
- for (Map.Entry> entry: treeMap.entrySet()){
- for (T t : entry.getValue()) {
- final StringBuilder builder = map.get(t);
- if (builder.length() > 0) {
- builder.append(", ");
- }
-
- builder.append(myName).append("=").append(entry.getKey());
+ Map weights = new IdentityHashMap();
+ for (T t : map.keySet()) {
+ weights.put(t, String.valueOf(getWeight(t)));
+ }
+ if (new HashSet(weights.values()).size() > 1 || ApplicationManager.getApplication().isUnitTestMode() || true) {
+ for (T t : map.keySet()) {
+ final StringBuilder builder = map.get(t);
+ if (builder.length() > 0) {
+ builder.append(", ");
}
+ builder.append(myName).append("=").append(weights.get(t));
}
}
myNext.describeItems(map, context);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
index d505f8af1210..be1d11f253e5 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
@@ -33,10 +33,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -333,7 +330,7 @@ public class WolfTheProblemSolverImpl extends WolfTheProblemSolver {
Document document = ((TextEditor)editor).getEditor().getDocument();
PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(document);
if (psiFile == null) continue;
- if (file == psiFile.getVirtualFile()) return true;
+ if (Comparing.equal(file, psiFile.getVirtualFile())) return true;
}
return false;
}
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 e16fa6bfa9ea..5bf76d099df1 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
@@ -51,10 +51,7 @@ import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Pair;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
@@ -583,7 +580,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
myProject.getMessageBus().connect(this).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
@Override
public void fileOpened(FileEditorManager source, VirtualFile file) {
- if (file != myFile.getVirtualFile()) return;
+ if (!Comparing.equal(file, myFile.getVirtualFile())) return;
if (myConsoleEditor != null) {
Editor selectedTextEditor = source.getSelectedTextEditor();
for (FileEditor fileEditor : source.getAllEditors(file)) {
@@ -608,7 +605,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
@Override
public void fileClosed(FileEditorManager source, VirtualFile file) {
- if (file != myFile.getVirtualFile()) return;
+ if (!Comparing.equal(file, myFile.getVirtualFile())) return;
if (myUiUpdateRunnable != null && !Boolean.TRUE.equals(file.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN))) {
if (myCurrentEditor.isDisposed()) myCurrentEditor = null;
ApplicationManager.getApplication().runReadAction(myUiUpdateRunnable);
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index 9ef7a9e24def..de56727d663e 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -656,6 +656,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
if (strings.length > 0) {
document.insertString(document.getTextLength(), strings[strings.length - 1]);
+ myContentSize -= strings.length - 1;
}
}
finally {
@@ -1574,8 +1575,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
* replace text
*
* @param s text for replace
- * @param start relativly to all document text
- * @param end relativly to all document text
+ * @param start relatively to all document text
+ * @param end relatively to all document text
*/
private void replaceUserText(final String s, int start, int end) {
if (start == end) {
diff --git a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
index 825fd267402a..2e5306315a6c 100644
--- a/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
+++ b/platform/lang-impl/src/com/intellij/execution/rmi/RemoteProcessSupport.java
@@ -301,7 +301,7 @@ public abstract class RemoteProcessSupport {
RemoteDeadHand.TwoMinutesTurkish.startCooking("localhost", result.port);
}
catch (Exception e) {
- LOG.error(e);
+ LOG.warn("The cook failed to start due to " + ExceptionUtil.getRootCause(e));
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index 4b139de03afb..ded203b2c1e8 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -1,4 +1,3 @@
-
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
@@ -414,7 +413,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
if(lang == null) return NOT_FOUND_RESULT;
CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey);
- if (data == null || data.lastFile != file) {
+ if (data == null || !Comparing.equal(data.lastFile, file)) {
Lexer lexer = getLexer(file, lang);
TokenSet tokensOfInterest = TokenSet.EMPTY;
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
index 1154dc8e136f..6e9eb784ada1 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
@@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * @author Alexey
- */
package com.intellij.ide.actions;
import com.intellij.codeInsight.TargetElementUtilBase;
@@ -53,10 +49,69 @@ import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.File;
import java.io.IOException;
+import java.net.URL;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+/**
+ * @author Alexey
+ */
public class CopyReferenceAction extends AnAction {
- public static final DataFlavor ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class);
+ public static final DataFlavor ourFlavor;
+ static {
+ try {
+ ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class);
+ }
+ catch (Exception e) {
+ // todo[r.sh] delete in IDEA 12
+ final StringBuilder msg = new StringBuilder();
+ final ClassLoader loader = CopyReferenceAction.class.getClassLoader();
+ msg.append("loader=").append(loader);
+ if (loader != null) {
+ final URL url = loader.getResource("com/intellij/ide/actions/CopyReferenceAction.class");
+ msg.append(" url=").append(url);
+ if (url != null) {
+ if ("jar".equals(url.getProtocol())) {
+ String path = url.getFile();
+ msg.append(" path=").append(path);
+ if (path != null && !path.isEmpty()) {
+ if (path.startsWith("file:") && path.length() > 5) path = path.substring(5);
+ if (path.startsWith("//") && path.length() > 2) path = path.substring(2);
+ final String[] parts = path.split("!/");
+ if (parts.length == 2) {
+ try {
+ final JarFile jar = new JarFile(parts[0]);
+ try {
+ msg.append(" jar=").append(jar);
+ final ZipEntry entry = jar.getEntry(parts[1].replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class"));
+ msg.append(" entry=").append(entry);
+ }
+ finally {
+ jar.close();
+ }
+ }
+ catch (IOException e1) {
+ msg.append(" io=").append(e1.getMessage());
+ throw new RuntimeException(msg.toString(), e);
+ }
+ }
+ }
+ }
+ else {
+ final String path = url.getFile();
+ msg.append(" path=").append(path);
+ if (path != null && !path.isEmpty()) {
+ final boolean exists = new File(path.replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class")).exists();
+ msg.append(" exists=").append(exists);
+ }
+ }
+ }
+ }
+ throw new RuntimeException(msg.toString(), e);
+ }
+ }
public CopyReferenceAction() {
super();
diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java
index b2b635d7496f..b3264e0daaaa 100644
--- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java
+++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkManager.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -79,7 +80,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist
public void run() {
if (myProject.isDisposed()) return;
for (Bookmark bookmark : myBookmarks) {
- if (bookmark.getFile() == file) {
+ if (Comparing.equal(bookmark.getFile(), file)) {
bookmark.createHighlighter((MarkupModelEx)DocumentMarkupModel.forDocument(document, myProject, true));
}
}
@@ -165,7 +166,7 @@ public class BookmarkManager extends AbstractProjectComponent implements Persist
@Nullable
public Bookmark findFileBookmark(@NotNull VirtualFile file) {
for (Bookmark bookmark : myBookmarks) {
- if (bookmark.getFile() == file && bookmark.getLine() == -1) return bookmark;
+ if (Comparing.equal(bookmark.getFile(), file) && bookmark.getLine() == -1) return bookmark;
}
return null;
diff --git a/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java b/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java
index aa3f1174dca1..9c8ca5ae68e1 100644
--- a/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java
+++ b/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
@@ -104,7 +105,7 @@ public class PatchProjectUtil {
if (included.isEmpty()) return;
final Set parents = new HashSet();
for (VirtualFile file : included) {
- if (file == contentEntry.getFile()) return;
+ if (Comparing.equal(file, contentEntry.getFile())) return;
final VirtualFile parent = file.getParent();
if (parent == null || parents.contains(parent)) continue;
parents.add(parent);
diff --git a/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java
index c7598d63b6d9..72f89bfaa6d0 100644
--- a/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java
+++ b/platform/lang-impl/src/com/intellij/ide/impl/ProjectPaneSelectInTarget.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFileSystemItem;
@@ -57,7 +58,7 @@ public class ProjectPaneSelectInTarget extends ProjectViewSelectInTarget impleme
return true;
}
- return vFile.getParent() == myProject.getBaseDir();
+ return Comparing.equal(vFile.getParent(), myProject.getBaseDir());
}
return false;
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java
index b821f227bbac..4216e5753b28 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootAction.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -65,7 +66,7 @@ public class MarkRootAction extends AnAction {
if (entry != null) {
final SourceFolder[] sourceFolders = entry.getSourceFolders();
for (SourceFolder sourceFolder : sourceFolders) {
- if (sourceFolder.getFile() == vFile) {
+ if (Comparing.equal(sourceFolder.getFile(), vFile)) {
entry.removeSourceFolder(sourceFolder);
break;
}
@@ -126,7 +127,7 @@ public class MarkRootAction extends AnAction {
if (!fileIndex.isInContent(vFile)) {
return false;
}
- if (fileIndex.getSourceRootForFile(vFile) == vFile) {
+ if (Comparing.equal(fileIndex.getSourceRootForFile(vFile), vFile)) {
boolean isTestSourceRoot = fileIndex.isInTestSourceContent(vFile);
if (acceptSourceRoot && !isTestSourceRoot) {
if (rootType != null) rootType.set(true);
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
index 84109a989960..42dc2bd3954e 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
@@ -18,6 +18,7 @@ package com.intellij.ide.projectView.impl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -63,7 +64,7 @@ public class ProjectRootsUtil {
for (ContentEntry contentEntry : contentEntries) {
final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
for (SourceFolder sourceFolder : sourceFolders) {
- if (virtualFile == sourceFolder.getFile()) return true;
+ if (Comparing.equal(virtualFile, sourceFolder.getFile())) return true;
}
}
return false;
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
index e621f8dac500..c897b0d765fd 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
@@ -113,7 +113,7 @@ public class ProjectViewDirectoryHelper {
public boolean canRepresent(Object element, PsiDirectory directory) {
if (element instanceof VirtualFile) {
VirtualFile vFile = (VirtualFile) element;
- return directory.getVirtualFile() == vFile;
+ return Comparing.equal(directory.getVirtualFile(), vFile);
}
return false;
}
@@ -180,7 +180,7 @@ public class ProjectViewDirectoryHelper {
while (current != null) {
VirtualFile parent = current.getParent();
- if (parent == dir) {
+ if (Comparing.equal(parent, dir)) {
final PsiDirectory psi = manager.findDirectory(current);
if (psi != null) {
directoriesOnTheWayToContentRoots.add(psi);
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
index 79c443dd51aa..9a35f9b89676 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java
@@ -298,7 +298,7 @@ public class PsiDirectoryNode extends BasePsiNode implements Navig
if (ProjectAttachProcessor.canAttachToProject()) {
// primary module is always on top; attached modules are sorted alphabetically
final VirtualFile file = getVirtualFile();
- if (file == myProject.getBaseDir()) {
+ if (Comparing.equal(file, myProject.getBaseDir())) {
return ""; // sorts before any other name
}
return getTitle();
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java
index b53889ffb4d1..d7258fcd05a4 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiFileNode.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.JarFileSystem;
@@ -175,6 +176,6 @@ public class PsiFileNode extends BasePsiNode implements NavigatableWith
@Override
public boolean contains(@NotNull VirtualFile file) {
- return super.contains(file) || isArchive() && PathUtil.getLocalFile(file) == getVirtualFile();
+ return super.contains(file) || isArchive() && Comparing.equal(PathUtil.getLocalFile(file), getVirtualFile());
}
}
diff --git a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java
index d5a4fa9703f8..a5aa44f17a8a 100644
--- a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java
+++ b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.impl.FilePropertyPusher;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.testFramework.LightVirtualFile;
@@ -76,7 +77,7 @@ public abstract class LanguagePerFileMappings implements PersistentStateCompo
file = window.getDelegate();
}
VirtualFile originalFile = file instanceof LightVirtualFile ? ((LightVirtualFile)file).getOriginalFile() : null;
- if (originalFile == file) originalFile = null;
+ if (Comparing.equal(originalFile, file)) originalFile = null;
if (file != null) {
final FilePropertyPusher pusher = getFilePropertyPusher();
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
index 5118581eb4ef..bd6b2dece58e 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/PsiAwareFileEditorManagerImpl.java
@@ -1,168 +1,170 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.openapi.fileEditor.impl;
-
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleUtil;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.problems.WolfTheProblemSolver;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.ui.ColorUtil;
-import com.intellij.ui.docking.DockManager;
-import org.jetbrains.annotations.NotNull;
-
-import java.awt.*;
-
-/**
- * @author yole
- */
-public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.PsiAwareFileEditorManagerImpl");
-
- private final PsiManager myPsiManager;
- private final WolfTheProblemSolver myProblemSolver;
-
- /**
- * Updates icons for open files when project roots change
- */
- private final MyPsiTreeChangeListener myPsiTreeChangeListener;
- private final WolfTheProblemSolver.ProblemListener myProblemListener;
-
- public PsiAwareFileEditorManagerImpl(final Project project, final PsiManager psiManager, final WolfTheProblemSolver problemSolver, DockManager dockManager) {
- super(project, dockManager);
- myPsiManager = psiManager;
- myProblemSolver = problemSolver;
- myPsiTreeChangeListener = new MyPsiTreeChangeListener();
- myProblemListener = new MyProblemListener();
- registerExtraEditorDataProvider(new TextEditorPsiDataProvider(), null);
- }
-
- @Override
- public void projectOpened() {
- super.projectOpened(); //To change body of overridden methods use File | Settings | File Templates.
- myPsiManager.addPsiTreeChangeListener(myPsiTreeChangeListener);
- myProblemSolver.addProblemListener(myProblemListener);
- }
-
- @Override
- public Color getFileColor(@NotNull final VirtualFile file) {
- Color color = super.getFileColor(file);
- if (myProblemSolver.isProblemFile(file)) {
- return ColorUtil.toAlpha(color, WaverGraphicsDecorator.WAVE_ALPHA_KEY);
- }
- return color;
- }
-
- public boolean isProblem(@NotNull final VirtualFile file) {
- return myProblemSolver.isProblemFile(file);
- }
-
- public String getFileTooltipText(final VirtualFile file) {
- final StringBuilder tooltipText = new StringBuilder();
- final Module module = ModuleUtil.findModuleForFile(file, getProject());
- if (module != null) {
- tooltipText.append("[");
- tooltipText.append(module.getName());
- tooltipText.append("] ");
- }
- tooltipText.append(FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl()));
- return tooltipText.toString();
- }
-
- @Override
- protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) {
- PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
- Document document = editor.getDocument();
- PsiFile psiFile = documentManager.getPsiFile(document);
- if (!focusEditor || documentManager.isUncommited(document)) {
- return editor;
- }
-
- return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile);
- }
-
- /**
- * Updates attribute of open files when roots change
- */
- private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
- public void propertyChanged(@NotNull final PsiTreeChangeEvent e) {
- if (PsiTreeChangeEvent.PROP_ROOTS.equals(e.getPropertyName())) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- final VirtualFile[] openFiles = getOpenFiles();
- for (int i = openFiles.length - 1; i >= 0; i--) {
- final VirtualFile file = openFiles[i];
- LOG.assertTrue(file != null);
- updateFileIcon(file);
- }
- }
- }
-
- public void childAdded(@NotNull PsiTreeChangeEvent event) {
- doChange(event);
- }
-
- public void childRemoved(@NotNull PsiTreeChangeEvent event) {
- doChange(event);
- }
-
- public void childReplaced(@NotNull PsiTreeChangeEvent event) {
- doChange(event);
- }
-
- public void childMoved(@NotNull PsiTreeChangeEvent event) {
- doChange(event);
- }
-
- public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
- doChange(event);
- }
-
- private void doChange(final PsiTreeChangeEvent event) {
- final PsiFile psiFile = event.getFile();
- final VirtualFile currentFile = getCurrentFile();
- if (currentFile != null && psiFile != null && psiFile.getVirtualFile() == currentFile) {
- updateFileIcon(currentFile);
- }
- }
- }
-
- private class MyProblemListener extends WolfTheProblemSolver.ProblemListener {
- public void problemsAppeared(final VirtualFile file) {
- updateFile(file);
- }
-
- public void problemsDisappeared(VirtualFile file) {
- updateFile(file);
- }
-
- public void problemsChanged(VirtualFile file) {
- updateFile(file);
- }
-
- private void updateFile(final VirtualFile file) {
- queueUpdateFile(file);
- }
- }
-}
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.fileEditor.impl;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.problems.WolfTheProblemSolver;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.ui.ColorUtil;
+import com.intellij.ui.docking.DockManager;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.text.PsiAwareFileEditorManagerImpl");
+
+ private final PsiManager myPsiManager;
+ private final WolfTheProblemSolver myProblemSolver;
+
+ /**
+ * Updates icons for open files when project roots change
+ */
+ private final MyPsiTreeChangeListener myPsiTreeChangeListener;
+ private final WolfTheProblemSolver.ProblemListener myProblemListener;
+
+ public PsiAwareFileEditorManagerImpl(final Project project, final PsiManager psiManager, final WolfTheProblemSolver problemSolver, DockManager dockManager) {
+ super(project, dockManager);
+ myPsiManager = psiManager;
+ myProblemSolver = problemSolver;
+ myPsiTreeChangeListener = new MyPsiTreeChangeListener();
+ myProblemListener = new MyProblemListener();
+ registerExtraEditorDataProvider(new TextEditorPsiDataProvider(), null);
+ }
+
+ @Override
+ public void projectOpened() {
+ super.projectOpened(); //To change body of overridden methods use File | Settings | File Templates.
+ myPsiManager.addPsiTreeChangeListener(myPsiTreeChangeListener);
+ myProblemSolver.addProblemListener(myProblemListener);
+ }
+
+ @Override
+ public Color getFileColor(@NotNull final VirtualFile file) {
+ Color color = super.getFileColor(file);
+ if (myProblemSolver.isProblemFile(file)) {
+ return ColorUtil.toAlpha(color, WaverGraphicsDecorator.WAVE_ALPHA_KEY);
+ }
+ return color;
+ }
+
+ public boolean isProblem(@NotNull final VirtualFile file) {
+ return myProblemSolver.isProblemFile(file);
+ }
+
+ public String getFileTooltipText(final VirtualFile file) {
+ final StringBuilder tooltipText = new StringBuilder();
+ final Module module = ModuleUtil.findModuleForFile(file, getProject());
+ if (module != null) {
+ tooltipText.append("[");
+ tooltipText.append(module.getName());
+ tooltipText.append("] ");
+ }
+ tooltipText.append(FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl()));
+ return tooltipText.toString();
+ }
+
+ @Override
+ protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) {
+ PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
+ Document document = editor.getDocument();
+ PsiFile psiFile = documentManager.getPsiFile(document);
+ if (!focusEditor || documentManager.isUncommited(document)) {
+ return editor;
+ }
+
+ return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, psiFile);
+ }
+
+ /**
+ * Updates attribute of open files when roots change
+ */
+ private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
+ public void propertyChanged(@NotNull final PsiTreeChangeEvent e) {
+ if (PsiTreeChangeEvent.PROP_ROOTS.equals(e.getPropertyName())) {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ final VirtualFile[] openFiles = getOpenFiles();
+ for (int i = openFiles.length - 1; i >= 0; i--) {
+ final VirtualFile file = openFiles[i];
+ LOG.assertTrue(file != null);
+ updateFileIcon(file);
+ }
+ }
+ }
+
+ public void childAdded(@NotNull PsiTreeChangeEvent event) {
+ doChange(event);
+ }
+
+ public void childRemoved(@NotNull PsiTreeChangeEvent event) {
+ doChange(event);
+ }
+
+ public void childReplaced(@NotNull PsiTreeChangeEvent event) {
+ doChange(event);
+ }
+
+ public void childMoved(@NotNull PsiTreeChangeEvent event) {
+ doChange(event);
+ }
+
+ public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
+ doChange(event);
+ }
+
+ private void doChange(final PsiTreeChangeEvent event) {
+ final PsiFile psiFile = event.getFile();
+ final VirtualFile currentFile = getCurrentFile();
+ if (currentFile != null && psiFile != null && Comparing.equal(psiFile.getVirtualFile(), currentFile)) {
+ updateFileIcon(currentFile);
+ }
+ }
+ }
+
+ private class MyProblemListener extends WolfTheProblemSolver.ProblemListener {
+ public void problemsAppeared(final VirtualFile file) {
+ updateFile(file);
+ }
+
+ public void problemsDisappeared(VirtualFile file) {
+ updateFile(file);
+ }
+
+ public void problemsChanged(VirtualFile file) {
+ updateFile(file);
+ }
+
+ private void updateFile(final VirtualFile file) {
+ queueUpdateFile(file);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java
index 26ac8a341b86..44b42d3dfcc8 100644
--- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/TestEditorManagerImpl.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.fileEditor.impl.text.TextEditorPsiDataProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.AsyncResult;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -331,7 +332,7 @@ import java.util.Map;
if (editor != null){
EditorFactory.getInstance().releaseEditor(editor);
}
- if (file == myActiveFile) myActiveFile = null;
+ if (Comparing.equal(file, myActiveFile)) myActiveFile = null;
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java
index 5910887431b7..99520def4ac9 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/patch/PsiPatchBaseDirectoryDetector.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
@@ -47,7 +48,7 @@ public class PsiPatchBaseDirectoryDetector extends PatchBaseDirectoryDetector {
if (psiFiles.length == 1) {
PsiDirectory parent = psiFiles [0].getContainingDirectory();
for(int i=nameComponents.length-2; i >= 0; i--) {
- if (!parent.getName().equals(nameComponents [i]) || parent.getVirtualFile() == myProject.getBaseDir()) {
+ if (!parent.getName().equals(nameComponents[i]) || Comparing.equal(parent.getVirtualFile(), myProject.getBaseDir())) {
return new Result(parent.getVirtualFile().getPresentableUrl(), i+1);
}
parent = parent.getParentDirectory();
diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java
index c44bf20793d9..2bde879b0205 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesModuleGroupingPolicy.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +49,7 @@ public class ChangesModuleGroupingPolicy implements ChangesGroupingPolicy {
ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
VirtualFile vFile = node.getVf();
- if (vFile != null && vFile == index.getContentRootForFile(vFile)) {
+ if (vFile != null && Comparing.equal(vFile, index.getContentRootForFile(vFile))) {
Module module = index.getModuleForFile(vFile);
return getNodeForModule(module, rootNode);
}
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
index ff4f11f5e5e0..21ec2f02fcf1 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DirectoryNode.java
@@ -21,6 +21,7 @@ import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -61,12 +62,12 @@ public class DirectoryNode extends PackageDependenciesNode {
if (showFQName) {
final VirtualFile contentRoot = index.getContentRootForFile(myVDirectory);
if (contentRoot != null) {
- if (myVDirectory == contentRoot) {
+ if (Comparing.equal(myVDirectory, contentRoot)) {
myFQName = dirName;
}
else {
final VirtualFile sourceRoot = index.getSourceRootForFile(myVDirectory);
- if (myVDirectory == sourceRoot) {
+ if (Comparing.equal(myVDirectory, sourceRoot)) {
myFQName = VfsUtilCore.getRelativePath(myVDirectory, contentRoot, '/');
}
else if (sourceRoot != null) {
@@ -96,10 +97,11 @@ public class DirectoryNode extends PackageDependenciesNode {
private String getContentRootName(final VirtualFile baseDir, final String dirName) {
if (baseDir != null) {
- if (myVDirectory != baseDir) {
+ if (!Comparing.equal(myVDirectory, baseDir)) {
if (VfsUtil.isAncestor(baseDir, myVDirectory, false)) {
return VfsUtilCore.getRelativePath(myVDirectory, baseDir, '/');
- } else {
+ }
+ else {
return myVDirectory.getPresentableUrl();
}
}
@@ -140,7 +142,7 @@ public class DirectoryNode extends PackageDependenciesNode {
final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
VirtualFile directory = myVDirectory;
VirtualFile contentRoot = index.getContentRootForFile(directory);
- if (directory == contentRoot) {
+ if (Comparing.equal(directory, contentRoot)) {
return "";
}
if (contentRoot == null) {
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java
index 2d5ad682d109..ce552ade2d90 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/FileTreeModelBuilder.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
@@ -431,7 +432,7 @@ public class FileTreeModelBuilder {
else if (node instanceof FileNode) { //non java files
psiFile = ((PsiFile)node.getPsiElement());
}
- if (psiFile != null && psiFile.getVirtualFile() == ((PsiFile)element).getVirtualFile()) {
+ if (psiFile != null && Comparing.equal(psiFile.getVirtualFile(), ((PsiFile)element).getVirtualFile())) {
result.add(node);
}
}
@@ -497,7 +498,7 @@ public class FileTreeModelBuilder {
final VirtualFile directory = virtualFile.getParent();
if (!myFlattenPackages && directory != null) {
- if (myCompactEmptyMiddlePackages && sourceRoot != virtualFile && contentRoot != virtualFile) {//compact
+ if (myCompactEmptyMiddlePackages && !Comparing.equal(sourceRoot, virtualFile) && !Comparing.equal(contentRoot, virtualFile)) {//compact
((DirectoryNode)directoryNode).setCompactedDirNode(childNode);
}
if (fileIndex.getModuleForFile(directory) == module) {
@@ -505,7 +506,7 @@ public class FileTreeModelBuilder {
if (parentDirectoryNode != null
|| !myCompactEmptyMiddlePackages
|| (sourceRoot != null && VfsUtil.isAncestor(directory, sourceRoot, false) && fileIndex.getSourceRootForFile(directory) != null)
- || directory == contentRoot) {
+ || Comparing.equal(directory, contentRoot)) {
getModuleDirNode(directory, module, (DirectoryNode)directoryNode).add(directoryNode);
}
else {
@@ -517,15 +518,18 @@ public class FileTreeModelBuilder {
}
}
else {
- if (contentRoot == virtualFile) {
+ if (Comparing.equal(contentRoot, virtualFile)) {
getModuleNode(module).add(directoryNode);
- } else {
+ }
+ else {
final VirtualFile root;
- if (sourceRoot != virtualFile && sourceRoot != null) {
+ if (!Comparing.equal(sourceRoot, virtualFile) && sourceRoot != null) {
root = sourceRoot;
- } else if (contentRoot != null) {
+ }
+ else if (contentRoot != null) {
root = contentRoot;
- } else {
+ }
+ else {
root = null;
}
if (root != null) {
@@ -586,7 +590,7 @@ public class FileTreeModelBuilder {
public boolean processFile(VirtualFile fileOrDir) {
if (!fileOrDir.isDirectory()) {
- if (lastParent != null && dir != fileOrDir.getParent()) {
+ if (lastParent != null && !Comparing.equal(dir, fileOrDir.getParent())) {
lastParent = null;
}
lastParent = buildFileNode(fileOrDir, lastParent);
diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
index 188c848c7d8e..94da68fb6c47 100644
--- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
+++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.project.ex.ProjectManagerEx;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.AbstractVcs;
@@ -160,7 +161,7 @@ public class ModuleAttachProcessor extends ProjectAttachProcessor {
for (Module module : ModuleManager.getInstance(project).getModules()) {
final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots();
for (VirtualFile root : roots) {
- if (root == project.getBaseDir()) {
+ if (Comparing.equal(root, project.getBaseDir())) {
return module;
}
}
diff --git a/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java b/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java
index bd2681310c9a..f277acd8c552 100644
--- a/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java
+++ b/platform/lang-impl/src/com/intellij/platform/PlatformProjectViewStructureProvider.java
@@ -23,6 +23,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -43,7 +44,7 @@ public class PlatformProjectViewStructureProvider implements TreeStructureProvid
public Collection modify(final AbstractTreeNode parent, final Collection children, final ViewSettings settings) {
if (parent instanceof PsiDirectoryNode) {
final VirtualFile vFile = ((PsiDirectoryNode)parent).getVirtualFile();
- if (vFile != null && ProjectFileIndex.SERVICE.getInstance(myProject).getContentRootForFile(vFile) == vFile) {
+ if (vFile != null && Comparing.equal(ProjectFileIndex.SERVICE.getInstance(myProject).getContentRootForFile(vFile), vFile)) {
final Collection moduleChildren = ((PsiDirectoryNode) parent).getChildren();
Collection result = new ArrayList();
for (AbstractTreeNode moduleChild : moduleChildren) {
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java
index 8fd306cb49b1..628dd65c6005 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/FileElementInfo.java
@@ -71,7 +71,7 @@ class FileElementInfo implements SmartPointerElementInfo {
@Override
public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
if (other instanceof FileElementInfo) {
- return myVirtualFile == ((FileElementInfo)other).myVirtualFile;
+ return Comparing.equal(myVirtualFile, ((FileElementInfo)other).myVirtualFile);
}
return Comparing.equal(restoreElement(), other.restoreElement());
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java
index c8d1b63fb577..423d187dff4f 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java
@@ -286,12 +286,12 @@ public class SelfElementInfo implements SmartPointerElementInfo {
public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
if (other instanceof SelfElementInfo) {
SelfElementInfo otherInfo = (SelfElementInfo)other;
- return myVirtualFile == otherInfo.myVirtualFile
- && myType == otherInfo.myType
- && mySyncMarkerIsValid
- && otherInfo.mySyncMarkerIsValid
- && mySyncStartOffset == otherInfo.mySyncStartOffset
- && mySyncEndOffset == otherInfo.mySyncEndOffset
+ return Comparing.equal(myVirtualFile, otherInfo.myVirtualFile)
+ && myType == otherInfo.myType
+ && mySyncMarkerIsValid
+ && otherInfo.mySyncMarkerIsValid
+ && mySyncStartOffset == otherInfo.mySyncStartOffset
+ && mySyncEndOffset == otherInfo.mySyncEndOffset
;
}
return Comparing.equal(restoreElement(), other.restoreElement());
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java
index fb8b400ebbcf..70430ac59874 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/PsiFileReferenceHelper.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.DirectoryIndex;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -84,7 +85,7 @@ public class PsiFileReferenceHelper extends FileReferenceHelper {
if (orderEntry instanceof ModuleSourceOrderEntry) {
for(ContentEntry e: ((ModuleSourceOrderEntry)orderEntry).getRootModel().getContentEntries()) {
for(SourceFolder sf:e.getSourceFolders()) {
- if (sf.getFile() == root) {
+ if (Comparing.equal(sf.getFile(), root)) {
String s = sf.getPackagePrefix();
if (s.length() > 0) {
path = s + "." + path;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
index d1ee84f27989..615c58974177 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
@@ -345,7 +345,10 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
assert documentWindow.getText().equals(psiFile.getText()) : "Document window text mismatch";
assert injectedFileViewProvider.getDocument() == documentWindow : "Provider document mismatch";
assert documentManager.getCachedDocument(psiFile) == documentWindow : "Cached document mismatch";
- assert psiFile.getVirtualFile() == injectedFileViewProvider.getVirtualFile() : "Virtual file mismatch: "+psiFile.getVirtualFile()+"; "+injectedFileViewProvider.getVirtualFile();
+ assert Comparing.equal(psiFile.getVirtualFile(), injectedFileViewProvider.getVirtualFile()) : "Virtual file mismatch: " +
+ psiFile.getVirtualFile() +
+ "; " +
+ injectedFileViewProvider.getVirtualFile();
PsiDocumentManagerImpl.checkConsistency(psiFile, documentWindow);
}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
index 5e1d334817f7..d826950a525b 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/DirectoryAsPackageRenameHandlerBase.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
@@ -67,7 +68,7 @@ public abstract class DirectoryAsPackageRenameHandlerBase> myIndexStamps;
- private boolean myIsDirty = false;
-
- private Timestamps(@Nullable DataInputStream stream) throws IOException {
- if (stream != null) {
- try {
- if (stream.available() > 0) {
- long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream);
- while(stream.available() > 0) {
- ID, ?> id = ID.findById(DataInputOutputUtil.readINT(stream));
- if (id != null) {
- long stamp = IndexInfrastructure.getIndexCreationStamp(id);
- if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f);
- if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp);
- }
- }
- }
- }
- finally {
- stream.close();
- }
- }
- }
-
- private void writeToStream(final DataOutputStream stream) throws IOException {
- if (myIndexStamps != null) {
- final long[] dominatingIndexStamp = new long[1];
- myIndexStamps.forEachEntry(
- new TObjectLongProcedure>() {
- @Override
- public boolean execute(ID, ?> a, long b) {
- dominatingIndexStamp[0] = Math.max(dominatingIndexStamp[0], b);
- return true;
- }
- }
- );
- DataInputOutputUtil.writeTIME(stream, dominatingIndexStamp[0]);
- myIndexStamps.forEachEntry(new TObjectLongProcedure>() {
- @Override
- public boolean execute(final ID, ?> id, final long timestamp) {
- try {
- DataInputOutputUtil.writeINT(stream, id.getUniqueId());
- return true;
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- });
- }
- }
-
- public long get(ID, ?> id) {
- return myIndexStamps != null? myIndexStamps.get(id) : 0L;
- }
-
- public void set(ID, ?> id, long tmst) {
- try {
- if (tmst < 0) {
- if (myIndexStamps == null) return;
- myIndexStamps.remove(id);
- return;
- }
- if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f);
-
- myIndexStamps.put(id, tmst);
- }
- finally {
- myIsDirty = true;
- }
- }
-
- public boolean isDirty() {
- return myIsDirty;
- }
- }
-
- private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap();
- private static final int CAPACITY = 100;
- private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY);
-
- public static boolean isFileIndexed(VirtualFile file, ID, ?> indexName, final long indexCreationStamp) {
- try {
- return getIndexStamp(file, indexName) == indexCreationStamp;
- }
- catch (RuntimeException e) {
- final Throwable cause = e.getCause();
- if (!(cause instanceof IOException)) {
- throw e; // in case of IO exceptions consider file unindexed
- }
- }
-
- return false;
- }
-
- public static long getIndexStamp(VirtualFile file, ID, ?> indexName) {
- synchronized (file) {
- Timestamps stamp = createOrGetTimeStamp(file);
- if (stamp != null) return stamp.get(indexName);
- return 0;
- }
- }
-
- private static Timestamps createOrGetTimeStamp(VirtualFile file) {
- if (file instanceof NewVirtualFile && file.isValid()) {
- Timestamps timestamps = myTimestampsCache.get(file);
- if (timestamps == null) {
- synchronized (myTimestampsCache) { // avoid synchroneous reads TODO:
- timestamps = myTimestampsCache.get(file);
- if (timestamps == null) {
- final DataInputStream stream = Timestamps.PERSISTENCE.readAttribute(file);
- try {
- timestamps = new Timestamps(stream);
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- myTimestampsCache.put(file, timestamps);
- }
- }
- }
- return timestamps;
- }
- return null;
- }
-
- public static void update(final VirtualFile file, final ID, ?> indexName, final long indexCreationStamp) {
- synchronized (file) {
- try {
- Timestamps stamp = createOrGetTimeStamp(file);
- if (stamp != null) stamp.set(indexName, indexCreationStamp);
- }
- catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) {
- }
- }
- }
-
- public static void flushCache(@Nullable VirtualFile finishedFile) {
- if (finishedFile == null || !myFinishedFiles.offer(finishedFile)) {
- VirtualFile[] files = null;
- synchronized (myFinishedFiles) {
- int size = myFinishedFiles.size();
- if ((finishedFile == null && size > 0) || size == CAPACITY) {
- files = myFinishedFiles.toArray(new VirtualFile[size]);
- myFinishedFiles.clear();
- }
- }
-
- if (files != null) {
- for(VirtualFile file:files) {
- synchronized (file) {
- Timestamps timestamp = myTimestampsCache.remove(file);
- if (timestamp == null) continue;
- synchronized (myTimestampsCache) {
- try {
- if (timestamp.isDirty() && file.isValid()) {
- final DataOutputStream sink = Timestamps.PERSISTENCE.writeAttribute(file);
- timestamp.writeToStream(sink);
- sink.close();
- }
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- }
- if (finishedFile != null) myFinishedFiles.offer(finishedFile);
- }
- }
-}
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.indexing;
+
+import com.intellij.openapi.vfs.InvalidVirtualFileAccessException;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.newvfs.FileAttribute;
+import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.util.containers.ConcurrentHashMap;
+import com.intellij.util.io.DataInputOutputUtil;
+import gnu.trove.TObjectLongHashMap;
+import gnu.trove.TObjectLongProcedure;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.concurrent.ArrayBlockingQueue;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Dec 25, 2007
+ */
+public class IndexingStamp {
+ private IndexingStamp() {
+ }
+
+ /**
+ * The class is meant to be accessed from synchronized block only
+ */
+ private static class Timestamps {
+ private static final FileAttribute PERSISTENCE = new FileAttribute("__index_stamps__", 1, false);
+ private TObjectLongHashMap> myIndexStamps;
+ private boolean myIsDirty = false;
+
+ private Timestamps(@Nullable DataInputStream stream) throws IOException {
+ if (stream != null) {
+ try {
+
+ long dominatingIndexStamp = DataInputOutputUtil.readTIME(stream);
+ while(stream.available() > 0) {
+ ID, ?> id = ID.findById(DataInputOutputUtil.readINT(stream));
+ if (id != null) {
+ long stamp = IndexInfrastructure.getIndexCreationStamp(id);
+ if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f);
+ if (stamp <= dominatingIndexStamp) myIndexStamps.put(id, stamp);
+ }
+ }
+ }
+ finally {
+ stream.close();
+ }
+ }
+ }
+
+ private void writeToStream(final DataOutputStream stream) throws IOException {
+ if (myIndexStamps != null && !myIndexStamps.isEmpty()) {
+ final long[] dominatingIndexStamp = new long[1];
+ myIndexStamps.forEachEntry(
+ new TObjectLongProcedure>() {
+ @Override
+ public boolean execute(ID, ?> a, long b) {
+ dominatingIndexStamp[0] = Math.max(dominatingIndexStamp[0], b);
+ return true;
+ }
+ }
+ );
+ DataInputOutputUtil.writeTIME(stream, dominatingIndexStamp[0]);
+ myIndexStamps.forEachEntry(new TObjectLongProcedure>() {
+ @Override
+ public boolean execute(final ID, ?> id, final long timestamp) {
+ try {
+ DataInputOutputUtil.writeINT(stream, id.getUniqueId());
+ return true;
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ } else {
+ DataInputOutputUtil.writeTIME(stream, DataInputOutputUtil.timeBase);
+ }
+ }
+
+ public long get(ID, ?> id) {
+ return myIndexStamps != null? myIndexStamps.get(id) : 0L;
+ }
+
+ public void set(ID, ?> id, long tmst) {
+ try {
+ if (tmst < 0) {
+ if (myIndexStamps == null) return;
+ myIndexStamps.remove(id);
+ return;
+ }
+ if (myIndexStamps == null) myIndexStamps = new TObjectLongHashMap>(5, 0.98f);
+
+ myIndexStamps.put(id, tmst);
+ }
+ finally {
+ myIsDirty = true;
+ }
+ }
+
+ public boolean isDirty() {
+ return myIsDirty;
+ }
+ }
+
+ private static final ConcurrentHashMap myTimestampsCache = new ConcurrentHashMap();
+ private static final int CAPACITY = 100;
+ private static final ArrayBlockingQueue myFinishedFiles = new ArrayBlockingQueue(CAPACITY);
+
+ public static boolean isFileIndexed(VirtualFile file, ID, ?> indexName, final long indexCreationStamp) {
+ try {
+ return getIndexStamp(file, indexName) == indexCreationStamp;
+ }
+ catch (RuntimeException e) {
+ final Throwable cause = e.getCause();
+ if (!(cause instanceof IOException)) {
+ throw e; // in case of IO exceptions consider file unindexed
+ }
+ }
+
+ return false;
+ }
+
+ public static long getIndexStamp(VirtualFile file, ID, ?> indexName) {
+ synchronized (file) {
+ Timestamps stamp = createOrGetTimeStamp(file);
+ if (stamp != null) return stamp.get(indexName);
+ return 0;
+ }
+ }
+
+ private static Timestamps createOrGetTimeStamp(VirtualFile file) {
+ if (file instanceof NewVirtualFile && file.isValid()) {
+ Timestamps timestamps = myTimestampsCache.get(file);
+ if (timestamps == null) {
+ synchronized (myTimestampsCache) { // avoid synchroneous reads TODO:
+ timestamps = myTimestampsCache.get(file);
+ if (timestamps == null) {
+ final DataInputStream stream = Timestamps.PERSISTENCE.readAttribute(file);
+ try {
+ timestamps = new Timestamps(stream);
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ myTimestampsCache.put(file, timestamps);
+ }
+ }
+ }
+ return timestamps;
+ }
+ return null;
+ }
+
+ public static void update(final VirtualFile file, final ID, ?> indexName, final long indexCreationStamp) {
+ synchronized (file) {
+ try {
+ Timestamps stamp = createOrGetTimeStamp(file);
+ if (stamp != null) stamp.set(indexName, indexCreationStamp);
+ }
+ catch (InvalidVirtualFileAccessException ignored /*ok to ignore it here*/) {
+ }
+ }
+ }
+
+ public static void flushCache(@Nullable VirtualFile finishedFile) {
+ if (finishedFile == null || !myFinishedFiles.offer(finishedFile)) {
+ VirtualFile[] files = null;
+ synchronized (myFinishedFiles) {
+ int size = myFinishedFiles.size();
+ if ((finishedFile == null && size > 0) || size == CAPACITY) {
+ files = myFinishedFiles.toArray(new VirtualFile[size]);
+ myFinishedFiles.clear();
+ }
+ }
+
+ if (files != null) {
+ for(VirtualFile file:files) {
+ synchronized (file) {
+ Timestamps timestamp = myTimestampsCache.remove(file);
+ if (timestamp == null) continue;
+ synchronized (myTimestampsCache) {
+ try {
+ if (timestamp.isDirty() && file.isValid()) {
+ final DataOutputStream sink = Timestamps.PERSISTENCE.writeAttribute(file);
+ timestamp.writeToStream(sink);
+ sink.close();
+ }
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ }
+ if (finishedFile != null) myFinishedFiles.offer(finishedFile);
+ }
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
index ec32b3994d56..06e833173d78 100644
--- a/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
+++ b/platform/lang-impl/src/com/intellij/util/ui/tree/AbstractFileTreeTable.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
@@ -212,7 +213,7 @@ public abstract class AbstractFileTreeTable extends TreeTable {
TreeNode child = root.getChildAt(i);
VirtualFile file = ((FileNode)child).getObject();
if (VfsUtil.isAncestor(file, toSelect, false)) {
- if (file == toSelect) {
+ if (Comparing.equal(file, toSelect)) {
TreeUtil.selectNode(getTree(), child);
getSelectionModel().clearSelection();
addSelectedPath(TreeUtil.getPathFromRoot(child));
diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
index 4b13d2a3929c..18308cb9e751 100644
--- a/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
+++ b/platform/lvcs-impl/src/com/intellij/history/integration/IdeaGateway.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Clock;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.*;
@@ -60,7 +61,7 @@ public class IdeaGateway {
for (Project each : openProjects) {
if (each.isDefault()) continue;
if (!each.isInitialized()) continue;
- if (each.getWorkspaceFile() == f) return false;
+ if (Comparing.equal(each.getWorkspaceFile(), f)) return false;
if (ProjectRootManager.getInstance(each).getFileIndex().isIgnored(f)) return false;
}
diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java
index 8c6a3c7cdb78..3d2edf2f2988 100644
--- a/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java
+++ b/platform/lvcs-impl/src/com/intellij/history/integration/revertion/UndoChangeRevertingVisitor.java
@@ -25,6 +25,7 @@ import com.intellij.history.integration.IdeaGateway;
import com.intellij.openapi.command.impl.DocumentUndoProvider;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashSet;
@@ -101,7 +102,7 @@ public class UndoChangeRevertingVisitor extends ChangeVisitor {
if (f != null) {
VirtualFile existing = f.getParent().findChild(c.getOldName());
try {
- if (existing != null && existing != f) {
+ if (existing != null && !Comparing.equal(existing, f)) {
existing.delete(LocalHistory.VFS_EVENT_REQUESTOR);
}
f.rename(LocalHistory.VFS_EVENT_REQUESTOR, c.getOldName());
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
index 331b18d35770..96826cd917de 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
@@ -53,7 +54,7 @@ public class LazyRangeMarkerFactory extends AbstractProjectComponent {
List markers = lazyMarkers.toStrongList();
List markersToRemove = new ArrayList();
for (final LazyMarker marker : markers) {
- if (marker.getFile() == docFile) {
+ if (Comparing.equal(marker.getFile(), docFile)) {
marker.ensureDelegate();
markersToRemove.add(marker);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java
index 8e61b7327f80..6b15e4a3dad7 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileElement.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.fileChooser;
import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.StringBuilderSpinAllocator;
@@ -84,7 +85,7 @@ public class FileElement {
@Override
public boolean equals(Object obj) {
if (obj instanceof FileElement) {
- if (((FileElement)obj).myFile == myFile) return true;
+ if (Comparing.equal(((FileElement)obj).myFile, myFile)) return true;
}
return false;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
index 78464b10d14a..c15570283dae 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
@@ -1,264 +1,265 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.fileEditor;
-
-import com.intellij.ide.*;
-import com.intellij.ide.FileEditorProvider;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.DataKey;
-import com.intellij.openapi.editor.*;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.fileTypes.INativeFileType;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.pom.Navigatable;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-public class OpenFileDescriptor implements Navigatable {
- /**
- * Tells descriptor to navigate in specific editor rather than file editor
- * in main IDEA window.
- * For example if you want to navigate in editor embedded into modal dialog,
- * you should provide this data.
- */
- public static final DataKey NAVIGATE_IN_EDITOR = DataKey.create("NAVIGATE_IN_EDITOR");
-
- @NotNull
- private final VirtualFile myFile;
- private final int myOffset;
- private final int myLogicalLine;
- private final int myLogicalColumn;
- private final RangeMarker myRangeMarker;
- @NotNull
- private final Project myProject;
-
- private boolean myUseCurrentWindow = false;
-
- public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) {
- this(project, file, -1, -1, offset, false);
- }
-
- public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) {
- this(project, file, logicalLine, logicalColumn, -1, false);
- }
-
- public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
- int logicalLine, int logicalColumn, boolean persistent) {
- this(project, file, logicalLine, logicalColumn, -1, persistent);
- }
-
- public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) {
- this(project, file, -1, -1, -1, false);
- }
-
- private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
- int logicalLine, int logicalColumn, int offset, boolean persistent) {
- myProject = project;
-
- myFile = file;
- myLogicalLine = logicalLine;
- myLogicalColumn = logicalColumn;
- myOffset = offset;
- if (offset >= 0) {
- myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
- }
- else if (logicalLine >= 0 ){
- myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, logicalLine, Math.max(0, logicalColumn), persistent);
- }
- else {
- myRangeMarker = null;
- }
- }
-
- @NotNull
- public VirtualFile getFile() {
- return myFile;
- }
-
- @Nullable
- public RangeMarker getRangeMarker() {
- return myRangeMarker;
- }
-
- public int getOffset() {
- return myRangeMarker != null && myRangeMarker.isValid() ? myRangeMarker.getStartOffset() : myOffset;
- }
-
- public int getLine() {
- return myLogicalLine;
- }
-
- public int getColumn() {
- return myLogicalColumn;
- }
-
- @Override
- public void navigate(boolean requestFocus) {
- if (!canNavigate()) {
- throw new IllegalStateException("Navigation is not possible with null project");
- }
-
- if (!myFile.isDirectory() && navigateInEditor(myProject, requestFocus)) return;
-
- navigateInProjectView();
- }
-
- private boolean navigateInEditor(@NotNull Project project, boolean requestFocus) {
- FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile,project);
- if (type == null || !myFile.isValid()) return false;
-
- if (type instanceof INativeFileType) {
- return ((INativeFileType) type).openFileInAssociatedApplication(project, myFile);
- }
-
- return navigateInRequestedEditor() || navigateInAnyFileEditor(project, requestFocus);
- }
-
- private boolean navigateInRequestedEditor() {
- DataContext ctx = DataManager.getInstance().getDataContext();
- Editor e = NAVIGATE_IN_EDITOR.getData(ctx);
- if (e == null) return false;
- if (FileDocumentManager.getInstance().getFile(e.getDocument()) != myFile) return false;
-
- navigateIn(e);
- return true;
- }
-
- private boolean navigateInAnyFileEditor(Project project, boolean focusEditor) {
- List editors = FileEditorManager.getInstance(project).openEditor(this, focusEditor);
- for (FileEditor editor : editors) {
- if (editor instanceof TextEditor) {
- Editor e = ((TextEditor)editor).getEditor();
- unfoldCurrentLine(e);
- if (focusEditor) {
- IdeFocusManager.getInstance(myProject).requestFocus(e.getContentComponent(), true);
- }
- }
- }
- return !editors.isEmpty();
- }
-
- private void navigateInProjectView() {
- SelectInContext context = new SelectInContext() {
- @Override
- @NotNull
- public Project getProject() {
- return myProject;
- }
-
- @Override
- @NotNull
- public VirtualFile getVirtualFile() {
- return myFile;
- }
-
- @Override
- @Nullable
- public Object getSelectorInFile() {
- return null;
- }
-
- @Override
- @Nullable
- public FileEditorProvider getFileEditorProvider() {
- return null;
- }
- };
-
- for (SelectInTarget target : SelectInManager.getInstance(myProject).getTargets()) {
- if (target.canSelect(context)) {
- target.selectIn(context, true);
- return;
- }
- }
- }
-
- public void navigateIn(@NotNull Editor e) {
- final int offset = getOffset();
- CaretModel caretModel = e.getCaretModel();
- boolean caretMoved = false;
- if (myLogicalLine >= 0) {
- LogicalPosition pos = new LogicalPosition(myLogicalLine, Math.max(myLogicalColumn, 0));
- if (offset < 0 || offset == e.logicalPositionToOffset(pos)) {
- caretModel.moveToLogicalPosition(pos);
- caretMoved = true;
- }
- }
- if (!caretMoved && offset >= 0) {
- caretModel.moveToOffset(Math.min(offset, e.getDocument().getTextLength()));
- caretMoved = true;
- }
-
- if (caretMoved) {
- e.getSelectionModel().removeSelection();
- scrollToCaret(e);
- unfoldCurrentLine(e);
- }
- }
-
- private static void unfoldCurrentLine(@NotNull final Editor editor) {
- final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
- final int offset = editor.getCaretModel().getOffset();
- int line = editor.getDocument().getLineNumber(offset);
- int start = editor.getDocument().getLineStartOffset(line);
- int end = editor.getDocument().getLineEndOffset(line);
- final TextRange range = new TextRange(start, end);
- editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
- @Override
- public void run() {
- for (FoldRegion region : allRegions) {
- if (!region.isExpanded() && range.intersects(TextRange.create(region))) {
- region.setExpanded(true);
- }
- }
- }
- });
- }
-
- private static void scrollToCaret(@NotNull Editor e) {
- e.getScrollingModel().scrollToCaret(ScrollType.CENTER);
- }
-
- @Override
- public boolean canNavigate() {
- return myFile.isValid();
- }
-
- @Override
- public boolean canNavigateToSource() {
- return canNavigate();
- }
-
- @NotNull
- public Project getProject() {
- return myProject;
- }
-
- public OpenFileDescriptor setUseCurrentWindow(boolean search) {
- myUseCurrentWindow = search;
- return this;
- }
-
- public boolean isUseCurrentWindow() {
- return myUseCurrentWindow;
- }
-}
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.fileEditor;
+
+import com.intellij.ide.*;
+import com.intellij.ide.FileEditorProvider;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.INativeFileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class OpenFileDescriptor implements Navigatable {
+ /**
+ * Tells descriptor to navigate in specific editor rather than file editor
+ * in main IDEA window.
+ * For example if you want to navigate in editor embedded into modal dialog,
+ * you should provide this data.
+ */
+ public static final DataKey NAVIGATE_IN_EDITOR = DataKey.create("NAVIGATE_IN_EDITOR");
+
+ @NotNull
+ private final VirtualFile myFile;
+ private final int myOffset;
+ private final int myLogicalLine;
+ private final int myLogicalColumn;
+ private final RangeMarker myRangeMarker;
+ @NotNull
+ private final Project myProject;
+
+ private boolean myUseCurrentWindow = false;
+
+ public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) {
+ this(project, file, -1, -1, offset, false);
+ }
+
+ public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) {
+ this(project, file, logicalLine, logicalColumn, -1, false);
+ }
+
+ public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
+ int logicalLine, int logicalColumn, boolean persistent) {
+ this(project, file, logicalLine, logicalColumn, -1, persistent);
+ }
+
+ public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) {
+ this(project, file, -1, -1, -1, false);
+ }
+
+ private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
+ int logicalLine, int logicalColumn, int offset, boolean persistent) {
+ myProject = project;
+
+ myFile = file;
+ myLogicalLine = logicalLine;
+ myLogicalColumn = logicalColumn;
+ myOffset = offset;
+ if (offset >= 0) {
+ myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
+ }
+ else if (logicalLine >= 0 ){
+ myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, logicalLine, Math.max(0, logicalColumn), persistent);
+ }
+ else {
+ myRangeMarker = null;
+ }
+ }
+
+ @NotNull
+ public VirtualFile getFile() {
+ return myFile;
+ }
+
+ @Nullable
+ public RangeMarker getRangeMarker() {
+ return myRangeMarker;
+ }
+
+ public int getOffset() {
+ return myRangeMarker != null && myRangeMarker.isValid() ? myRangeMarker.getStartOffset() : myOffset;
+ }
+
+ public int getLine() {
+ return myLogicalLine;
+ }
+
+ public int getColumn() {
+ return myLogicalColumn;
+ }
+
+ @Override
+ public void navigate(boolean requestFocus) {
+ if (!canNavigate()) {
+ throw new IllegalStateException("Navigation is not possible with null project");
+ }
+
+ if (!myFile.isDirectory() && navigateInEditor(myProject, requestFocus)) return;
+
+ navigateInProjectView();
+ }
+
+ private boolean navigateInEditor(@NotNull Project project, boolean requestFocus) {
+ FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile,project);
+ if (type == null || !myFile.isValid()) return false;
+
+ if (type instanceof INativeFileType) {
+ return ((INativeFileType) type).openFileInAssociatedApplication(project, myFile);
+ }
+
+ return navigateInRequestedEditor() || navigateInAnyFileEditor(project, requestFocus);
+ }
+
+ private boolean navigateInRequestedEditor() {
+ DataContext ctx = DataManager.getInstance().getDataContext();
+ Editor e = NAVIGATE_IN_EDITOR.getData(ctx);
+ if (e == null) return false;
+ if (!Comparing.equal(FileDocumentManager.getInstance().getFile(e.getDocument()), myFile)) return false;
+
+ navigateIn(e);
+ return true;
+ }
+
+ private boolean navigateInAnyFileEditor(Project project, boolean focusEditor) {
+ List editors = FileEditorManager.getInstance(project).openEditor(this, focusEditor);
+ for (FileEditor editor : editors) {
+ if (editor instanceof TextEditor) {
+ Editor e = ((TextEditor)editor).getEditor();
+ unfoldCurrentLine(e);
+ if (focusEditor) {
+ IdeFocusManager.getInstance(myProject).requestFocus(e.getContentComponent(), true);
+ }
+ }
+ }
+ return !editors.isEmpty();
+ }
+
+ private void navigateInProjectView() {
+ SelectInContext context = new SelectInContext() {
+ @Override
+ @NotNull
+ public Project getProject() {
+ return myProject;
+ }
+
+ @Override
+ @NotNull
+ public VirtualFile getVirtualFile() {
+ return myFile;
+ }
+
+ @Override
+ @Nullable
+ public Object getSelectorInFile() {
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public FileEditorProvider getFileEditorProvider() {
+ return null;
+ }
+ };
+
+ for (SelectInTarget target : SelectInManager.getInstance(myProject).getTargets()) {
+ if (target.canSelect(context)) {
+ target.selectIn(context, true);
+ return;
+ }
+ }
+ }
+
+ public void navigateIn(@NotNull Editor e) {
+ final int offset = getOffset();
+ CaretModel caretModel = e.getCaretModel();
+ boolean caretMoved = false;
+ if (myLogicalLine >= 0) {
+ LogicalPosition pos = new LogicalPosition(myLogicalLine, Math.max(myLogicalColumn, 0));
+ if (offset < 0 || offset == e.logicalPositionToOffset(pos)) {
+ caretModel.moveToLogicalPosition(pos);
+ caretMoved = true;
+ }
+ }
+ if (!caretMoved && offset >= 0) {
+ caretModel.moveToOffset(Math.min(offset, e.getDocument().getTextLength()));
+ caretMoved = true;
+ }
+
+ if (caretMoved) {
+ e.getSelectionModel().removeSelection();
+ scrollToCaret(e);
+ unfoldCurrentLine(e);
+ }
+ }
+
+ private static void unfoldCurrentLine(@NotNull final Editor editor) {
+ final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();
+ final int offset = editor.getCaretModel().getOffset();
+ int line = editor.getDocument().getLineNumber(offset);
+ int start = editor.getDocument().getLineStartOffset(line);
+ int end = editor.getDocument().getLineEndOffset(line);
+ final TextRange range = new TextRange(start, end);
+ editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
+ @Override
+ public void run() {
+ for (FoldRegion region : allRegions) {
+ if (!region.isExpanded() && range.intersects(TextRange.create(region))) {
+ region.setExpanded(true);
+ }
+ }
+ }
+ });
+ }
+
+ private static void scrollToCaret(@NotNull Editor e) {
+ e.getScrollingModel().scrollToCaret(ScrollType.CENTER);
+ }
+
+ @Override
+ public boolean canNavigate() {
+ return myFile.isValid();
+ }
+
+ @Override
+ public boolean canNavigateToSource() {
+ return canNavigate();
+ }
+
+ @NotNull
+ public Project getProject() {
+ return myProject;
+ }
+
+ public OpenFileDescriptor setUseCurrentWindow(boolean search) {
+ myUseCurrentWindow = search;
+ return this;
+ }
+
+ public boolean isUseCurrentWindow() {
+ return myUseCurrentWindow;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java
index 38675fe45e03..08dbaeb3e653 100644
--- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -327,6 +328,16 @@ public class VfsUtil extends VfsUtilCore {
return virtualFileManager.findFileByUrl(vfUrl);
}
+ @Nullable
+ public static VirtualFile findFileByIoFile(@NotNull File file, boolean refreshIfNeeded) {
+ LocalFileSystem fileSystem = LocalFileSystem.getInstance();
+ VirtualFile virtualFile = fileSystem.findFileByIoFile(file);
+ if (virtualFile == null && refreshIfNeeded) {
+ virtualFile = fileSystem.refreshAndFindFileByIoFile(file);
+ }
+ return virtualFile;
+ }
+
/**
* Converts VsfUrl info java.net.URL. Does not support "jar:" protocol.
*
@@ -473,8 +484,8 @@ public class VfsUtil extends VfsUtilCore {
final VirtualFile commonAncestor = getCommonAncestor(src, dst);
if (commonAncestor != null) {
StringBuilder buffer = new StringBuilder();
- if (src != commonAncestor) {
- while (src.getParent() != commonAncestor) {
+ if (!Comparing.equal(src, commonAncestor)) {
+ while (!Comparing.equal(src.getParent(), commonAncestor)) {
buffer.append("..").append(separatorChar);
src = src.getParent();
}
diff --git a/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java b/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java
index 1a8438cc511e..a29c73739737 100644
--- a/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java
+++ b/platform/platform-api/src/com/intellij/ui/RowsDnDSupport.java
@@ -47,6 +47,7 @@ public class RowsDnDSupport {
}
private static void installImpl(@NotNull final JComponent component, @NotNull final EditableModel model) {
+ component.setTransferHandler(new TransferHandler(null));
DnDSupport.createBuilder(component)
.setBeanProvider(new Function() {
@Override
@@ -72,8 +73,10 @@ public class RowsDnDSupport {
event.setHighlighting(rectangle, 2);
}
else {
- event.setDropPossible(false);
+ if (oldIndex != newIndex) // Drag&Drop always starts with new==old and we shouldn't display 'rejecting' cursor in this case
+ event.setDropPossible(false, "");
event.hideHighlighter();
+ return true;
}
return false;
}
@@ -122,7 +125,7 @@ public class RowsDnDSupport {
} else if (component instanceof JList) {
return ((JList)component).locationToIndex(point);
} else if (component instanceof JTree) {
- return ((JTree)component).getRowForLocation(point.x, point.y);
+ return ((JTree)component).getClosestRowForLocation(point.x, point.y);
} else {
throw new IllegalArgumentException("Unsupported component: " + component);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java
index 443a10030ec2..683e205d644e 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CloseAllEditorsButActiveAction.java
@@ -1,4 +1,3 @@
-
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
@@ -24,6 +23,7 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
public class CloseAllEditorsButActiveAction extends AnAction implements DumbAware {
@@ -39,7 +39,7 @@ public class CloseAllEditorsButActiveAction extends AnAction implements DumbAwar
selectedFile = fileEditorManager.getSelectedFiles()[0];
final VirtualFile[] siblings = fileEditorManager.getSiblings(selectedFile);
for (final VirtualFile sibling : siblings) {
- if (selectedFile != sibling) {
+ if (!Comparing.equal(selectedFile, sibling)) {
fileEditorManager.closeFile(sibling);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java
index a5b968468de0..ca9103d60b1a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/CommandMerger.java
@@ -231,6 +231,14 @@ public class CommandMerger {
return !myCurrentActions.isEmpty();
}
+ public boolean isPhysical() {
+ if (myAllAffectedDocuments.isEmpty()) return false;
+ for (DocumentReference each : myAllAffectedDocuments) {
+ if (each.getFile() == null) return false;
+ }
+ return true;
+ }
+
public boolean isUndoAvailable(@NotNull Collection refs) {
if (hasNonUndoableActions()) {
return false;
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
index a53830f241b7..c5405f1e9dc3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/DocumentReferenceManagerImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.command.undo.DocumentReferenceManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileAdapter;
@@ -75,7 +76,7 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
List files = f.getUserData(DELETED_FILES);
f.putUserData(DELETED_FILES, null);
- assert files != null;
+ assert files != null : f;
for (VirtualFile each : files) {
Reference r = new WeakReferenceWithEquals(each);
DocumentReference ref = myFileToRef.remove(r);
@@ -159,7 +160,7 @@ public class DocumentReferenceManagerImpl extends DocumentReferenceManager imple
@Override
public boolean equals(Object obj) {
T doc = get();
- return doc != null && obj instanceof Reference && ((Reference)obj).get() == doc;
+ return doc != null && obj instanceof Reference && Comparing.equal(doc, ((Reference)obj).get());
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
index 8dfe6ea8cfed..b412d811ea4d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
@@ -283,7 +283,7 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
myCommandLevel--;
if (myCommandLevel > 0) return;
- if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isTransparent()) {
+ if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isTransparent() && myCurrentMerger.isPhysical()) {
addFocusedDocumentAsAffected();
}
myOriginatorReference = null;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
index 33c8e1d104b5..bedb82bbca22 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorComposite.java
@@ -181,7 +181,7 @@ public abstract class EditorComposite implements Disposable {
public void selectionChanged(final FileEditorManagerEvent event) {
final VirtualFile oldFile = event.getOldFile();
final VirtualFile newFile = event.getNewFile();
- if (oldFile == newFile && getFile() == newFile) {
+ if (Comparing.equal(oldFile, newFile) && Comparing.equal(getFile(), newFile)) {
final FileEditor oldEditor = event.getOldEditor();
if (oldEditor != null) oldEditor.deselectNotify();
final FileEditor newEditor = event.getNewEditor();
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
index 03791c9477d5..5380ee9ec8fa 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.Pair;
@@ -254,7 +255,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
public boolean hasBeenOpen(@NotNull VirtualFile f) {
for (HistoryEntry each : myEntriesList) {
- if (each.myFile == f) return true;
+ if (Comparing.equal(each.myFile, f)) return true;
}
return false;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
index c1cfae48f8ee..81d51d770538 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
@@ -122,7 +122,7 @@ public class EditorWindow {
public void closeAllExcept(final VirtualFile selectedFile) {
final VirtualFile[] files = getFiles();
for (final VirtualFile file : files) {
- if (file != selectedFile && !isFilePinned(file)) {
+ if (!Comparing.equal(file, selectedFile) && !isFilePinned(file)) {
closeFile(file);
}
}
@@ -1090,7 +1090,7 @@ public class EditorWindow {
if (fileCanBeClosed(file, fileToIgnore)) {
boolean found = false;
for (int j = 0; j != histFiles.length; j++) {
- if (histFiles[j] == file) {
+ if (Comparing.equal(histFiles[j], file)) {
found = true;
break;
}
@@ -1146,7 +1146,7 @@ public class EditorWindow {
if (fileCanBeClosed(file, fileToIgnore)) {
boolean found = false;
for (int j = 0; j != histFiles.length; j++) {
- if (histFiles[j] == file) {
+ if (Comparing.equal(histFiles[j], file)) {
found = true;
break;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
index e5c2c5eb7991..1afc02766e6b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
@@ -387,7 +387,7 @@ public class EditorsSplitters extends JPanel {
final VirtualFile currentFile = getCurrentFile();
if (currentFile != null) {
for (int i = 0; i != virtualFiles.length; ++i) {
- if (virtualFiles[i] == currentFile) {
+ if (Comparing.equal(virtualFiles[i], currentFile)) {
virtualFiles[i] = virtualFiles[0];
virtualFiles[0] = currentFile;
break;
@@ -572,7 +572,7 @@ public class EditorsSplitters extends JPanel {
for (int i = 0; i != windows.length; ++i) {
final VirtualFile[] files = windows[i].getFiles();
for (final VirtualFile fileAt : files) {
- if (fileAt != file) {
+ if (!Comparing.equal(fileAt, file)) {
return fileAt;
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index a12860e54b64..a050a9455940 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -1,1801 +1,1801 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.fileEditor.impl;
-
-import com.intellij.ProjectTopics;
-import com.intellij.ide.IdeBundle;
-import com.intellij.ide.plugins.PluginManager;
-import com.intellij.ide.ui.UISettings;
-import com.intellij.ide.ui.UISettingsListener;
-import com.intellij.injected.editor.VirtualFileWindow;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.ex.ApplicationManagerEx;
-import com.intellij.openapi.application.impl.LaterInvocator;
-import com.intellij.openapi.command.CommandProcessor;
-import com.intellij.openapi.components.ProjectComponent;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ScrollType;
-import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.impl.EditorComponentImpl;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileEditor.*;
-import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
-import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
-import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
-import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
-import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
-import com.intellij.openapi.fileTypes.FileTypeEvent;
-import com.intellij.openapi.fileTypes.FileTypeListener;
-import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.project.DumbAwareRunnable;
-import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.impl.ProjectImpl;
-import com.intellij.openapi.roots.ModuleRootAdapter;
-import com.intellij.openapi.roots.ModuleRootEvent;
-import com.intellij.openapi.startup.StartupManager;
-import com.intellij.openapi.util.*;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.registry.Registry;
-import com.intellij.openapi.vcs.FileStatus;
-import com.intellij.openapi.vcs.FileStatusListener;
-import com.intellij.openapi.vcs.FileStatusManager;
-import com.intellij.openapi.vfs.*;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.openapi.wm.WindowManager;
-import com.intellij.openapi.wm.ex.StatusBarEx;
-import com.intellij.openapi.wm.impl.IdeFrameImpl;
-import com.intellij.ui.FocusTrackback;
-import com.intellij.ui.docking.DockContainer;
-import com.intellij.ui.docking.DockManager;
-import com.intellij.ui.tabs.impl.JBTabsImpl;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.messages.MessageBusConnection;
-import com.intellij.util.messages.impl.MessageListenerList;
-import com.intellij.util.ui.SameColor;
-import com.intellij.util.ui.UIUtil;
-import com.intellij.util.ui.update.MergingUpdateQueue;
-import com.intellij.util.ui.update.Update;
-import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.border.Border;
-import java.awt.*;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.lang.ref.WeakReference;
-import java.util.*;
-import java.util.List;
-
-/**
- * @author Anton Katilin
- * @author Eugene Belyaev
- * @author Vladimir Kondratyev
- */
-public class FileEditorManagerImpl extends FileEditorManagerEx implements ProjectComponent, JDOMExternalizable {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl");
- private static final Key WATCH_REQUEST_KEY = Key.create("WATCH_REQUEST_KEY");
- private static final Key DUMB_AWARE = Key.create("DUMB_AWARE");
-
- private static final FileEditor[] EMPTY_EDITOR_ARRAY = {};
- private static final FileEditorProvider[] EMPTY_PROVIDER_ARRAY = {};
- public static final Key CLOSING_TO_REOPEN = Key.create("CLOSING_TO_REOPEN");
-
- private volatile JPanel myPanels;
- private EditorsSplitters mySplitters;
- private final Project myProject;
- private final List> mySelectionHistory = new ArrayList>();
- private WeakReference myLastSelectedComposite = new WeakReference(null);
-
-
- private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null);
-
- private final BusyObject.Impl.Simple myBusyObject = new BusyObject.Impl.Simple();
-
- /**
- * Removes invalid myEditor and updates "modified" status.
- */
- private final MyEditorPropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener();
- private final DockManager myDockManager;
- private DockableEditorContainerFactory myContentFactory;
-
- public FileEditorManagerImpl(final Project project, DockManager dockManager) {
-/* ApplicationManager.getApplication().assertIsDispatchThread(); */
- myProject = project;
- myDockManager = dockManager;
- myListenerList =
- new MessageListenerList(myProject.getMessageBus(), FileEditorManagerListener.FILE_EDITOR_MANAGER);
-
- if (Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME).length > 0) {
- myListenerList.add(new FileEditorManagerAdapter() {
- @Override
- public void selectionChanged(FileEditorManagerEvent event) {
- EditorsSplitters splitters = getSplitters();
- openAssociatedFile(event.getNewFile(), splitters.getCurrentWindow(), splitters);
- }
- });
- }
-
- myQueue.setTrackUiActivity(true);
- }
-
- void initDockableContentFactory() {
- if (myContentFactory != null) return;
-
- myContentFactory = new DockableEditorContainerFactory(myProject, this, myDockManager);
- myDockManager.register(DockableEditorContainerFactory.TYPE, myContentFactory);
- Disposer.register(myProject, myContentFactory);
- }
-
- public static boolean isDumbAware(FileEditor editor) {
- return Boolean.TRUE.equals(editor.getUserData(DUMB_AWARE));
- }
-
- //-------------------------------------------------------------------------------
-
- public JComponent getComponent() {
- initUI();
- return myPanels;
- }
-
- public EditorsSplitters getMainSplitters() {
- initUI();
-
- return mySplitters;
- }
-
- public Set getAllSplitters() {
- HashSet all = new HashSet();
- all.add(getMainSplitters());
- Set dockContainers = myDockManager.getContainers();
- for (DockContainer each : dockContainers) {
- if (each instanceof DockableEditorTabbedContainer) {
- all.add(((DockableEditorTabbedContainer)each).getSplitters());
- }
- }
-
- return Collections.unmodifiableSet(all);
- }
-
- private AsyncResult getActiveSplitters(boolean syncUsage) {
- final boolean async = Registry.is("ide.windowSystem.asyncSplitters") && !syncUsage;
-
- final AsyncResult result = new AsyncResult();
- final IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
- Runnable run = new Runnable() {
- @Override
- public void run() {
- if (myProject.isDisposed()) {
- result.setRejected();
- return;
- }
-
- Component focusOwner = fm.getFocusOwner();
- if (focusOwner == null && !async) {
- focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
- }
-
- if (focusOwner == null && !async) {
- focusOwner = fm.getLastFocusedFor(fm.getLastFocusedFrame());
- }
-
- DockContainer container = myDockManager.getContainerFor(focusOwner);
- if (container == null && !async) {
- focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- container = myDockManager.getContainerFor(focusOwner);
- }
-
- if (container instanceof DockableEditorTabbedContainer) {
- result.setDone(((DockableEditorTabbedContainer)container).getSplitters());
- }
- else {
- result.setDone(getMainSplitters());
- }
- }
- };
-
- if (async) {
- fm.doWhenFocusSettlesDown(run);
- }
- else {
- run.run();
- }
-
- return result;
- }
-
- private final Object myInitLock = new Object();
-
- private void initUI() {
- if (myPanels == null) {
- synchronized (myInitLock) {
- if (myPanels == null) {
- myPanels = new JPanel(new BorderLayout()) {
- @Override
- public Color getBackground() {
- boolean navBar = UISettings.getInstance().SHOW_NAVIGATION_BAR;
- if (navBar) {
- return UIUtil.getSlightlyDarkerColor(UIUtil.isUnderAquaLookAndFeel() ? new SameColor(200) : UIUtil.getPanelBackground());
- } else {
- return UIUtil.isUnderAquaLookAndFeel() ? new SameColor(189) : UIUtil.getPanelBackground();
- }
- }
- };
- myPanels.setBorder(new MyBorder());
- mySplitters = new EditorsSplitters(this, myDockManager, true);
- myPanels.add(mySplitters, BorderLayout.CENTER);
- }
- }
- }
- }
-
- private static class MyBorder implements Border {
- @Override
- public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
- if (UIUtil.isUnderAquaLookAndFeel()) {
- g.setColor(JBTabsImpl.MAC_AQUA_BG_COLOR);
- final Insets insets = getBorderInsets(c);
- if (insets.top > 0) {
- g.fillRect(x, y, width, height + insets.top);
- }
- }
- }
-
- @Override
- public Insets getBorderInsets(Component c) {
- return new Insets(0, 0, 0, 0);
- }
-
- @Override
- public boolean isBorderOpaque() {
- return false;
- }
- }
-
- public JComponent getPreferredFocusedComponent() {
- assertReadAccess();
- final EditorWindow window = getSplitters().getCurrentWindow();
- if (window != null) {
- final EditorWithProviderComposite editor = window.getSelectedEditor();
- if (editor != null) {
- return editor.getPreferredFocusedComponent();
- }
- }
- return null;
- }
-
- //-------------------------------------------------------
-
- /**
- * @return color of the file which corresponds to the
- * file's status
- */
- public Color getFileColor(@NotNull final VirtualFile file) {
- final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject);
- Color statusColor = fileStatusManager != null ? fileStatusManager.getStatus(file).getColor() : Color.BLACK;
- if (statusColor == null) statusColor = Color.BLACK;
- return statusColor;
- }
-
- public boolean isProblem(@NotNull final VirtualFile file) {
- return false;
- }
-
- public String getFileTooltipText(VirtualFile file) {
- return FileUtil.getLocationRelativeToUserHome(file.getPresentableUrl());
- }
-
- public void updateFilePresentation(VirtualFile file) {
- if (!isFileOpen(file)) return;
-
- updateFileColor(file);
- updateFileIcon(file);
- updateFileName(file);
- updateFileBackgroundColor(file);
- }
-
- /**
- * Updates tab color for the specified file. The file
- * should be opened in the myEditor, otherwise the method throws an assertion.
- */
- private void updateFileColor(final VirtualFile file) {
- Set all = getAllSplitters();
- for (EditorsSplitters each : all) {
- each.updateFileColor(file);
- }
- }
-
- private void updateFileBackgroundColor(final VirtualFile file) {
- Set all = getAllSplitters();
- for (EditorsSplitters each : all) {
- each.updateFileBackgroundColor(file);
- }
- }
-
- /**
- * Updates tab icon for the specified file. The file
- * should be opened in the myEditor, otherwise the method throws an assertion.
- */
- protected void updateFileIcon(final VirtualFile file) {
- Set all = getAllSplitters();
- for (EditorsSplitters each : all) {
- each.updateFileIcon(file);
- }
- }
-
- /**
- * Updates tab title and tab tool tip for the specified file
- */
- void updateFileName(@Nullable final VirtualFile file) {
- // Queue here is to prevent title flickering when tab is being closed and two events arriving: with component==null and component==next focused tab
- // only the last event makes sense to handle
- myQueue.queue(new Update("UpdateFileName " + (file == null ? "" : file.getPath())) {
- public boolean isExpired() {
- return myProject.isDisposed() || !myProject.isOpen() || (file == null ? super.isExpired() : !file.isValid());
- }
-
- public void run() {
- Set all = getAllSplitters();
- for (EditorsSplitters each : all) {
- each.updateFileName(file);
- }
- }
- });
- }
-
- //-------------------------------------------------------
-
-
- public VirtualFile getFile(@NotNull final FileEditor editor) {
- final EditorComposite editorComposite = getEditorComposite(editor);
- if (editorComposite != null) {
- return editorComposite.getFile();
- }
- return null;
- }
-
- public void unsplitWindow() {
- final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
- if (currentWindow != null) {
- currentWindow.unsplit(true);
- }
- }
-
- public void unsplitAllWindow() {
- final EditorWindow currentWindow = getActiveSplitters(true).getResult().getCurrentWindow();
- if (currentWindow != null) {
- currentWindow.unsplitAll();
- }
- }
-
- @Override
- public int getWindowSplitCount() {
- return getActiveSplitters(true).getResult().getSplitCount();
- }
-
- @Override
- public boolean hasSplitOrUndockedWindows() {
- Set splitters = getAllSplitters();
- if (splitters.size() > 1) return true;
- return getWindowSplitCount() > 1;
- }
-
- @NotNull
- public EditorWindow[] getWindows() {
- ArrayList windows = new ArrayList();
- Set all = getAllSplitters();
- for (EditorsSplitters each : all) {
- EditorWindow[] eachList = each.getWindows();
- windows.addAll(Arrays.asList(eachList));
- }
-
- return windows.toArray(new EditorWindow[windows.size()]);
- }
-
- public EditorWindow getNextWindow(@NotNull final EditorWindow window) {
- final EditorWindow[] windows = getSplitters().getOrderedWindows();
- for (int i = 0; i != windows.length; ++i) {
- if (windows[i].equals(window)) {
- return windows[(i + 1) % windows.length];
- }
- }
- LOG.error("Not window found");
- return null;
- }
-
- public EditorWindow getPrevWindow(@NotNull final EditorWindow window) {
- final EditorWindow[] windows = getSplitters().getOrderedWindows();
- for (int i = 0; i != windows.length; ++i) {
- if (windows[i].equals(window)) {
- return windows[(i + windows.length - 1) % windows.length];
- }
- }
- LOG.error("Not window found");
- return null;
- }
-
- public void createSplitter(final int orientation, @Nullable final EditorWindow window) {
- // window was available from action event, for example when invoked from the tab menu of an editor that is not the 'current'
- if (window != null) {
- window.split(orientation, true, null, false);
- }
- // otherwise we'll split the current window, if any
- else {
- final EditorWindow currentWindow = getSplitters().getCurrentWindow();
- if (currentWindow != null) {
- currentWindow.split(orientation, true, null, false);
- }
- }
- }
-
- public void changeSplitterOrientation() {
- final EditorWindow currentWindow = getSplitters().getCurrentWindow();
- if (currentWindow != null) {
- currentWindow.changeOrientation();
- }
- }
-
-
- public void flipTabs() {
- /*
- if (myTabs == null) {
- myTabs = new EditorTabs (this, UISettings.getInstance().EDITOR_TAB_PLACEMENT);
- remove (mySplitters);
- add (myTabs, BorderLayout.CENTER);
- initTabs ();
- } else {
- remove (myTabs);
- add (mySplitters, BorderLayout.CENTER);
- myTabs.dispose ();
- myTabs = null;
- }
- */
- myPanels.revalidate();
- }
-
- public boolean tabsMode() {
- return false;
- }
-
- private void setTabsMode(final boolean mode) {
- if (tabsMode() != mode) {
- flipTabs();
- }
- //LOG.assertTrue (tabsMode () == mode);
- }
-
-
- public boolean isInSplitter() {
- final EditorWindow currentWindow = getSplitters().getCurrentWindow();
- return currentWindow != null && currentWindow.inSplitter();
- }
-
- public boolean hasOpenedFile() {
- final EditorWindow currentWindow = getSplitters().getCurrentWindow();
- return currentWindow != null && currentWindow.getSelectedEditor() != null;
- }
-
- public VirtualFile getCurrentFile() {
- return getActiveSplitters(true).getResult().getCurrentFile();
- }
-
- public AsyncResult getActiveWindow() {
- return _getActiveWindow(false);
- }
-
- private AsyncResult _getActiveWindow(boolean now) {
- final AsyncResult result = new AsyncResult();
- getActiveSplitters(now).doWhenDone(new AsyncResult.Handler() {
- @Override
- public void run(EditorsSplitters editorsSplitters) {
- result.setDone(editorsSplitters.getCurrentWindow());
- }
- });
-
- return result;
- }
-
- public EditorWindow getCurrentWindow() {
- return _getActiveWindow(true).getResult();
- }
-
- public void setCurrentWindow(final EditorWindow window) {
- getActiveSplitters(true).getResult().setCurrentWindow(window, true);
- }
-
- public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window, final boolean transferFocus) {
- assertDispatchThread();
-
- CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
- public void run() {
- if (window.isFileOpen(file)) {
- window.closeFile(file, true, transferFocus);
- final List windows = window.getOwner().findWindows(file);
- if (windows.isEmpty()) { // no more windows containing this file left
- final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY);
- if (request != null) {
- LocalFileSystem.getInstance().removeWatchedRoot(request);
- }
- }
- }
- }
- }, IdeBundle.message("command.close.active.editor"), null);
- removeSelectionRecord(file, window);
- }
-
- public void closeFile(@NotNull final VirtualFile file, @NotNull final EditorWindow window) {
- closeFile(file, window, true);
- }
-
- //============================= EditorManager methods ================================
-
- public void closeFile(@NotNull final VirtualFile file) {
- closeFile(file, true, false);
- }
-
- public void closeFile(@NotNull final VirtualFile file, final boolean moveFocus, final boolean closeAllCopies) {
- assertDispatchThread();
-
- final LocalFileSystem.WatchRequest request = file.getUserData(WATCH_REQUEST_KEY);
- if (request != null) {
- LocalFileSystem.getInstance().removeWatchedRoot(request);
- }
-
- CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
- public void run() {
- closeFileImpl(file, moveFocus, closeAllCopies);
- }
- }, "", null);
- }
-
-
-
- private void closeFileImpl(@NotNull final VirtualFile file, final boolean moveFocus, boolean closeAllCopies) {
- assertDispatchThread();
- runChange(new FileEditorManagerChange() {
- public void run(EditorsSplitters splitters) {
- splitters.closeFile(file, moveFocus);
- }
- }, closeAllCopies ? null : getActiveSplitters(true).getResult());
- }
-
- //-------------------------------------- Open File ----------------------------------------
-
- @NotNull
- public Pair openFileWithProviders(@NotNull final VirtualFile file,
- final boolean focusEditor,
- boolean searchForSplitter) {
- if (!file.isValid()) {
- throw new IllegalArgumentException("file is not valid: " + file);
- }
- assertDispatchThread();
-
- EditorWindow wndToOpenIn = null;
- if (searchForSplitter) {
- Set all = getAllSplitters();
- EditorsSplitters active = getActiveSplitters(true).getResult();
- if (active.getCurrentWindow() != null && active.getCurrentWindow().isFileOpen(file)) {
- wndToOpenIn = active.getCurrentWindow();
- } else {
- for (EditorsSplitters splitters : all) {
- final EditorWindow window = splitters.getCurrentWindow();
- if (window == null) continue;
-
- if (window.isFileOpen(file)) {
- wndToOpenIn = window;
- break;
- }
- }
- }
- }
- else {
- wndToOpenIn = getSplitters().getCurrentWindow();
- }
-
- EditorsSplitters splitters = getSplitters();
-
- if (wndToOpenIn == null) {
- wndToOpenIn = splitters.getOrCreateCurrentWindow(file);
- }
-
- openAssociatedFile(file, wndToOpenIn, splitters);
- return openFileImpl2(wndToOpenIn, file, focusEditor);
- }
-
- private void openAssociatedFile(VirtualFile file, EditorWindow wndToOpenIn, EditorsSplitters splitters) {
- EditorWindow[] windows = splitters.getWindows();
-
- if (file != null && windows.length == 2) {
- for (FileEditorAssociateFinder finder : Extensions.getExtensions(FileEditorAssociateFinder.EP_NAME)) {
- VirtualFile associatedFile = finder.getAssociatedFileToOpen(myProject, file);
-
- if (associatedFile != null) {
- EditorWindow currentWindow = splitters.getCurrentWindow();
- int idx = windows[0] == wndToOpenIn ? 1 : 0;
- openFileImpl2(windows[idx], associatedFile, false);
-
- if (currentWindow != null) {
- splitters.setCurrentWindow(currentWindow, false);
- }
-
- break;
- }
- }
- }
- }
-
- @NotNull
- @Override
- public Pair openFileWithProviders(@NotNull VirtualFile file,
- boolean focusEditor,
- @NotNull EditorWindow window) {
- if (!file.isValid()) {
- throw new IllegalArgumentException("file is not valid: " + file);
- }
- assertDispatchThread();
-
- return openFileImpl2(window, file, focusEditor);
- }
-
- @NotNull
- public Pair openFileImpl2(@NotNull final EditorWindow window,
- @NotNull final VirtualFile file,
- final boolean focusEditor) {
- final Ref> result = new Ref>();
- CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
- public void run() {
- result.set(openFileImpl3(window, file, focusEditor, null, true));
- }
- }, "", null);
- return result.get();
- }
-
- /**
- * @param file to be opened. Unlike openFile method, file can be
- * invalid. For example, all file were invalidate and they are being
- * removed one by one. If we have removed one invalid file, then another
- * invalid file become selected. That's why we do not require that
- * passed file is valid.
- * @param entry map between FileEditorProvider and FileEditorState. If this parameter
- * @param current
- */
- @NotNull
- Pair openFileImpl3(@NotNull final EditorWindow window,
- @NotNull final VirtualFile file,
- final boolean focusEditor,
- @Nullable final HistoryEntry entry,
- boolean current) {
- return openFileImpl4(window, file, focusEditor, entry, current, -1);
- }
-
- @NotNull
- Pair openFileImpl4(@NotNull final EditorWindow window,
- @NotNull final VirtualFile file,
- final boolean focusEditor,
- @Nullable final HistoryEntry entry,
- boolean current,
- int index) {
- // Open file
- FileEditor[] editors;
- FileEditorProvider[] providers;
- final EditorWithProviderComposite newSelectedComposite;
- boolean newEditorCreated = false;
-
- final boolean open = window.isFileOpen(file);
- if (open) {
- // File is already opened. In this case we have to just select existing EditorComposite
- newSelectedComposite = window.findFileComposite(file);
- LOG.assertTrue(newSelectedComposite != null);
-
- editors = newSelectedComposite.getEditors();
- providers = newSelectedComposite.getProviders();
- }
- else {
- // File is not opened yet. In this case we have to create editors
- // and select the created EditorComposite.
- final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
- providers = editorProviderManager.getProviders(myProject, file);
- if (DumbService.getInstance(myProject).isDumb()) {
- final List dumbAware = ContainerUtil.findAll(providers, new Condition() {
- public boolean value(FileEditorProvider fileEditorProvider) {
- return DumbService.isDumbAware(fileEditorProvider);
- }
- });
- providers = dumbAware.toArray(new FileEditorProvider[dumbAware.size()]);
- }
-
- if (providers.length == 0) {
- return Pair.create(EMPTY_EDITOR_ARRAY, EMPTY_PROVIDER_ARRAY);
- }
- newEditorCreated = true;
-
- getProject().getMessageBus().syncPublisher(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER).beforeFileOpened(this, file);
-
- editors = new FileEditor[providers.length];
- for (int i = 0; i < providers.length; i++) {
- try {
- final FileEditorProvider provider = providers[i];
- LOG.assertTrue(provider != null);
- LOG.assertTrue(provider.accept(myProject, file));
- final FileEditor editor = provider.createEditor(myProject, file);
- LOG.assertTrue(editor != null);
- LOG.assertTrue(editor.isValid());
- editors[i] = editor;
- // Register PropertyChangeListener into editor
- editor.addPropertyChangeListener(myEditorPropertyChangeListener);
- editor.putUserData(DUMB_AWARE, DumbService.isDumbAware(provider));
-
- if (current && editor instanceof TextEditorImpl) {
- ((TextEditorImpl)editor).initFolding();
- }
- }
- catch (Exception e) {
- LOG.error(e);
- }
- catch (AssertionError e) {
- LOG.error(e);
- }
- }
-
- // Now we have to create EditorComposite and insert it into the TabbedEditorComponent.
- // After that we have to select opened editor.
- newSelectedComposite = new EditorWithProviderComposite(file, editors, providers, this);
-
- if (index >= 0) {
- newSelectedComposite.getFile().putUserData(EditorWindow.INITIAL_INDEX_KEY, index);
- }
- }
-
- window.setEditor(newSelectedComposite, focusEditor);
-
- final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject);
- for (int i = 0; i < editors.length; i++) {
- final FileEditor editor = editors[i];
- if (editor instanceof TextEditor) {
- // hack!!!
- // This code prevents "jumping" on next repaint.
- ((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling();
- }
-
- final FileEditorProvider provider = providers[i];//getProvider(editor);
-
- // Restore editor state
- FileEditorState state = null;
- if (entry != null) {
- state = entry.getState(provider);
- }
- if (state == null && !open) {
- // We have to try to get state from the history only in case
- // if editor is not opened. Otherwise history entry might have a state
- // out of sync with the current editor state.
- state = editorHistoryManager.getState(file, provider);
- }
- if (state != null) {
- editor.setState(state);
- }
- }
-
- // Restore selected editor
- final FileEditorProvider selectedProvider = editorHistoryManager.getSelectedProvider(file);
- if (selectedProvider != null) {
- final FileEditor[] _editors = newSelectedComposite.getEditors();
- final FileEditorProvider[] _providers = newSelectedComposite.getProviders();
- for (int i = _editors.length - 1; i >= 0; i--) {
- final FileEditorProvider provider = _providers[i];//getProvider(_editors[i]);
- if (provider.equals(selectedProvider)) {
- newSelectedComposite.setSelectedEditor(i);
- break;
- }
- }
- }
-
- // Notify editors about selection changes
- window.getOwner().setCurrentWindow(window, focusEditor);
- window.getOwner().afterFileOpen(file);
-
- newSelectedComposite.getSelectedEditor().selectNotify();
-
- final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject);
- if (newEditorCreated) {
- if (window.isShowing()) {
- window.setPaintBlocked(true);
- }
- notifyPublisher(new Runnable() {
- @Override
- public void run() {
- window.setPaintBlocked(false);
- if (isFileOpen(file)) {
- getProject().getMessageBus().syncPublisher(FileEditorManagerListener.FILE_EDITOR_MANAGER)
- .fileOpened(FileEditorManagerImpl.this, file);
- }
- }
- });
-
- //Add request to watch this editor's virtual file
- final VirtualFile parentDir = file.getParent();
- if (parentDir != null) {
- final LocalFileSystem.WatchRequest request = LocalFileSystem.getInstance().addRootToWatch(parentDir.getPath(), false);
- file.putUserData(WATCH_REQUEST_KEY, request);
- }
- }
-
- //[jeka] this is a hack to support back-forward navigation
- // previously here was incorrect call to fireSelectionChanged() with a side-effect
- ((IdeDocumentHistoryImpl)IdeDocumentHistory.getInstance(myProject)).onSelectionChanged();
-
- // Transfer focus into editor
- if (!ApplicationManagerEx.getApplicationEx().isUnitTestMode()) {
- if (focusEditor) {
- //myFirstIsActive = myTabbedContainer1.equals(tabbedContainer);
- window.setAsCurrentWindow(true);
- ToolWindowManager.getInstance(myProject).activateEditorComponent();
- focusManager.toFront(window.getOwner());
- }
- }
-
- // Update frame and tab title
- updateFileName(file);
-
- // Make back/forward work
- IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation();
-
- return Pair.create(editors, providers);
- }
-
- @Override
- public ActionCallback notifyPublisher(final Runnable runnable) {
- final IdeFocusManager focusManager = IdeFocusManager.getInstance(myProject);
- final ActionCallback done = new ActionCallback();
- return myBusyObject.execute(new ActiveRunnable() {
- @Override
- public ActionCallback run() {
- focusManager.doWhenFocusSettlesDown(new ExpirableRunnable.ForProject(myProject) {
- @Override
- public void run() {
- runnable.run();
- done.setDone();
- }
- });
- return done;
- }
- });
- }
-
- public void setSelectedEditor(VirtualFile file, String fileEditorProviderId) {
- EditorWithProviderComposite composite = getCurrentEditorWithProviderComposite(file);
- if (composite == null) {
- final List composites = getEditorComposites(file);
-
- if (composites.isEmpty()) return;
- composite = composites.get(0);
- }
-
- final FileEditorProvider[] editorProviders = composite.getProviders();
- final FileEditorProvider selectedProvider = composite.getSelectedEditorWithProvider().getSecond();
-
- for (int i = 0; i < editorProviders.length; i++) {
- if (editorProviders[i].getEditorTypeId().equals(fileEditorProviderId) && !selectedProvider.equals(editorProviders[i])) {
- composite.setSelectedEditor(i);
- composite.getSelectedEditor().selectNotify();
- }
- }
- }
-
-
- @Nullable
- EditorWithProviderComposite newEditorComposite(final VirtualFile file) {
- if (file == null) {
- return null;
- }
-
- final FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
- final FileEditorProvider[] providers = editorProviderManager.getProviders(myProject, file);
- final FileEditor[] editors = new FileEditor[providers.length];
- for (int i = 0; i < providers.length; i++) {
- final FileEditorProvider provider = providers[i];
- LOG.assertTrue(provider != null);
- LOG.assertTrue(provider.accept(myProject, file));
- final FileEditor editor = provider.createEditor(myProject, file);
- editors[i] = editor;
- LOG.assertTrue(editor.isValid());
- editor.addPropertyChangeListener(myEditorPropertyChangeListener);
- }
-
- final EditorWithProviderComposite newComposite = new EditorWithProviderComposite(file, editors, providers, this);
- final EditorHistoryManager editorHistoryManager = EditorHistoryManager.getInstance(myProject);
- for (int i = 0; i < editors.length; i++) {
- final FileEditor editor = editors[i];
- if (editor instanceof TextEditor) {
- // hack!!!
- // This code prevents "jumping" on next repaint.
- //((EditorEx)((TextEditor)editor).getEditor()).stopOptimizedScrolling();
- }
-
- final FileEditorProvider provider = providers[i];
-
-// Restore myEditor state
- FileEditorState state = editorHistoryManager.getState(file, provider);
- if (state != null) {
- editor.setState(state);
- }
- }
- return newComposite;
- }
-
- @NotNull
- public List openEditor(@NotNull final OpenFileDescriptor descriptor, final boolean focusEditor) {
- assertDispatchThread();
- if (descriptor.getFile() instanceof VirtualFileWindow) {
- VirtualFileWindow delegate = (VirtualFileWindow)descriptor.getFile();
- int hostOffset = delegate.getDocumentWindow().injectedToHost(descriptor.getOffset());
- OpenFileDescriptor realDescriptor = new OpenFileDescriptor(descriptor.getProject(), delegate.getDelegate(), hostOffset);
- realDescriptor.setUseCurrentWindow(descriptor.isUseCurrentWindow());
- return openEditor(realDescriptor, focusEditor);
- }
-
- final List result = new ArrayList();
- CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
- public void run() {
- VirtualFile file = descriptor.getFile();
- final FileEditor[] editors = openFile(file, focusEditor, !descriptor.isUseCurrentWindow());
- ContainerUtil.addAll(result, editors);
-
- boolean navigated = false;
- for (final FileEditor editor : editors) {
- if (editor instanceof NavigatableFileEditor &&
- getSelectedEditor(descriptor.getFile()) == editor) { // try to navigate opened editor
- navigated = navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor);
- if (navigated) break;
- }
- }
-
- if (!navigated) {
- for (final FileEditor editor : editors) {
- if (editor instanceof NavigatableFileEditor && getSelectedEditor(descriptor.getFile()) != editor) { // try other editors
- if (navigateAndSelectEditor((NavigatableFileEditor)editor, descriptor)) {
- break;
- }
- }
- }
- }
- }
- }, "", null);
-
- return result;
- }
-
- private boolean navigateAndSelectEditor(final NavigatableFileEditor editor, final OpenFileDescriptor descriptor) {
- if (editor.canNavigateTo(descriptor)) {
- setSelectedEditor(editor);
- editor.navigateTo(descriptor);
- return true;
- }
-
- return false;
- }
-
- private void setSelectedEditor(final FileEditor editor) {
- final EditorWithProviderComposite composite = getEditorComposite(editor);
- if (composite == null) return;
-
- final FileEditor[] editors = composite.getEditors();
- for (int i = 0; i < editors.length; i++) {
- final FileEditor each = editors[i];
- if (editor == each) {
- composite.setSelectedEditor(i);
- composite.getSelectedEditor().selectNotify();
- break;
- }
- }
- }
-
- @NotNull
- public Project getProject() {
- return myProject;
- }
-
- @Nullable
- public Editor openTextEditor(final OpenFileDescriptor descriptor, final boolean focusEditor) {
- final Collection fileEditors = openEditor(descriptor, focusEditor);
- for (FileEditor fileEditor : fileEditors) {
- if (fileEditor instanceof TextEditor) {
- setSelectedEditor(descriptor.getFile(), TextEditorProvider.getInstance().getEditorTypeId());
- Editor editor = ((TextEditor)fileEditor).getEditor();
- return getOpenedEditor(editor, focusEditor);
- }
- }
-
- return null;
- }
-
- protected Editor getOpenedEditor(final Editor editor, final boolean focusEditor) {
- return editor;
- }
-
- public Editor getSelectedTextEditor() {
- assertReadAccess();
-
- final EditorWindow currentWindow = getSplitters().getCurrentWindow();
- if (currentWindow != null) {
- final EditorWithProviderComposite selectedEditor = currentWindow.getSelectedEditor();
- if (selectedEditor != null && selectedEditor.getSelectedEditor() instanceof TextEditor) {
- return ((TextEditor)selectedEditor.getSelectedEditor()).getEditor();
- }
- }
-
- return null;
- }
-
-
- public boolean isFileOpen(@NotNull final VirtualFile file) {
- return !getEditorComposites(file).isEmpty();
- }
-
- @NotNull
- public VirtualFile[] getOpenFiles() {
- HashSet openFiles = new HashSet();
- for (EditorsSplitters each : getAllSplitters()) {
- openFiles.addAll(Arrays.asList(each.getOpenFiles()));
- }
-
- return VfsUtilCore.toVirtualFileArray(openFiles);
- }
-
- @NotNull
- public VirtualFile[] getSelectedFiles() {
- HashSet selectedFiles = new HashSet();
- for (EditorsSplitters each : getAllSplitters()) {
- selectedFiles.addAll(Arrays.asList(each.getSelectedFiles()));
- }
-
- return VfsUtilCore.toVirtualFileArray(selectedFiles);
- }
-
- @NotNull
- public FileEditor[] getSelectedEditors() {
- HashSet selectedEditors = new HashSet