Use VFS visitor in place of recursion (compiler)

This commit is contained in:
Roman Shevchenko
2012-08-26 20:52:22 +04:00
parent 46c07adc08
commit 23e04118e7
7 changed files with 204 additions and 173 deletions
@@ -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.
@@ -66,7 +66,7 @@ public class ChunkBuild extends CompositeGenerator{
add(new ModuleChunkClasspath(chunk, genOptions, false, true), 1);
add(new ModuleChunkClasspath(chunk, genOptions, true, true), 1);
final ModuleChunkSourcepath moduleSources = new ModuleChunkSourcepath(project, chunk, genOptions);
final ModuleChunkSourcePath moduleSources = new ModuleChunkSourcePath(project, chunk, genOptions);
add(moduleSources, 1);
add(new CompileModuleChunkTarget(project, chunk, moduleSources.getSourceRoots(), moduleSources.getTestSourceRoots(), chunkBaseDir, genOptions), 1);
add(new CleanModule(chunk), 1);
@@ -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.
@@ -22,24 +22,25 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModuleFileIndex;
import com.intellij.openapi.roots.ModuleRootManager;
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.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eugene Zhuravlev
* Date: Nov 22, 2004
* @since Nov 22, 2004
*/
public class ModuleChunkSourcepath extends CompositeGenerator{
public class ModuleChunkSourcePath extends CompositeGenerator{
private final VirtualFile[] mySourceRoots;
private final VirtualFile[] myTestSourceRoots;
public ModuleChunkSourcepath(final Project project, ModuleChunk chunk, final GenerationOptions genOptions) {
final Path sourcepath = new Path(BuildProperties.getSourcepathProperty(chunk.getName()));
final Path testSourcepath = new Path(BuildProperties.getTestSourcepathProperty(chunk.getName()));
public ModuleChunkSourcePath(final Project project, ModuleChunk chunk, final GenerationOptions genOptions) {
final Path sourcePath = new Path(BuildProperties.getSourcepathProperty(chunk.getName()));
final Path testSourcePath = new Path(BuildProperties.getTestSourcepathProperty(chunk.getName()));
final PatternSet excludedFromCompilation = new PatternSet(BuildProperties.getExcludedFromCompilationProperty(chunk.getName()));
final String moduleChunkBasedirProperty = BuildProperties.getModuleChunkBasedirProperty(chunk);
final Module[] modules = chunk.getModules();
@@ -95,10 +96,10 @@ public class ModuleChunkSourcepath extends CompositeGenerator{
}
}
if (sourcesDirSet.getGeneratorCount() > 0) {
sourcepath.add(sourcesDirSet);
sourcePath.add(sourcesDirSet);
}
if (testSourcesDirSet.getGeneratorCount() > 0) {
testSourcepath.add(testSourcesDirSet);
testSourcePath.add(testSourcesDirSet);
}
}
@@ -108,17 +109,17 @@ public class ModuleChunkSourcepath extends CompositeGenerator{
}
}
mySourceRoots = VfsUtil.toVirtualFileArray(sourceRootFiles);
myTestSourceRoots = VfsUtil.toVirtualFileArray(testSourceRootFiles);
mySourceRoots = VfsUtilCore.toVirtualFileArray(sourceRootFiles);
myTestSourceRoots = VfsUtilCore.toVirtualFileArray(testSourceRootFiles);
if (excludedFromCompilation.getGeneratorCount() > 0) {
add(excludedFromCompilation, 1);
}
if (sourcepath.getGeneratorCount() > 0) {
add(sourcepath, 1);
if (sourcePath.getGeneratorCount() > 0) {
add(sourcePath, 1);
}
if (testSourcepath.getGeneratorCount() != 0) {
add(testSourcepath, 1);
if (testSourcePath.getGeneratorCount() != 0) {
add(testSourcePath, 1);
}
}
@@ -141,32 +142,41 @@ public class ModuleChunkSourcepath extends CompositeGenerator{
return contentRoot;
}
private void addExcludePatterns(Module module, final VirtualFile root, VirtualFile dir, CompositeGenerator generator, final boolean parentIncluded) {
if (FileTypeManager.getInstance().isFileIgnored(dir)) {
// ignored files are handled by global 'ignored' patternset
return;
}
final boolean isIncluded = ModuleRootManager.getInstance(module).getFileIndex().isInContent(dir);
if (isIncluded != parentIncluded) {
final String relativePath = VfsUtilCore.getRelativePath(dir, root, '/');
if (isIncluded) {
generator.add(new Include(relativePath + "/**"));
}
else {
if (!isExcludedByDefault(dir.getName())) {
generator.add(new Exclude(relativePath + "/**"));
private static void addExcludePatterns(Module module,
final VirtualFile root,
VirtualFile dir,
final CompositeGenerator generator,
final boolean parentIncluded) {
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile dir) {
if (!dir.isDirectory() || fileTypeManager.isFileIgnored(dir)) {
// ignored files are handled by global 'ignored' pattern set
return false;
}
final boolean isIncluded = moduleRootManager.getFileIndex().isInContent(dir);
if (isIncluded != parentIncluded) {
final String relativePath = VfsUtilCore.getRelativePath(dir, root, '/');
if (isIncluded) {
generator.add(new Include(relativePath + "/**"));
}
else {
if (!isExcludedByDefault(dir.getName())) {
generator.add(new Exclude(relativePath + "/**"));
}
}
}
return true;
}
}
final VirtualFile[] children = dir.getChildren();
for (VirtualFile child : children) {
if (child.isDirectory()) {
addExcludePatterns(module, root, child, generator, isIncluded);
}
}
});
}
private boolean isExcludedByDefault(String name) {
private static boolean isExcludedByDefault(String name) {
//noinspection HardCodedStringLiteral
return "CVS".equals(name) || "SCCS".equals(name) || ".DS_Store".equals(name);
}
@@ -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.
@@ -947,7 +947,7 @@ public class CompileDriver {
outputsToRefresh.add(generated.getSecond());
}
RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(outputsToRefresh));
RefreshQueue.getInstance().refresh(false, true, null, VfsUtilCore.toVirtualFileArray(outputsToRefresh));
if (progressIndicator.isCanceled()) {
return ExitStatus.CANCELLED;
}
@@ -1126,19 +1126,21 @@ public class CompileDriver {
}
private static void walkChildren(VirtualFile from, final CompileContext context) {
final VirtualFile[] files = from.getChildren();
if (files != null && files.length > 0) {
context.getProgressIndicator().checkCanceled();
context.getProgressIndicator().setText2(from.getPresentableUrl());
for (VirtualFile file : files) {
walkChildren(file, context);
VfsUtilCore.visitChildrenRecursively(from, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (file.isDirectory()) {
context.getProgressIndicator().checkCanceled();
context.getProgressIndicator().setText2(file.getPresentableUrl());
}
return true;
}
}
});
}
private static void createClasspathIndex(final VirtualFile file) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(VfsUtil.virtualToIoFile(file), "classpath.index")));
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(VfsUtilCore.virtualToIoFile(file), "classpath.index")));
try {
writeIndex(writer, file, file);
}
@@ -1152,12 +1154,19 @@ public class CompileDriver {
}
private static void writeIndex(final BufferedWriter writer, final VirtualFile root, final VirtualFile file) throws IOException {
writer.write(VfsUtilCore.getRelativePath(file, root, '/'));
writer.write('\n');
for (VirtualFile child : file.getChildren()) {
writeIndex(writer, root, child);
}
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
try {
writer.write(VfsUtilCore.getRelativePath(file, root, '/'));
writer.write('\n');
return true;
}
catch (IOException e) {
throw new VisitorException(e);
}
}
}, IOException.class);
}
private static void dropDependencyCache(final CompileContextEx context) {
@@ -1382,7 +1391,7 @@ public class CompileDriver {
filesToRecompile.addAll(allDependent);
}
if (filesToRecompile.size() > 0) {
sink.add(null, Collections.<TranslatingCompiler.OutputItem>emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile));
sink.add(null, Collections.<TranslatingCompiler.OutputItem>emptyList(), VfsUtilCore.toVirtualFileArray(filesToRecompile));
}
if (errorCount == 0) {
// perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers
@@ -1398,7 +1407,7 @@ public class CompileDriver {
final Collection<VirtualFile> deps = CacheUtils.findDependentFiles(context, Collections.<VirtualFile>emptySet(), null);
if (deps.size() > 0) {
TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.<TranslatingCompiler.OutputItem>emptyList(),
VfsUtil.toVirtualFileArray(deps));
VfsUtilCore.toVirtualFileArray(deps));
}
}
catch (IOException ignored) {
@@ -1957,7 +1966,7 @@ public class CompileDriver {
}
if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
compiler.compile(context, moduleChunk, VfsUtil.toVirtualFileArray(toCompile), sink);
compiler.compile(context, moduleChunk, VfsUtilCore.toVirtualFileArray(toCompile), sink);
}
}
finally {
@@ -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.
@@ -13,27 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author: Eugene Zhuravlev
* Date: Jan 20, 2003
* Time: 5:34:19 PM
*/
package com.intellij.compiler.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.ExportableUserDataHolderBase;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.util.io.FileUtil;
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.NotNull;
import java.util.*;
/**
* @author Eugene Zhuravlev
* @since Jan 20, 2003
*/
public class FileSetCompileScope extends ExportableUserDataHolderBase implements CompileScope {
private final Set<VirtualFile> myRootFiles = new HashSet<VirtualFile>();
private final Set<String> myDirectoryUrls = new HashSet<String>();
@@ -66,7 +64,6 @@ public class FileSetCompileScope extends ExportableUserDataHolderBase implements
@NotNull
public VirtualFile[] getFiles(final FileType fileType, boolean inSourceOnly) {
final List<VirtualFile> files = new ArrayList<VirtualFile>();
final FileTypeManager typeManager = FileTypeManager.getInstance();
for (Iterator<VirtualFile> it = myRootFiles.iterator(); it.hasNext();) {
VirtualFile file = it.next();
if (!file.isValid()) {
@@ -82,7 +79,7 @@ public class FileSetCompileScope extends ExportableUserDataHolderBase implements
}
}
}
return VfsUtil.toVirtualFileArray(files);
return VfsUtilCore.toVirtualFileArray(files);
}
public boolean belongs(String url) {
@@ -117,20 +114,15 @@ public class FileSetCompileScope extends ExportableUserDataHolderBase implements
myUrls = null;
}
private static void addRecursively(final Collection<VirtualFile> container, final VirtualFile fromDirectory, FileType fileType) {
VirtualFile[] children = fromDirectory.getChildren();
if (children.length > 0) {
final FileTypeManager typeManager = FileTypeManager.getInstance();
for (VirtualFile child : children) {
if (child.isDirectory()) {
addRecursively(container, child, fileType);
}
else {
if (fileType == null || fileType.equals(child.getFileType())) {
container.add(child);
}
private static void addRecursively(final Collection<VirtualFile> container, VirtualFile fromDirectory, final FileType fileType) {
VfsUtilCore.visitChildrenRecursively(fromDirectory, new VirtualFileVisitor(VirtualFileVisitor.SKIP_ROOT) {
@Override
public boolean visitFile(@NotNull VirtualFile child) {
if (!child.isDirectory() && (fileType == null || fileType.equals(child.getFileType()))) {
container.add(child);
}
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.
@@ -67,7 +67,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Eugene Zhuravlev
* Date: Jun 3, 2008
* @since Jun 3, 2008
*
* A source file is scheduled for recompilation if
* 1. its timestamp has changed
@@ -78,22 +78,22 @@ import java.util.concurrent.atomic.AtomicInteger;
* 1. corresponding source file has been scheduled for recompilation (see above)
* 2. corresponding source file has been deleted
*/
public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TranslatingCompilerFilesMonitor");
public static boolean ourDebugMode = false;
private static final boolean ourDebugMode = false;
private static final FileAttribute ourSourceFileAttribute = new FileAttribute("_make_source_file_info_", 3);
private static final FileAttribute ourOutputFileAttribute = new FileAttribute("_make_output_file_info_", 3);
private static final Key<Map<String, VirtualFile>> SOURCE_FILES_CACHE = Key.create("_source_url_to_vfile_cache_");
private final Object myDataLock = new Object();
private final TIntHashSet mySuspendedProjects = new TIntHashSet(); // projectId for allprojects that should not be monitored
private final TIntHashSet mySuspendedProjects = new TIntHashSet(); // projectId for all projects that should not be monitored
private final TIntObjectHashMap<TIntHashSet> mySourcesToRecompile = new TIntObjectHashMap<TIntHashSet>(); // ProjectId->set of source file paths
private PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> myOutputRootsStorage; // ProjectId->map[moduleId->Pair(outputDirId, testOutputDirId)]
// Map: projectId -> Map{output path -> [sourceUrl; classname]}
// Map: projectId -> Map{output path -> [sourceUrl; className]}
private final SLRUCache<Integer, Outputs> myOutputsToDelete = new SLRUCache<Integer, Outputs>(3, 3) {
@Override
public Outputs getIfCached(Integer key) {
@@ -1031,24 +1031,26 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
void execute(VirtualFile file);
}
private static void processRecursively(VirtualFile file, boolean dbOnly, final FileProcessor processor) {
if (file.getFileSystem() instanceof LocalFileSystem) {
if (file.isDirectory()) {
if (dbOnly) {
for (VirtualFile child : ((NewVirtualFile)file).iterInDbChildren()) {
processRecursively(child, true, processor);
}
}
else {
for (VirtualFile child : file.getChildren()) {
processRecursively(child, false, processor);
}
}
}
else {
processor.execute(file);
}
private static void processRecursively(VirtualFile file, final boolean dbOnly, final FileProcessor processor) {
if (!(file.getFileSystem() instanceof LocalFileSystem)) {
return;
}
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (!file.isDirectory()) {
processor.execute(file);
}
return true;
}
@Nullable
@Override
public Iterable<VirtualFile> getChildrenIterable(@NotNull VirtualFile file) {
return file.isDirectory() && dbOnly ? ((NewVirtualFile)file).iterInDbChildren() : null;
}
});
}
// made public for tests
@@ -1090,30 +1092,27 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
else {
final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
new Object() {
void processFile(VirtualFile file) {
VfsUtilCore.visitChildrenRecursively(srcRoot, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (fileTypeManager.isFileIgnored(file)) {
return;
return false;
}
final int fileId = getFileId(file);
if (fileId > 0 /*file is valid*/) {
if (file.isDirectory()) {
projRef.get();
for (VirtualFile child : file.getChildren()) {
processFile(child);
}
}
else {
if (!isMarkedForRecompilation(projectId, fileId)) {
final SourceFileInfo srcInfo = loadSourceInfo(file);
if (srcInfo != null) {
addSourceForRecompilation(projectId, file, srcInfo);
}
else if (!isMarkedForRecompilation(projectId, fileId)) {
final SourceFileInfo srcInfo = loadSourceInfo(file);
if (srcInfo != null) {
addSourceForRecompilation(projectId, file, srcInfo);
}
}
}
return true;
}
}.processFile(srcRoot);
});
}
}
}
@@ -1168,24 +1167,25 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
return oldOutputRoot != null && oldOutputRoot.intValue() > 0 && !Comparing.equal(oldOutputRoot, currentOutputRoot);
}
private void processOldOutputRoot(int projectId, VirtualFile outputRoot) {
private void processOldOutputRoot(final int projectId, VirtualFile outputRoot) {
// recursively mark all corresponding sources for recompilation
if (outputRoot.isDirectory()) {
for (VirtualFile child : outputRoot.getChildren()) {
processOldOutputRoot(projectId, child);
}
}
else {
// todo: possible optimization - process only those outputs that are not marked for deletion yet
final OutputFileInfo outputInfo = loadOutputInfo(outputRoot);
if (outputInfo != null) {
final String srcPath = outputInfo.getSourceFilePath();
final VirtualFile srcFile = srcPath != null? LocalFileSystem.getInstance().findFileByPath(srcPath) : null;
if (srcFile != null) {
loadInfoAndAddSourceForRecompilation(projectId, srcFile);
VfsUtilCore.visitChildrenRecursively(outputRoot, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (!file.isDirectory()) {
// todo: possible optimization - process only those outputs that are not marked for deletion yet
final OutputFileInfo outputInfo = loadOutputInfo(file);
if (outputInfo != null) {
final String srcPath = outputInfo.getSourceFilePath();
final VirtualFile srcFile = srcPath != null? LocalFileSystem.getInstance().findFileByPath(srcPath) : null;
if (srcFile != null) {
loadInfoAndAddSourceForRecompilation(projectId, srcFile);
}
}
}
return true;
}
}
});
}
public void scanSourcesForCompilableFiles(final Project project) {
@@ -1409,18 +1409,31 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
final Set<String> toMark;
if (eventFile.isDirectory()) {
toMark = new HashSet<String>();
new Object() {
void process(VirtualFile file, String filePath) {
if (file.isDirectory()) {
for (VirtualFile child : file.getChildren()) {
process(child, filePath + "/" + child.getName());
VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() {
private StringBuilder filePath = new StringBuilder(root);
@Override
public boolean visitFile(@NotNull VirtualFile child) {
if (child.isDirectory()) {
if (child != eventFile) {
filePath.append("/").append(child.getName());
}
}
else {
toMark.add(filePath);
String childPath = filePath.toString();
if (child != eventFile) childPath += "/" + child.getName();
toMark.add(childPath);
}
return true;
}
@Override
public void afterChildrenVisited(@NotNull VirtualFile file) {
if (file.isDirectory() && file != eventFile) {
filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length());
}
}
}.process(eventFile, root);
});
}
else {
toMark = Collections.singleton(root);
@@ -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.
@@ -13,12 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author: Eugene Zhuravlev
* Date: Jan 24, 2003
* Time: 4:25:47 PM
*/
package com.intellij.compiler.impl.javaCompiler;
import com.intellij.codeInsight.NullableNotNullManager;
@@ -54,6 +48,7 @@ import com.intellij.openapi.util.text.StringUtil;
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.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
@@ -76,6 +71,10 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @author Eugene Zhuravlev
* @since Jan 24, 2003
*/
public class BackendCompilerWrapper {
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper");
@@ -645,18 +644,15 @@ public class BackendCompilerWrapper {
}
else {
// seems to be a root for generated sources
new Object() {
void iterateContent(VirtualFile from) {
for (VirtualFile child : from.getChildren()) {
if (child.isDirectory()) {
iterateContent(child);
}
else {
contentIterator.processFile(child);
}
VfsUtilCore.visitChildrenRecursively(from, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (!file.isDirectory()) {
contentIterator.processFile(file);
}
return true;
}
}.iterateContent(from);
});
}
final CacheCorruptedException exc = exRef.get();
if (exc != null) {
@@ -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.
@@ -18,8 +18,11 @@ package com.intellij.packaging.impl.compiler;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
import com.intellij.packaging.elements.PackagingFileFilter;
import org.jetbrains.annotations.NotNull;
@@ -44,34 +47,42 @@ public abstract class IncrementalCompilerInstructionCreatorBase implements Incre
public void addDirectoryCopyInstructions(@NotNull VirtualFile directory, @Nullable PackagingFileFilter filter) {
ProjectFileIndex index = ProjectRootManager.getInstance(myContext.getCompileContext().getProject()).getFileIndex();
final boolean copyExcluded = index.isIgnored(directory);
collectInstructionsRecursively(directory, filter, index, FileTypeManager.getInstance(), copyExcluded);
collectInstructionsRecursively(directory, this, filter, index, FileTypeManager.getInstance(), copyExcluded);
}
private void collectInstructionsRecursively(VirtualFile directory,
PackagingFileFilter filter,
ProjectFileIndex index,
final FileTypeManager fileTypeManager,
boolean copyExcluded) {
final VirtualFile[] children = directory.getChildren();
if (children != null) {
for (VirtualFile child : children) {
private static final Key<IncrementalCompilerInstructionCreatorBase> INSTRUCTION_CREATOR = Key.create("pkg.compiler.instruction.creator");
private static void collectInstructionsRecursively(VirtualFile directory,
final IncrementalCompilerInstructionCreatorBase creator,
final PackagingFileFilter filter,
final ProjectFileIndex index,
final FileTypeManager fileTypeManager,
final boolean copyExcluded) {
VfsUtilCore.visitChildrenRecursively(directory, new VirtualFileVisitor(VirtualFileVisitor.SKIP_ROOT) {
{ set(INSTRUCTION_CREATOR, creator); }
@Override
public boolean visitFile(@NotNull VirtualFile child) {
if (copyExcluded) {
if (fileTypeManager.isFileIgnored(child)) continue;
if (fileTypeManager.isFileIgnored(child)) return false;
}
else {
if (index.isIgnored(child)) continue;
if (index.isIgnored(child)) return false;
}
if ((filter == null || filter.accept(child, myContext.getCompileContext()))) {
final IncrementalCompilerInstructionCreatorBase creator = get(INSTRUCTION_CREATOR);
if (filter == null || filter.accept(child, creator.myContext.getCompileContext())) {
if (!child.isDirectory()) {
addFileCopyInstruction(child, child.getName());
creator.addFileCopyInstruction(child, child.getName());
}
else {
subFolder(child.getName()).collectInstructionsRecursively(child, filter, index, fileTypeManager, copyExcluded);
set(INSTRUCTION_CREATOR, creator.subFolder(child.getName()));
}
}
return true;
}
}
});
}
@Override