diff --git a/platform/core-impl/src/com/intellij/psi/impl/CheckUtil.java b/platform/core-impl/src/com/intellij/psi/impl/CheckUtil.java index 5ee064702422..0761ee87b187 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/CheckUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/CheckUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -17,7 +17,9 @@ package com.intellij.psi.impl; import com.intellij.openapi.fileTypes.FileTypeRegistry; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.psi.PsiBundle; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; @@ -49,17 +51,17 @@ public class CheckUtil { } public static void checkDelete(@NotNull final VirtualFile file) throws IncorrectOperationException { - if (FileTypeRegistry.getInstance().isFileIgnored(file)) { - return; - } - if (!file.isWritable()) { - throw new IncorrectOperationException(PsiBundle.message("cannot.delete.a.read.only.file", file.getPresentableUrl())); - } - if (file.isDirectory() && !file.isSymLink()) { - VirtualFile[] children = file.getChildren(); - for (VirtualFile aChildren : children) { - checkDelete(aChildren); + VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor(VirtualFileVisitor.NO_FOLLOW_SYMLINKS) { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (FileTypeRegistry.getInstance().isFileIgnored(file)) { + return false; + } + if (!file.isWritable()) { + throw new IncorrectOperationException(PsiBundle.message("cannot.delete.a.read.only.file", file.getPresentableUrl())); + } + return true; } - } + }); } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index 4356cfece39e..c7cb00668529 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -31,7 +31,9 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.psi.*; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.impl.PsiManagerImpl; @@ -48,8 +50,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import java.io.IOException; -import java.io.Writer; import java.util.*; import java.util.concurrent.ConcurrentMap; @@ -68,9 +68,7 @@ public class FileManagerImpl implements FileManager { private final FileDocumentManager myFileDocumentManager; private final MessageBusConnection myConnection; - public FileManagerImpl(PsiManagerImpl manager, - FileDocumentManager fileDocumentManager, - FileIndexFacade fileIndex) { + public FileManagerImpl(PsiManagerImpl manager, FileDocumentManager fileDocumentManager, FileIndexFacade fileIndex) { myManager = manager; myFileIndex = fileIndex; myConnection = manager.getProject().getMessageBus().connect(); @@ -78,21 +76,21 @@ public class FileManagerImpl implements FileManager { myFileDocumentManager = fileDocumentManager; myConnection.subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() { - @Override public void enteredDumbMode() { - recalcAllViewProviders(); + updateAllViewProviders(); } @Override public void exitDumbMode() { - recalcAllViewProviders(); + updateAllViewProviders(); } }); Disposer.register(manager.getProject(), this); } private static final VirtualFile NULL = new LightVirtualFile(); + public void processQueue() { // just to call processQueue() myVFileToViewProviderMap.remove(NULL); @@ -103,7 +101,7 @@ public class FileManagerImpl implements FileManager { return myVFileToViewProviderMap; } - private void recalcAllViewProviders() { + private void updateAllViewProviders() { handleFileTypesChange(new FileTypesChanged() { @Override protected void updateMaps() { @@ -391,17 +389,18 @@ public class FileManagerImpl implements FileManager { } void removeFilesAndDirsRecursively(VirtualFile vFile) { - if (vFile.isDirectory()) { - myVFileToPsiDirMap.remove(vFile); - - VirtualFile[] children = vFile.getChildren(); - for (VirtualFile child : children) { - removeFilesAndDirsRecursively(child); + VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (file.isDirectory()) { + myVFileToPsiDirMap.remove(file); + } + else { + myVFileToViewProviderMap.remove(file); + } + return true; } - } - else { - myVFileToViewProviderMap.remove(vFile); - } + }); } @Nullable @@ -411,6 +410,7 @@ public class FileManagerImpl implements FileManager { ? ((SingleRootFileViewProvider)fileViewProvider).getCachedPsi(fileViewProvider.getBaseLanguage()) : null; } + @NotNull @Override public List getAllCachedFiles() { List files = new ArrayList(); @@ -514,18 +514,4 @@ public class FileManagerImpl implements FileManager { myManager.childrenChanged(event); } } - - @SuppressWarnings({"HardCodedStringLiteral"}) - public void dumpFilesWithContentLoaded(Writer out) throws IOException { - out.write("Files with content loaded cached in FileManagerImpl:\n"); - Set vFiles = myVFileToViewProviderMap.keySet(); - for (VirtualFile fileCacheEntry : vFiles) { - final FileViewProvider view = myVFileToViewProviderMap.get(fileCacheEntry); - PsiFile psiFile = view.getPsi(view.getBaseLanguage()); - if (psiFile instanceof PsiFileImpl && ((PsiFileImpl)psiFile).isContentsLoaded()) { - out.write(fileCacheEntry.getPresentableUrl()); - out.write("\n"); - } - } - } } diff --git a/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java b/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java index 596df393bd7e..cc7be9cc0ea3 100644 --- a/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java +++ b/platform/lang-api/src/com/intellij/refactoring/util/CommonRefactoringUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -115,7 +115,7 @@ public class CommonRefactoringUtil { } else { if (recursively) { - addVirtualFiles(vFile, readonly); + collectReadOnlyFiles(vFile, readonly); } else { readonly.add(vFile); @@ -131,7 +131,7 @@ public class CommonRefactoringUtil { failed.add(virtualFile); } else { - addVirtualFiles(virtualFile, readonly); + collectReadOnlyFiles(virtualFile, readonly); } } else { @@ -165,7 +165,7 @@ public class CommonRefactoringUtil { } } - final VirtualFile[] files = VfsUtil.toVirtualFileArray(readonly); + final VirtualFile[] files = VfsUtilCore.toVirtualFileArray(readonly); final ReadonlyStatusHandler.OperationStatus status = ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(files); ContainerUtil.addAll(failed, status.getReadonlyFiles()); if (notifyOnFail && (!failed.isEmpty() || seenNonWritablePsiFilesWithoutVirtualFile && readonly.isEmpty())) { @@ -195,20 +195,18 @@ public class CommonRefactoringUtil { return failed.isEmpty(); } - private static void addVirtualFiles(final VirtualFile vFile, final Collection list) { - if (!vFile.isWritable()) { - list.add(vFile); - } - if (!vFile.isSymLink()) { - final VirtualFile[] children = vFile.getChildren(); - if (children != null) { - final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - for (VirtualFile virtualFile : children) { - if (fileTypeManager.isFileIgnored(virtualFile)) continue; - addVirtualFiles(virtualFile, list); + public static void collectReadOnlyFiles(final VirtualFile vFile, final Collection list) { + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + + VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor(VirtualFileVisitor.NO_FOLLOW_SYMLINKS) { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!vFile.isWritable() && !fileTypeManager.isFileIgnored(file)) { + list.add(vFile); } + return true; } - } + }); } public static String capitalize(String text) { diff --git a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java index 36611568fbdb..255e3effa506 100644 --- a/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java +++ b/platform/lang-impl/src/com/intellij/analysis/BaseAnalysisAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -29,7 +29,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.JarFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -216,15 +218,15 @@ public abstract class BaseAnalysisAction extends AnAction { return null; } - private static void traverseDirectory(VirtualFile vFile, Set files) { - if (vFile.isDirectory()) { - final VirtualFile[] virtualFiles = vFile.getChildren(); - for (VirtualFile virtualFile : virtualFiles) { - traverseDirectory(virtualFile, files); + private static void traverseDirectory(final VirtualFile vFile, final Set files) { + VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!file.isDirectory()) { + files.add(file); + } + return true; } - } - else { - files.add(vFile); - } + }); } } diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionProcessor.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionProcessor.java index 715b25c6aa0b..502a341eb6ca 100644 --- a/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionProcessor.java +++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/FrameworkDetectionProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -22,7 +22,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.patterns.ElementPattern; import com.intellij.util.containers.MultiMap; import com.intellij.util.indexing.FileContent; @@ -72,35 +74,46 @@ public class FrameworkDetectionProcessor { } private void collectSuitableFiles(@NotNull VirtualFile file) { - if (myProgressIndicator.isCanceled() || !myProcessedFiles.add(file)) return; + class CancelledException extends RuntimeException { } - if (file.isDirectory()) { - file.getChildren();//initialize myChildren field to ensure that refresh will be really performed - file.refresh(false, false); - VirtualFile[] children = file.getChildren(); - for (VirtualFile child : children) { - collectSuitableFiles(child); - } - return; - } - - final FileType fileType = file.getFileType(); - if (!myDetectorsByFileType.containsKey(fileType)) { - return; - } - - myProgressIndicator.setText2(file.getPresentableUrl()); try { - FileContent fileContent = new FileContentImpl(file, file.contentsToByteArray(false)); - for (FrameworkDetectorData detector : myDetectorsByFileType.get(fileType)) { - if (detector.myFilePattern.accepts(fileContent)) { - detector.mySuitableFiles.add(file); + VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (myProgressIndicator.isCanceled()) { + throw new CancelledException(); + } + if (!myProcessedFiles.add(file)) { + return false; + } + + if (file.isDirectory()) { + file.getChildren(); // initialize myChildren field to ensure that refresh will be really performed + file.refresh(false, false); + } + else { + final FileType fileType = file.getFileType(); + if (myDetectorsByFileType.containsKey(fileType)) { + myProgressIndicator.setText2(file.getPresentableUrl()); + try { + final FileContent fileContent = new FileContentImpl(file, file.contentsToByteArray(false)); + for (FrameworkDetectorData detector : myDetectorsByFileType.get(fileType)) { + if (detector.myFilePattern.accepts(fileContent)) { + detector.mySuitableFiles.add(file); + } + } + } + catch (IOException e) { + LOG.info(e); + } + } + } + + return true; } - } - } - catch (IOException e) { - LOG.info(e); + }); } + catch (CancelledException ignored) { } } private static class FrameworkDetectorData { 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 9c8ca5ae68e1..1ac03875ad28 100644 --- a/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/impl/PatchProjectUtil.java @@ -23,16 +23,17 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; 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.roots.impl.ModifiableModelCommitter; 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; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.HashSet; @@ -109,10 +110,10 @@ public class PatchProjectUtil { final VirtualFile parent = file.getParent(); if (parent == null || parents.contains(parent)) continue; parents.add(parent); - for (VirtualFile toExclude : parent.getChildren()) { + for (VirtualFile toExclude : parent.getChildren()) { // if it will ever dead-loop on symlink blame anna.kozlova boolean toExcludeSibling = true; for (VirtualFile includeRoot : included) { - if (VfsUtil.isAncestor(toExclude, includeRoot, false)) { + if (VfsUtilCore.isAncestor(toExclude, includeRoot, false)) { toExcludeSibling = false; } } @@ -124,13 +125,15 @@ public class PatchProjectUtil { processIncluded(contentEntry, parents); } - public static void iterate(VirtualFile contentRoot, ContentIterator iterator, ProjectFileIndex idx) { - if (!iterator.processFile(contentRoot)) return; - if (idx.getModuleForFile(contentRoot) == null) return; //already excluded - final VirtualFile[] files = contentRoot.getChildren(); - for (VirtualFile file : files) { - iterate(file, iterator, idx); - } + public static void iterate(VirtualFile contentRoot, final ContentIterator iterator, final ProjectFileIndex idx) { + VfsUtilCore.visitChildrenRecursively(contentRoot, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!iterator.processFile(file)) return false; + if (idx.getModuleForFile(file) == null) return false; // already excluded + return true; + } + }); } public static Map> loadPatterns(@NonNls String propertyKey) { diff --git a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java index 1236e960cc91..39d236678b1d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java +++ b/platform/lang-impl/src/com/intellij/ide/util/DeleteHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -29,7 +29,6 @@ import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; @@ -37,7 +36,10 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.ex.MessagesEx; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.WritingAccessProvider; -import com.intellij.psi.*; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.psi.util.PsiUtilCore; @@ -168,7 +170,6 @@ public class DeleteHandler { } } - final FileTypeManager ftManager = FileTypeManager.getInstance(); CommandProcessor.getInstance().executeCommand(project, new Runnable() { public void run() { if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(elements), false)) { @@ -186,12 +187,11 @@ public class DeleteHandler { VirtualFile virtualFile = ((PsiDirectory)elementToDelete).getVirtualFile(); if (virtualFile.isInLocalFileSystem() && !virtualFile.isSymLink()) { ArrayList readOnlyFiles = new ArrayList(); - getReadOnlyVirtualFiles(virtualFile, readOnlyFiles, ftManager); + CommonRefactoringUtil.collectReadOnlyFiles(virtualFile, readOnlyFiles); if (!readOnlyFiles.isEmpty()) { - int _result = Messages.showYesNoDialog(project, IdeBundle.message("prompt.directory.contains.read.only.files", - virtualFile.getPresentableUrl()), - IdeBundle.message("title.delete"), Messages.getQuestionIcon()); + String message = IdeBundle.message("prompt.directory.contains.read.only.files", virtualFile.getPresentableUrl()); + int _result = Messages.showYesNoDialog(project, message, IdeBundle.message("title.delete"), Messages.getQuestionIcon()); if (_result != 0) continue; boolean success = true; @@ -269,22 +269,6 @@ public class DeleteHandler { return success[0]; } - /** - * Fills readOnlyFiles with VirtualFiles - */ - private static void getReadOnlyVirtualFiles(VirtualFile file, ArrayList readOnlyFiles, final FileTypeManager ftManager) { - if (ftManager.isFileIgnored(file)) return; - if (!file.isWritable()) { - readOnlyFiles.add(file); - } - if (file.isDirectory()) { - VirtualFile[] children = file.getChildren(); - for (VirtualFile child : children) { - getReadOnlyVirtualFiles(child, readOnlyFiles, ftManager); - } - } - } - public static boolean shouldEnableDeleteAction(PsiElement[] elements) { if (elements == null || elements.length == 0) return false; for (PsiElement element : elements) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java b/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java index e176b16be1ac..748ca3bccccf 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -17,8 +17,9 @@ package com.intellij.util.indexing; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.roots.ContentIterator; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -48,7 +49,7 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { THashSet files = new THashSet(); THashSet directories = new THashSet(); if (myExtensions == null) { - myExtensions = Extensions.getExtensions(IndexableSetContributor.EP_NAME); + myExtensions = Extensions.getExtensions(IndexedRootsProvider.EP_NAME); } for (IndexedRootsProvider provider : myExtensions) { for(VirtualFile file:IndexableSetContributor.getRootsToIndex(provider)) { @@ -75,7 +76,7 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { @Override public boolean isInSet(@NotNull VirtualFile file) { for (final VirtualFile root : getDirectories()) { - if (VfsUtil.isAncestor(root, file, false)) { + if (VfsUtilCore.isAncestor(root, file, false)) { return true; } } @@ -83,16 +84,20 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { } @Override - public void iterateIndexableFilesIn(@NotNull VirtualFile file, @NotNull ContentIterator iterator) { - if (!isInSet(file)) return; + public void iterateIndexableFilesIn(@NotNull VirtualFile file, @NotNull final ContentIterator iterator) { + VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!isInSet(file)) { + return false; + } - if (file.isDirectory()) { - for (VirtualFile child : file.getChildren()) { - iterateIndexableFilesIn(child, iterator); + if (!file.isDirectory()) { + iterator.processFile(file); + } + + return true; } - } - else { - iterator.processFile(file); - } + }); } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index c6b66414d66e..3ebcb65dde74 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -87,9 +87,8 @@ import java.util.concurrent.locks.Lock; /** * @author Eugene Zhuravlev - * Date: Dec 20, 2007 + * @since Dec 20, 2007 */ - public class FileBasedIndexImpl extends FileBasedIndex { private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.FileBasedIndexImpl"); @NonNls @@ -126,23 +125,13 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Nullable private ScheduledFuture myFlushingFuture; private volatile int myLocalModCount; private volatile int myFilesModCount; - private volatile boolean myInitialized; // need this variable for memory barrier - @Override - public void requestReindex(@NotNull final VirtualFile file) { - myChangedFilesCollector.invalidateIndices(file, true); - } - - @Override - public void requestReindexExcluded(@NotNull final VirtualFile file) { - myChangedFilesCollector.invalidateIndices(file, false); - } + @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private volatile boolean myInitialized; // need this variable for memory barrier public FileBasedIndexImpl(final VirtualFileManagerEx vfManager, FileDocumentManager fdm, FileTypeManager fileTypeManager, @NotNull MessageBus bus, - SerializationManager sm - /*need this parameter to ensure component dependency*/) throws IOException { + @SuppressWarnings("UnusedParameters") SerializationManager sm /*needed to ensure dependency*/) throws IOException { myVfManager = vfManager; myFileDocumentManager = fdm; myFileTypeManager = fileTypeManager; @@ -266,15 +255,16 @@ public class FileBasedIndexImpl extends FileBasedIndex { }); myChangedFilesCollector = new ChangedFilesCollector(); + } - /* - final File workInProgressFile = getMarkerFile(); - if (workInProgressFile.exists()) { - // previous IDEA session was closed incorrectly, so drop all indices - FileUtil.delete(PathManager.getIndexRoot()); - } - */ + @Override + public void requestReindex(@NotNull final VirtualFile file) { + myChangedFilesCollector.invalidateIndices(file, true); + } + @Override + public void requestReindexExcluded(@NotNull final VirtualFile file) { + myChangedFilesCollector.invalidateIndices(file, false); } private void initExtensions() { @@ -335,10 +325,9 @@ public class FileBasedIndexImpl extends FileBasedIndex { performShutdown(); } }); - //FileUtil.createIfDoesntExist(workInProgressFile); saveRegisteredIndices(myIndices.keySet()); myFlushingFuture = FlushingDaemon.everyFiveSeconds(new Runnable() { - int lastModCount = 0; + private int lastModCount = 0; @Override public void run() { @@ -424,7 +413,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { try { if (storage != null) storage.close(); storage = null; - } catch (Exception ex) {} + } + catch (Exception ignored) { } FileUtil.delete(IndexInfrastructure.getIndexRootDir(name)); IndexInfrastructure.rewriteVersion(versionFile, version); @@ -478,13 +468,14 @@ public class FileBasedIndexImpl extends FileBasedIndex { } @NotNull - private UpdatableIndex createIndex(@NotNull final ID indexId, @NotNull final FileBasedIndexExtension extension, @NotNull final MemoryIndexStorage storage) throws StorageException, IOException { + private UpdatableIndex createIndex(@NotNull final ID indexId, + @NotNull final FileBasedIndexExtension extension, + @NotNull final MemoryIndexStorage storage) + throws StorageException, IOException { final MapReduceIndex index; if (extension instanceof CustomImplementationFileBasedIndexExtension) { - final UpdatableIndex custom = ((CustomImplementationFileBasedIndexExtension)extension).createIndexImplementation(indexId, this, storage); - - assert custom != null : "Custom index implementation must not be null; index: " + indexId; - + final UpdatableIndex custom = + ((CustomImplementationFileBasedIndexExtension)extension).createIndexImplementation(indexId, this, storage); if (!(custom instanceof MapReduceIndex)) { return custom; } @@ -645,8 +636,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { //FileUtil.delete(getMarkerFile()); } catch (Throwable e) { - LOG.info("Problems during index shutdown", e); - throw new RuntimeException(e); + LOG.error("Problems during index shutdown", e); } LOG.info("END INDEX SHUTDOWN"); } @@ -1007,7 +997,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { set.forEach(new TIntProcedure() { @Override public boolean execute(int value) { - value = value - myMinId; + value -= myMinId; myBitMask[value >> SHIFT] |= (1L << (value & MASK)); return true; } @@ -1084,8 +1074,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { ValueContainer.IntIterator iterator = container.getInputIdsIterator(value); if (mainIntersection == null || iterator.size() < mainIntersection.size()) { - for (final ValueContainer.IntIterator inputIdsIterator = iterator; inputIdsIterator.hasNext(); ) { - final int id = inputIdsIterator.next(); + while (iterator.hasNext()) { + final int id = iterator.next(); if (mainIntersection == null && (projectFilesFilter == null || projectFilesFilter.contains(id)) || mainIntersection != null && mainIntersection.contains(id) ) { @@ -1842,83 +1832,94 @@ public class FileBasedIndexImpl extends FileBasedIndex { myFilesToUpdate.add(file); } - void invalidateIndices(@NotNull final VirtualFile file, final boolean markForReindex) { - if (isUnderConfigOrSystem(file)) { - return; - } - if (file.isDirectory()) { - if (isMock(file) || myManagingFS.wereChildrenAccessed(file)) { - final Iterable children = file instanceof NewVirtualFile - ? ((NewVirtualFile)file).iterInDbChildren() : Arrays.asList(file.getChildren()); - for (VirtualFile child : children) { - invalidateIndices(child, markForReindex); + private void invalidateIndices(@NotNull final VirtualFile file, final boolean markForReindex) { + VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (isUnderConfigOrSystem(file)) { + return false; } - } - } - else { - cleanProcessedFlag(file); - IndexingStamp.flushCache(file); - final List> affectedIndices = new ArrayList>(myIndices.size()); - - for (final ID indexId : myIndices.keySet()) { - try { - if (!needsFileContentLoading(indexId)) { - if (shouldUpdateIndex(file, indexId)) { - updateSingleIndex(indexId, file, null); - } + if (file.isDirectory()) { + if (!isMock(file) && !myManagingFS.wereChildrenAccessed(file)) { + return false; } - else { // the index requires file content - if (shouldUpdateIndex(file, indexId)) { - affectedIndices.add(indexId); - } - } - } - catch (StorageException e) { - LOG.info(e); - requestRebuild(indexId); - } - } - - if (!affectedIndices.isEmpty()) { - if (markForReindex && !isTooLarge(file)) { - // only mark the file as unindexed, reindex will be done lazily - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - for (ID indexId : affectedIndices) { - IndexingStamp.update(file, indexId, IndexInfrastructure.INVALID_STAMP2); - } - } - }); - // the file is for sure not a dir and it was previously indexed by at least one index - scheduleForUpdate(file); } else { - myFutureInvalidations.offer(new InvalidationTask(file) { - @Override - public void run() { - removeFileDataFromIndices(affectedIndices, file); - } - }); + invalidateIndicesForFile(file, markForReindex); + } + return true; + } + + @Override + public Iterable getChildrenIterable(@NotNull VirtualFile file) { + return file instanceof NewVirtualFile ? ((NewVirtualFile)file).iterInDbChildren() : Arrays.asList(file.getChildren()); + } + }); + } + + private void invalidateIndicesForFile(final VirtualFile file, boolean markForReindex) { + cleanProcessedFlag(file); + IndexingStamp.flushCache(file); + final List> affectedIndices = new ArrayList>(myIndices.size()); + + for (final ID indexId : myIndices.keySet()) { + try { + if (!needsFileContentLoading(indexId)) { + if (shouldUpdateIndex(file, indexId)) { + updateSingleIndex(indexId, file, null); + } + } + else { // the index requires file content + if (shouldUpdateIndex(file, indexId)) { + affectedIndices.add(indexId); + } } } - if (!markForReindex) { - final boolean removedFromUpdateQueue = myFilesToUpdate.remove(file);// no need to update it anymore - if (removedFromUpdateQueue && affectedIndices.isEmpty()) { - // Currently the file is about to be deleted and previously it was scheduled for update and not processed up to now. - // Because the file was scheduled for update, at the moment of scheduling it was marked as unindexed, - // so, to be on the safe side, we have to schedule data invalidation from all content-requiring indices for this file - myFutureInvalidations.offer(new InvalidationTask(file) { - @Override - public void run() { - removeFileDataFromIndices(myRequiringContentIndices, file); - } - }); - } + catch (StorageException e) { + LOG.info(e); + requestRebuild(indexId); } - - IndexingStamp.flushCache(file); } + + if (!affectedIndices.isEmpty()) { + if (markForReindex && !isTooLarge(file)) { + // only mark the file as unindexed, reindex will be done lazily + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + for (ID indexId : affectedIndices) { + IndexingStamp.update(file, indexId, IndexInfrastructure.INVALID_STAMP2); + } + } + }); + // the file is for sure not a dir and it was previously indexed by at least one index + scheduleForUpdate(file); + } + else { + myFutureInvalidations.offer(new InvalidationTask(file) { + @Override + public void run() { + removeFileDataFromIndices(affectedIndices, file); + } + }); + } + } + if (!markForReindex) { + final boolean removedFromUpdateQueue = myFilesToUpdate.remove(file);// no need to update it anymore + if (removedFromUpdateQueue && affectedIndices.isEmpty()) { + // Currently the file is about to be deleted and previously it was scheduled for update and not processed up to now. + // Because the file was scheduled for update, at the moment of scheduling it was marked as unindexed, + // so, to be on the safe side, we have to schedule data invalidation from all content-requiring indices for this file + myFutureInvalidations.offer(new InvalidationTask(file) { + @Override + public void run() { + removeFileDataFromIndices(myRequiringContentIndices, file); + } + }); + } + } + + IndexingStamp.flushCache(file); } private void removeFileDataFromIndices(@NotNull Collection> affectedIndices, @NotNull VirtualFile file) { @@ -2299,29 +2300,29 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - private static void iterateRecursively(@Nullable final VirtualFile root, @NotNull final ContentIterator processor, @Nullable ProgressIndicator indicator) { - if (root != null) { - if (indicator != null) { - indicator.checkCanceled(); - indicator.setText2(root.getPresentableUrl()); - } - - if (root.isDirectory()) { - for (VirtualFile file : root.getChildren()) { - if (file.isDirectory()) { - iterateRecursively(file, processor, indicator); - } - else { - processor.processFile(file); - } - } - } - else { - processor.processFile(root); - } + private static void iterateRecursively(@Nullable final VirtualFile root, + @NotNull final ContentIterator processor, + @Nullable final ProgressIndicator indicator) { + if (root == null) { + return; } + + VfsUtilCore.visitChildrenRecursively(root, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (indicator != null) { + indicator.checkCanceled(); + indicator.setText2(file.getPresentableUrl()); + } + if (!file.isDirectory()) { + processor.processFile(file); + } + return true; + } + }); } + @SuppressWarnings({"WhileLoopSpinsOnField", "SynchronizeOnThis"}) private static class StorageGuard { private int myHolds = 0; @@ -2374,6 +2375,5 @@ public class FileBasedIndexImpl extends FileBasedIndex { notifyAll(); } } - } } 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 abe8ccdb77fd..18a6cdf51c8e 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/VfsUtil.java @@ -51,6 +51,7 @@ public class VfsUtil extends VfsUtilCore { /** * Copies all files matching the filter from fromDir to toDir. + * Symlinks end special files are ignored. * * @param requestor any object to control who called this method. Note that * it is considered to be an external change if requestor is null. @@ -60,11 +61,13 @@ public class VfsUtil extends VfsUtilCore { * @param filter {@link VirtualFileFilter} * @throws IOException if files failed to be copied */ - public static void copyDirectory(Object requestor, @NotNull VirtualFile fromDir, @NotNull VirtualFile toDir, @Nullable VirtualFileFilter filter) - throws IOException { - VirtualFile[] children = fromDir.getChildren(); + public static void copyDirectory(Object requestor, + @NotNull VirtualFile fromDir, + @NotNull VirtualFile toDir, + @Nullable VirtualFileFilter filter) throws IOException { + @SuppressWarnings("UnsafeVfsRecursion") VirtualFile[] children = fromDir.getChildren(); for (VirtualFile child : children) { - if (filter == null || filter.accept(child)) { + if (!child.isSymLink() && !child.isSpecialFile() && (filter == null || filter.accept(child))) { if (!child.isDirectory()) { copyFile(requestor, child, toDir); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/FixLineSeparatorsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/FixLineSeparatorsAction.java index 0944fca0f57c..4bc4cd738dea 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/FixLineSeparatorsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/FixLineSeparatorsAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -23,7 +23,10 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -44,20 +47,18 @@ public class FixLineSeparatorsAction extends AnAction { } private static void fixSeparators(VirtualFile vFile) { - if (vFile.isDirectory()) { - for (VirtualFile child : vFile.getChildren()) { - fixSeparators(child); + VfsUtilCore.visitChildrenRecursively(vFile, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!file.isDirectory() && !file.getFileType().isBinary()) { + final Document document = FileDocumentManager.getInstance().getDocument(file); + if (areSeparatorsBroken(document)) { + fixSeparators(document); + } + } + return true; } - } - else { - if (vFile.getFileType().isBinary()) { - return; - } - final Document document = FileDocumentManager.getInstance().getDocument(vFile); - if (areSeparatorsBroken(document)) { - fixSeparators(document); - } - } + }); } private static boolean areSeparatorsBroken(Document document) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/PruneEmptyDirectoriesAction.java b/platform/platform-impl/src/com/intellij/ide/actions/PruneEmptyDirectoriesAction.java index e400f63ff3f5..32e00cb73bb0 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/PruneEmptyDirectoriesAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/PruneEmptyDirectoriesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -25,7 +25,10 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; +import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -47,33 +50,42 @@ public class PruneEmptyDirectoriesAction extends AnAction { pruneEmptiesIn(file, ftManager); } } - catch (IOException e1) { - - } + catch (IOException ignored) { } } - private static void pruneEmptiesIn(final VirtualFile file, FileTypeManager ftManager) throws IOException { - if (file.isDirectory()) { - if (ftManager.isFileIgnored(file)) return; - - for (VirtualFile child : file.getChildren()) { - pruneEmptiesIn(child, ftManager); + private static void pruneEmptiesIn(VirtualFile file, final FileTypeManager ftManager) throws IOException { + VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (file.isDirectory()) { + if (ftManager.isFileIgnored(file)) { + return false; + } + } + else { + if (".DS_Store".equals(file.getName())) { + delete(file); + return false; + } + } + return true; } - if (file.getChildren().length == 0) { - delete(file); + @Override + public void afterChildrenVisited(@NotNull VirtualFile file) { + if (file.isDirectory() && file.getChildren().length == 0) { + delete(file); + } } - } - else if (".DS_Store".equals(file.getName())) { - delete(file); - } + }); } private static void delete(final VirtualFile file) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { try { - file.delete(null); + file.delete(PruneEmptyDirectoriesAction.class); + //noinspection UseOfSystemOutOrSystemErr System.out.println("Deleted: " + file.getPresentableUrl()); } catch (IOException e) { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index ce6cf2cae7f6..663dfa37c06b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -129,11 +129,12 @@ public class FileBasedStorage extends XmlElementStorage { } private static void requestAllChildren(final VirtualFile configDir, @Nullable final String excludeDir) { - if (excludeDir == null || !excludeDir.equals(configDir.getName())) { - for (VirtualFile file : configDir.getChildren()) { - requestAllChildren(file, excludeDir); + VfsUtilCore.visitChildrenRecursively(configDir, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + return excludeDir == null || !excludeDir.equals(file.getName()); } - } + }); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java index e33ce1bc07c9..232dbe8e7fe6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -45,7 +45,7 @@ public class DummyFileSystem extends DeprecatedVirtualFileSystem implements NonP private static VirtualFile findById(final int id, final VirtualFileImpl r) { if (r == null) return null; if (r.getId() == id) return r; - final VirtualFile[] children = r.getChildren(); + @SuppressWarnings("UnsafeVfsRecursion") final VirtualFile[] children = r.getChildren(); if (children != null) { for (VirtualFile f : children) { final VirtualFile child = findById(id, (VirtualFileImpl)f); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index c8c5ef088ac9..6909760dc09d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.roots.impl; import com.intellij.openapi.Disposable; @@ -30,6 +29,7 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtilCore; @@ -50,17 +50,17 @@ import java.util.*; public class DirectoryIndexImpl extends DirectoryIndex { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexImpl"); + private static final Key PACKAGE_NAME = Key.create("dir.index.visitor.package.name"); + protected final Project myProject; + protected final DirectoryIndexExcludePolicy[] myExcludePolicies; + protected volatile IndexState myState; private boolean myInitialized = false; private boolean myDisposed = false; - protected volatile IndexState myState; - - protected final DirectoryIndexExcludePolicy[] myExcludePolicies; public DirectoryIndexImpl(Project project) { myProject = project; - myExcludePolicies = Extensions.getExtensions(DirectoryIndexExcludePolicy.EP_NAME, myProject); myState = new IndexState(); Disposer.register(project, new Disposable() { @@ -264,9 +264,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { } void fillMapWithModuleContent(VirtualFile root, final Module module, final VirtualFile contentRoot, @Nullable final ProgressIndicator progress) { - VfsUtilCore.visitChildrenRecursively(root, new DirectoryVisitor() { - @Override protected DirectoryInfo updateInfo(VirtualFile file) { if (progress != null) { @@ -294,9 +292,8 @@ public class DirectoryIndexImpl extends DirectoryIndex { } private abstract class DirectoryVisitor extends VirtualFileVisitor { - private final Stack myDirectoryInfoStack = new Stack(); - + @Override public boolean visitFile(@NotNull VirtualFile file) { if (!file.isDirectory()) return false; @@ -305,7 +302,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { myDirectoryInfoStack.push(info); return true; } - return false; + return false; } @Override @@ -318,7 +315,7 @@ public class DirectoryIndexImpl extends DirectoryIndex { protected void afterChildrenVisited(DirectoryInfo info) {} } - + private boolean isExcluded(VirtualFile root, VirtualFile dir) { Set excludes = myExcludeRootsMap.get(root); return excludes != null && excludes.contains(dir.getUrl()); @@ -368,7 +365,6 @@ public class DirectoryIndexImpl extends DirectoryIndex { final String packageName, final VirtualFile sourceRoot, final boolean isTestSource, @Nullable final ProgressIndicator progress) { - VfsUtilCore.visitChildrenRecursively(dir, new DirectoryVisitor() { private final Stack myPackages = new Stack(); @@ -425,30 +421,36 @@ public class DirectoryIndexImpl extends DirectoryIndex { } } - protected void fillMapWithLibrarySources(VirtualFile dir, String packageName, VirtualFile sourceRoot, @Nullable ProgressIndicator progress) { - if (progress != null) { - progress.checkCanceled(); - } - if (isIgnored(dir)) return; + protected void fillMapWithLibrarySources(final VirtualFile dir, + final String packageName, + final VirtualFile sourceRoot, + @Nullable final ProgressIndicator progress) { + VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() { + { set(PACKAGE_NAME, packageName); } - DirectoryInfo info = getOrCreateDirInfo(dir); + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (progress != null) progress.checkCanceled(); + if (!file.isDirectory() || isIgnored(file)) return false; - if (info.isInLibrarySource) { // library sources overlap - String definedPackage = myDirToPackageName.get(dir); - if (definedPackage != null && definedPackage.isEmpty()) return; // another library source root starts here - } + DirectoryInfo info = getOrCreateDirInfo(file); - info.isInLibrarySource = true; - info.sourceRoot = sourceRoot; - setPackageName(dir, packageName); + if (info.isInLibrarySource) { // library sources overlap + String definedPackage = myDirToPackageName.get(file); + if (definedPackage != null && definedPackage.isEmpty()) return false; // another library source root starts here + } - VirtualFile[] children = dir.getChildren(); - for (VirtualFile child : children) { - if (child.isDirectory()) { - String childPackageName = getPackageNameForSubdir(packageName, child.getName()); - fillMapWithLibrarySources(child, childPackageName, sourceRoot, progress); + info.isInLibrarySource = true; + info.sourceRoot = sourceRoot; + + final String packageName = get(PACKAGE_NAME); + final String newPackageName = file == dir ? packageName : getPackageNameForSubdir(packageName, file.getName()); + setPackageName(file, newPackageName); + set(PACKAGE_NAME, newPackageName); + + return true; } - } + }); } private void initLibraryClasses(Module module, ProgressIndicator progress) { @@ -465,32 +467,37 @@ public class DirectoryIndexImpl extends DirectoryIndex { } } - protected void fillMapWithLibraryClasses(VirtualFile dir, String packageName, VirtualFile classRoot, @Nullable ProgressIndicator progress) { - if (progress != null) { - progress.checkCanceled(); - } - if (isIgnored(dir)) return; + protected void fillMapWithLibraryClasses(final VirtualFile dir, + final String packageName, + final VirtualFile classRoot, + @Nullable final ProgressIndicator progress) { + VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() { + { set(PACKAGE_NAME, packageName); } - DirectoryInfo info = getOrCreateDirInfo(dir); + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (progress != null) progress.checkCanceled(); + if (!file.isDirectory() || isIgnored(file)) return false; - if (info.libraryClassRoot != null) { // library classes overlap - String definedPackage = myDirToPackageName.get(dir); - if (definedPackage != null && definedPackage.isEmpty()) return; // another library root starts here - } + DirectoryInfo info = getOrCreateDirInfo(file); - info.libraryClassRoot = classRoot; + if (info.libraryClassRoot != null) { // library classes overlap + String definedPackage = myDirToPackageName.get(file); + if (definedPackage != null && definedPackage.isEmpty()) return false; // another library root starts here + } - if (!info.isInModuleSource && !info.isInLibrarySource) { - setPackageName(dir, packageName); - } + info.libraryClassRoot = classRoot; - VirtualFile[] children = dir.getChildren(); - for (VirtualFile child : children) { - if (child.isDirectory()) { - String childPackageName = getPackageNameForSubdir(packageName, child.getName()); - fillMapWithLibraryClasses(child, childPackageName, classRoot, progress); + final String packageName = get(PACKAGE_NAME); + final String newPackageName = file == dir ? packageName : getPackageNameForSubdir(packageName, file.getName()); + if (!info.isInModuleSource && !info.isInLibrarySource) { + setPackageName(file, newPackageName); + } + set(PACKAGE_NAME, newPackageName); + + return true; } - } + }); } private void initOrderEntries(Module module, @@ -593,7 +600,6 @@ public class DirectoryIndexImpl extends DirectoryIndex { @Nullable final VirtualFile libraryClassRoot, @Nullable final VirtualFile librarySourceRoot, @Nullable final DirectoryInfo parentInfo, @Nullable final ProgressIndicator progress) { - VfsUtilCore.visitChildrenRecursively(root, new DirectoryVisitor() { private final Stack> myEntries = new Stack>(); @@ -770,4 +776,4 @@ public class DirectoryIndexImpl extends DirectoryIndex { return copy; } } -} +} \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 174ca848ea83..454634f8550d 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.roots.impl.libraries; import com.intellij.openapi.Disposable; @@ -32,6 +31,7 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; @@ -49,6 +49,9 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static com.intellij.openapi.vfs.VirtualFileVisitor.ONE_LEVEL_DEEP; +import static com.intellij.openapi.vfs.VirtualFileVisitor.SKIP_ROOT; + /** * @author dsl */ @@ -173,17 +176,17 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi } public static void collectJarFiles(final VirtualFile dir, final List container, final boolean recursively) { - for (VirtualFile child : dir.getChildren()) { - final VirtualFile jarRoot = StandardFileSystems.getJarRootForLocalFile(child); - if (jarRoot != null) { - container.add(jarRoot); - } - else { - if (recursively && child.isDirectory()) { - collectJarFiles(child, container, recursively); + VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor(SKIP_ROOT, (recursively ? null : ONE_LEVEL_DEEP)) { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + final VirtualFile jarRoot = StandardFileSystems.getJarRootForLocalFile(file); + if (jarRoot != null) { + container.add(jarRoot); + return false; } + return true; } - } + }); } @Override diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 2ab5790586fb..5cf65ba2fae3 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -240,8 +240,8 @@ public abstract class VcsVFSListener implements Disposable { } private void addFileToMove(final VirtualFile file, final String newParentPath, final String newName) { - if (file.isDirectory() && !isDirectoryVersioningSupported()) { - VirtualFile[] children = file.getChildren(); + if (file.isDirectory() && !file.isSymLink() && !isDirectoryVersioningSupported()) { + @SuppressWarnings("UnsafeVfsRecursion") VirtualFile[] children = file.getChildren(); if (children != null) { for (VirtualFile child : children) { addFileToMove(child, newParentPath + "/" + newName, child.getName()); @@ -432,7 +432,7 @@ public abstract class VcsVFSListener implements Disposable { // If a file is scheduled for deletion, and at the same time for copying or addition, don't delete it. // It happens during Overwrite command or undo of overwrite. - private void dontDeleteAddedCopiedOrMovedFiles() { + private void doNotDeleteAddedCopiedOrMovedFiles() { Collection copiedAddedMoved = new ArrayList(); for (VirtualFile file : myCopyFromMap.keySet()) { copiedAddedMoved.add(file.getPath()); @@ -444,14 +444,14 @@ public abstract class VcsVFSListener implements Disposable { copiedAddedMoved.add(movedFileInfo.myNewPath); } - for (Iterator iter = myDeletedFiles.iterator(); iter.hasNext(); ) { - if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iter.next().getPath()))) { - iter.remove(); + for (Iterator iterator = myDeletedFiles.iterator(); iterator.hasNext(); ) { + if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iterator.next().getPath()))) { + iterator.remove(); } } - for (Iterator iter = myDeletedWithoutConfirmFiles.iterator(); iter.hasNext(); ) { - if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iter.next().getPath()))) { - iter.remove(); + for (Iterator iterator = myDeletedWithoutConfirmFiles.iterator(); iterator.hasNext(); ) { + if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iterator.next().getPath()))) { + iterator.remove(); } } } @@ -471,7 +471,7 @@ public abstract class VcsVFSListener implements Disposable { finally { myCommandLevel--; } - dontDeleteAddedCopiedOrMovedFiles(); + doNotDeleteAddedCopiedOrMovedFiles(); checkMovedAddedSourceBack(); if (!myAddedFiles.isEmpty()) { executeAdd(); diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java index c539a0a8a707..c98d422ec81f 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/VcsUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -36,9 +36,7 @@ import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ContentRevision; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.openapi.wm.StatusBar; import org.jetbrains.annotations.NotNull; @@ -426,24 +424,32 @@ public class VcsUtil { * * @throws IllegalArgumentException if dir isn't a directory. */ - public static void collectFiles(VirtualFile dir, List files, boolean recursive, boolean addDirectories) { + public static void collectFiles(final VirtualFile dir, + final List files, + final boolean recursive, + final boolean addDirectories) { if (!dir.isDirectory()) { throw new IllegalArgumentException(VcsBundle.message("exception.text.file.should.be.directory", dir.getPresentableUrl())); } - FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - VirtualFile[] children = dir.getChildren(); - for (VirtualFile child : children) { - if (!child.isDirectory() && (fileTypeManager == null || child.getFileType() != FileTypes.UNKNOWN)) { - files.add(child); - } - else if (recursive && child.isDirectory()) { - if (addDirectories) { - files.add(child); + final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); + VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (file.isDirectory()) { + if (addDirectories) { + files.add(file); + } + if (!recursive && file != dir) { + return false; + } } - collectFiles(child, files, recursive, false); + else if (fileTypeManager == null || file.getFileType() != FileTypes.UNKNOWN) { + files.add(file); + } + return true; } - } + }); } public static boolean runVcsProcessWithProgress(final VcsRunnable runnable, String progressTitle, boolean canBeCanceled, Project project) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/generator/SpellCheckerDictionaryGenerator.java b/plugins/spellchecker/src/com/intellij/spellchecker/generator/SpellCheckerDictionaryGenerator.java index 2033868ede4c..df3f8b65ffa4 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/generator/SpellCheckerDictionaryGenerator.java +++ b/plugins/spellchecker/src/com/intellij/spellchecker/generator/SpellCheckerDictionaryGenerator.java @@ -1,14 +1,32 @@ +/* + * 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.spellchecker.generator; import com.intellij.lang.Language; import com.intellij.lang.LanguageNamesValidation; +import com.intellij.lang.refactoring.NamesValidator; 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.util.TextRange; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; @@ -63,10 +81,10 @@ public abstract class SpellCheckerDictionaryGenerator { generate(myDefaultDictName, progressIndicator); // other gem-related dictionaries in alphabet order - final List dictsList = new ArrayList(myDict2FolderMap.keySet()); - Collections.sort(dictsList); + final List dictionaries = new ArrayList(myDict2FolderMap.keySet()); + Collections.sort(dictionaries); - for (String dict : dictsList) { + for (String dict : dictionaries) { if (myDefaultDictName.equals(dict)) { continue; } @@ -92,7 +110,7 @@ public abstract class SpellCheckerDictionaryGenerator { } if (seenNames.isEmpty()) { - System.out.println(" No new words was found."); + LOG.info(" No new words was found."); return; } @@ -122,21 +140,22 @@ public abstract class SpellCheckerDictionaryGenerator { } } - protected void processFolder(final HashSet seenNames, final PsiManager manager, - final VirtualFile folder) { - if (myExcludedFolders.contains(folder)) { - return; - } - for (VirtualFile virtualFile : folder.getChildren()) { - if (virtualFile.isDirectory()) { - processFolder(seenNames, manager, virtualFile); - continue; + protected void processFolder(final HashSet seenNames, final PsiManager manager, final VirtualFile folder) { + VfsUtilCore.visitChildrenRecursively(folder, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (myExcludedFolders.contains(file)) { + return false; + } + if (!file.isDirectory()) { + final PsiFile psiFile = manager.findFile(file); + if (psiFile != null) { + processFile(psiFile, seenNames); + } + } + return true; } - final PsiFile file = manager.findFile(virtualFile); - if (file != null) { - processFile(file, seenNames); - } - } + }); } protected abstract void processFile(PsiFile file, HashSet seenNames); @@ -185,10 +204,11 @@ public abstract class SpellCheckerDictionaryGenerator { return; } - boolean keyword = LanguageNamesValidation.INSTANCE.forLanguage(language).isKeyword(word, myProject); - if (keyword){ + final NamesValidator namesValidator = LanguageNamesValidation.INSTANCE.forLanguage(language); + if (namesValidator != null && namesValidator.isKeyword(word, myProject)) { return; } + globalSeenNames.add(lowerWord); if (mySpellCheckerManager.hasProblem(lowerWord)){ seenNames.add(lowerWord);