/*
* Copyright 2010-2015 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 org.jetbrains.kotlin.jps.build;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.incremental.ModuleBuildTarget;
import org.jetbrains.jps.model.java.JavaSourceRootType;
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
import org.jetbrains.jps.model.java.compiler.JpsCompilerExcludes;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class KotlinSourceFileCollector {
// For incremental compilation
@NotNull
public static MultiMap<ModuleBuildTarget, File> getDirtySourceFiles(DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder)
throws IOException
{
final MultiMap<ModuleBuildTarget, File> result = new MultiMap<ModuleBuildTarget, File>();
dirtyFilesHolder.processDirtyFiles(new FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>() {
@Override
public boolean apply(ModuleBuildTarget target, File file, JavaSourceRootDescriptor root) throws IOException {
//TODO this is a workaround for bug in JPS: the latter erroneously calls process with invalid parameters
if (!root.getTarget().equals(target)) {
return true;
}
if (isKotlinSourceFile(file)) {
result.putValue(target, file);
}
return true;
}
});
return result;
}
@NotNull
public static List<File> getRemovedKotlinFiles(
@NotNull DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
@NotNull ModuleBuildTarget target
) throws IOException {
return ContainerUtil.map(ContainerUtil.filter(dirtyFilesHolder.getRemovedFiles(target), new Condition<String>() {
@Override
public boolean value(String s) {
return FileUtilRt.extensionEquals(s, "kt");
}
}),
new Function<String, File>() {
@Override
public File fun(String s) {
return new File(s);
}
});
}
@NotNull
public static List<File> getAllKotlinSourceFiles(@NotNull ModuleBuildTarget target) {
final List<File> moduleExcludes = ContainerUtil.map(target.getModule().getExcludeRootsList().getUrls(), new Function<String, File>() {
@Override
public File fun(String url) {
return JpsPathUtil.urlToFile(url);
}
});
final JpsCompilerExcludes compilerExcludes =
JpsJavaExtensionService.getInstance().getOrCreateCompilerConfiguration(target.getModule().getProject()).getCompilerExcludes();
final List<File> result = ContainerUtil.newArrayList();
for (JpsModuleSourceRoot sourceRoot : getRelevantSourceRoots(target)) {
FileUtil.processFilesRecursively(
sourceRoot.getFile(),
new Processor<File>() {
@Override
public boolean process(File file) {
if (compilerExcludes.isExcluded(file)) return true;
if (file.isFile() && isKotlinSourceFile(file)) {
result.add(file);
}
return true;
}
},
new Processor<File>() {
@Override
public boolean process(final File dir) {
return ContainerUtil.find(moduleExcludes, new Condition<File>() {
@Override
public boolean value(File exclude) {
return FileUtil.filesEqual(exclude, dir);
}
}) == null;
}
});
}
return result;
}
private static Iterable<JpsModuleSourceRoot> getRelevantSourceRoots(ModuleBuildTarget target) {
JavaSourceRootType sourceRootType = target.isTests() ? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE;
//noinspection unchecked
return (Iterable) target.getModule().getSourceRoots(sourceRootType);
}
static boolean isKotlinSourceFile(File file) {
return FileUtilRt.extensionEquals(file.getName(), "kt");
}
private KotlinSourceFileCollector() {}
}