Use VFS visitor in place of recursion (platform)

This commit is contained in:
Roman Shevchenko
2012-08-24 22:19:12 +04:00
parent 30faf5f1ec
commit 451fba2c78
19 changed files with 466 additions and 421 deletions
@@ -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;
}
}
});
}
}
@@ -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<PsiFile> getAllCachedFiles() {
List<PsiFile> files = new ArrayList<PsiFile>();
@@ -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<VirtualFile> 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");
}
}
}
}
@@ -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<VirtualFile> 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<VirtualFile> 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) {
@@ -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<VirtualFile> 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<VirtualFile> 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);
}
});
}
}
@@ -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 {
@@ -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<Pattern, Set<Pattern>> loadPatterns(@NonNls String propertyKey) {
@@ -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<VirtualFile> readOnlyFiles = new ArrayList<VirtualFile>();
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<VirtualFile> 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) {
@@ -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<VirtualFile> files = new THashSet<VirtualFile>();
THashSet<VirtualFile> directories = new THashSet<VirtualFile>();
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);
}
});
}
}
@@ -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 <K, V> UpdatableIndex<K, V, FileContent> createIndex(@NotNull final ID<K, V> indexId, @NotNull final FileBasedIndexExtension<K, V> extension, @NotNull final MemoryIndexStorage<K, V> storage) throws StorageException, IOException {
private <K, V> UpdatableIndex<K, V, FileContent> createIndex(@NotNull final ID<K, V> indexId,
@NotNull final FileBasedIndexExtension<K, V> extension,
@NotNull final MemoryIndexStorage<K, V> storage)
throws StorageException, IOException {
final MapReduceIndex<K, V, FileContent> index;
if (extension instanceof CustomImplementationFileBasedIndexExtension) {
final UpdatableIndex<K, V, FileContent> custom = ((CustomImplementationFileBasedIndexExtension<K, V, FileContent>)extension).createIndexImplementation(indexId, this, storage);
assert custom != null : "Custom index implementation must not be null; index: " + indexId;
final UpdatableIndex<K, V, FileContent> custom =
((CustomImplementationFileBasedIndexExtension<K, V, FileContent>)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<VirtualFile> 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<ID<?, ?>> affectedIndices = new ArrayList<ID<?, ?>>(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<VirtualFile> 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<ID<?, ?>> affectedIndices = new ArrayList<ID<?, ?>>(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<ID<?, ?>> 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();
}
}
}
}
@@ -51,6 +51,7 @@ public class VfsUtil extends VfsUtilCore {
/**
* Copies all files matching the <code>filter</code> from <code>fromDir</code> to <code>toDir</code>.
* 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 <code>requestor</code> is <code>null</code>.
@@ -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);
}
@@ -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) {
@@ -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) {
@@ -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
@@ -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);
@@ -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<String> 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<DirectoryInfo> myDirectoryInfoStack = new Stack<DirectoryInfo>();
@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<String> 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<String> myPackages = new Stack<String>();
@@ -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<List<OrderEntry>> myEntries = new Stack<List<OrderEntry>>();
@@ -770,4 +776,4 @@ public class DirectoryIndexImpl extends DirectoryIndex {
return copy;
}
}
}
}
@@ -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<VirtualFile> 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
@@ -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<String> copiedAddedMoved = new ArrayList<String>();
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<FilePath> iter = myDeletedFiles.iterator(); iter.hasNext(); ) {
if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iter.next().getPath()))) {
iter.remove();
for (Iterator<FilePath> iterator = myDeletedFiles.iterator(); iterator.hasNext(); ) {
if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iterator.next().getPath()))) {
iterator.remove();
}
}
for (Iterator<FilePath> iter = myDeletedWithoutConfirmFiles.iterator(); iter.hasNext(); ) {
if (copiedAddedMoved.contains(FileUtil.toSystemIndependentName(iter.next().getPath()))) {
iter.remove();
for (Iterator<FilePath> 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();
@@ -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 <code>dir</code> 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<VirtualFile> 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)
@@ -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<String> dictsList = new ArrayList<String>(myDict2FolderMap.keySet());
Collections.sort(dictsList);
final List<String> dictionaries = new ArrayList<String>(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<String> 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<String> 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<String> 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);