Simplify code in module script/xml generation

Pass classpath and annotation roots explicitly instead of wrapped in a callback
This commit is contained in:
Alexander Udalov
2015-01-22 17:16:06 +03:00
parent fa2116040e
commit 3ea59117ac
8 changed files with 97 additions and 134 deletions
@@ -25,21 +25,13 @@ public interface KotlinModuleDescriptionBuilder {
KotlinModuleDescriptionBuilder addModule(
String moduleName,
String outputDir,
DependencyProvider dependencyProvider,
List<File> sourceFiles,
List<File> javaSourceRoots,
Collection<File> classpathRoots,
List<File> annotationRoots,
boolean tests,
Set<File> directoriesToFilterOut
);
CharSequence asText();
interface DependencyProvider {
void processClassPath(DependencyProcessor processor);
}
interface DependencyProcessor {
void processClassPathSection(String sectionDescription, Collection<File> files);
void processAnnotationRoots(List<File> files);
}
}
@@ -54,11 +54,12 @@ public class KotlinModuleScriptBuilderFactory implements KotlinModuleDescription
public KotlinModuleDescriptionBuilder addModule(
String moduleName,
String outputDir,
DependencyProvider dependencyProvider,
List<File> sourceFiles,
List<File> javaSourceRoots,
Collection<File> classpathRoots,
List<File> annotationRoots,
boolean tests,
final Set<File> directoriesToFilterOut
Set<File> directoriesToFilterOut
) {
assert !done : "Already done";
@@ -75,41 +76,42 @@ public class KotlinModuleScriptBuilderFactory implements KotlinModuleDescription
script.append(" sources += \"" + toSystemIndependentName(sourceFile.getPath()) + "\"\n");
}
DependencyProcessor processor = new DependencyProcessor() {
@Override
public void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection<File> files) {
script.append(" // " + sectionDescription + "\n");
for (File file : files) {
if (directoriesToFilterOut.contains(file)) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
script.append(" // Output directory, commented out\n");
script.append(" // ");
}
script.append(" classpath += \"" + toSystemIndependentName(file.getPath()) + "\"\n");
}
}
@Override
public void processAnnotationRoots(@NotNull List<File> files) {
script.append(" // External annotations\n");
for (File file : files) {
script.append(" annotationsPath += \"").append(toSystemIndependentName(file.getPath())).append("\"\n");
}
}
};
if (!javaSourceRoots.isEmpty()) {
processor.processClassPathSection("Java source roots", javaSourceRoots);
processClassPathSection("Java source roots", javaSourceRoots, directoriesToFilterOut);
}
dependencyProvider.processClassPath(processor);
processClassPathSection("Classpath", classpathRoots, directoriesToFilterOut);
processAnnotationRoots(annotationRoots);
script.append(" }\n");
return this;
}
private void processClassPathSection(
@NotNull String sectionDescription,
@NotNull Collection<File> files,
@NotNull Set<File> directoriesToFilterOut
) {
script.append(" // " + sectionDescription + "\n");
for (File file : files) {
if (directoriesToFilterOut.contains(file)) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
script.append(" // Output directory, commented out\n");
script.append(" // ");
}
script.append(" classpath += \"" + toSystemIndependentName(file.getPath()) + "\"\n");
}
}
private void processAnnotationRoots(@NotNull List<File> files) {
script.append(" // External annotations\n");
for (File file : files) {
script.append(" annotationsPath += \"").append(toSystemIndependentName(file.getPath())).append("\"\n");
}
}
@Override
public CharSequence asText() {
if (!done) {
@@ -120,5 +122,4 @@ public class KotlinModuleScriptBuilderFactory implements KotlinModuleDescription
return script;
}
}
}
@@ -58,11 +58,12 @@ public class KotlinModuleXmlBuilderFactory implements KotlinModuleDescriptionBui
public KotlinModuleDescriptionBuilder addModule(
String moduleName,
String outputDir,
DependencyProvider dependencyProvider,
List<File> sourceFiles,
List<File> javaSourceRoots,
Collection<File> classpathRoots,
List<File> annotationRoots,
boolean tests,
final Set<File> directoriesToFilterOut
Set<File> directoriesToFilterOut
) {
assert !done : "Already done";
@@ -83,49 +84,50 @@ public class KotlinModuleXmlBuilderFactory implements KotlinModuleDescriptionBui
p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>");
}
DependencyProcessor processor = new DependencyProcessor() {
@Override
public void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection<File> files) {
p.println("<!-- ", sectionDescription, " -->");
for (File file : files) {
boolean isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.ENABLED;
if (isOutput) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
p.println("<!-- Output directory, commented out -->");
p.println("<!-- ");
p.pushIndent();
}
p.println("<", CLASSPATH, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
if (isOutput) {
p.popIndent();
p.println("-->");
}
}
}
@Override
public void processAnnotationRoots(@NotNull List<File> files) {
p.println("<!-- External annotations -->");
for (File file : files) {
p.println("<", EXTERNAL_ANNOTATIONS, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
}
}
};
if (!javaSourceRoots.isEmpty()) {
processor.processClassPathSection("Java source roots", javaSourceRoots);
processClassPathSection("Java source roots", javaSourceRoots, directoriesToFilterOut);
}
dependencyProvider.processClassPath(processor);
processClassPathSection("Classpath", classpathRoots, directoriesToFilterOut);
processAnnotationRoots(annotationRoots);
closeTag(p, MODULE);
return this;
}
private void processClassPathSection(
@NotNull String sectionDescription,
@NotNull Collection<File> files,
@NotNull Set<File> directoriesToFilterOut
) {
p.println("<!-- ", sectionDescription, " -->");
for (File file : files) {
boolean isOutput = directoriesToFilterOut.contains(file) && !IncrementalCompilation.ENABLED;
if (isOutput) {
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
p.println("<!-- Output directory, commented out -->");
p.println("<!-- ");
p.pushIndent();
}
p.println("<", CLASSPATH, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
if (isOutput) {
p.popIndent();
p.println("-->");
}
}
}
private void processAnnotationRoots(@NotNull List<File> files) {
p.println("<!-- External annotations -->");
for (File file : files) {
p.println("<", EXTERNAL_ANNOTATIONS, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
}
}
@Override
public CharSequence asText() {
if (!done) {
+3 -3
View File
@@ -5,11 +5,11 @@
<sources path="s2"/>
<!-- Java source roots -->
<classpath path="java"/>
<!-- Classpath -->
<classpath path="cp1"/>
<classpath path="cp2"/>
<!-- External annotations -->
<externalAnnotations path="a1/f1"/>
<externalAnnotations path="a2"/>
<!-- s1 -->
<classpath path="cp1"/>
<classpath path="cp2"/>
</module>
</modules>
+4 -4
View File
@@ -3,14 +3,14 @@
<module name="name" outputDir="output">
<sources path="s1"/>
<sources path="s2"/>
<!-- External annotations -->
<externalAnnotations path="a1/f1"/>
<externalAnnotations path="a2"/>
<!-- s1 -->
<!-- Classpath -->
<!-- Output directory, commented out -->
<!--
<classpath path="cp1"/>
-->
<classpath path="cp2"/>
<!-- External annotations -->
<externalAnnotations path="a1/f1"/>
<externalAnnotations path="a2"/>
</module>
</modules>
+8 -8
View File
@@ -3,28 +3,28 @@
<module name="name" outputDir="output">
<sources path="s1"/>
<sources path="s2"/>
<!-- External annotations -->
<externalAnnotations path="a1/f1"/>
<externalAnnotations path="a2"/>
<!-- s1 -->
<!-- Classpath -->
<!-- Output directory, commented out -->
<!--
<classpath path="cp1"/>
-->
<classpath path="cp2"/>
<!-- External annotations -->
<externalAnnotations path="a1/f1"/>
<externalAnnotations path="a2"/>
</module>
<!-- Module script for tests -->
<module name="name2" outputDir="output2">
<sources path="s12"/>
<sources path="s22"/>
<!-- External annotations -->
<externalAnnotations path="a12/f12"/>
<externalAnnotations path="a22"/>
<!-- s12 -->
<!-- Classpath -->
<!-- Output directory, commented out -->
<!--
<classpath path="cp12"/>
-->
<classpath path="cp22"/>
<!-- External annotations -->
<externalAnnotations path="a12/f12"/>
<externalAnnotations path="a22"/>
</module>
</modules>
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.modules;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.test.JetTestUtils;
import java.io.File;
@@ -29,15 +28,10 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
String actual = KotlinModuleXmlBuilderFactory.INSTANCE.create().addModule(
"name",
"output",
new KotlinModuleDescriptionBuilder.DependencyProvider() {
@Override
public void processClassPath(@NotNull KotlinModuleDescriptionBuilder.DependencyProcessor processor) {
processor.processAnnotationRoots(Arrays.asList(new File("a1/f1"), new File("a2")));
processor.processClassPathSection("s1", Arrays.asList(new File("cp1"), new File("cp2")));
}
},
Arrays.asList(new File("s1"), new File("s2")),
Collections.singletonList(new File("java")),
Arrays.asList(new File("cp1"), new File("cp2")),
Arrays.asList(new File("a1/f1"), new File("a2")),
false,
Collections.<File>emptySet()
).asText().toString();
@@ -48,15 +42,10 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
String actual = KotlinModuleXmlBuilderFactory.INSTANCE.create().addModule(
"name",
"output",
new KotlinModuleDescriptionBuilder.DependencyProvider() {
@Override
public void processClassPath(@NotNull KotlinModuleDescriptionBuilder.DependencyProcessor processor) {
processor.processAnnotationRoots(Arrays.asList(new File("a1/f1"), new File("a2")));
processor.processClassPathSection("s1", Arrays.asList(new File("cp1"), new File("cp2")));
}
},
Arrays.asList(new File("s1"), new File("s2")),
Collections.<File>emptyList(),
Arrays.asList(new File("cp1"), new File("cp2")),
Arrays.asList(new File("a1/f1"), new File("a2")),
false,
Collections.singleton(new File("cp1"))
).asText().toString();
@@ -68,30 +57,20 @@ public class KotlinModuleXmlGeneratorTest extends TestCase {
builder.addModule(
"name",
"output",
new KotlinModuleDescriptionBuilder.DependencyProvider() {
@Override
public void processClassPath(@NotNull KotlinModuleDescriptionBuilder.DependencyProcessor processor) {
processor.processAnnotationRoots(Arrays.asList(new File("a1/f1"), new File("a2")));
processor.processClassPathSection("s1", Arrays.asList(new File("cp1"), new File("cp2")));
}
},
Arrays.asList(new File("s1"), new File("s2")),
Collections.<File>emptyList(),
Arrays.asList(new File("cp1"), new File("cp2")),
Arrays.asList(new File("a1/f1"), new File("a2")),
false,
Collections.singleton(new File("cp1"))
);
builder.addModule(
"name2",
"output2",
new KotlinModuleDescriptionBuilder.DependencyProvider() {
@Override
public void processClassPath(@NotNull KotlinModuleDescriptionBuilder.DependencyProcessor processor) {
processor.processAnnotationRoots(Arrays.asList(new File("a12/f12"), new File("a22")));
processor.processClassPathSection("s12", Arrays.asList(new File("cp12"), new File("cp22")));
}
},
Arrays.asList(new File("s12"), new File("s22")),
Collections.<File>emptyList(),
Arrays.asList(new File("cp12"), new File("cp22")),
Arrays.asList(new File("a12/f12"), new File("a22")),
true,
Collections.singleton(new File("cp12"))
);
@@ -47,8 +47,6 @@ import java.io.IOException;
import java.util.*;
import static org.jetbrains.kotlin.jps.build.JpsUtils.getAllDependencies;
import static org.jetbrains.kotlin.modules.KotlinModuleDescriptionBuilder.DependencyProcessor;
import static org.jetbrains.kotlin.modules.KotlinModuleDescriptionBuilder.DependencyProvider;
public class KotlinBuilderModuleScriptGenerator {
@@ -89,9 +87,10 @@ public class KotlinBuilderModuleScriptGenerator {
builder.addModule(
target.getId(),
outputDir.getAbsolutePath(),
getKotlinModuleDependencies(target),
moduleSources,
findSourceRoots(context, target),
findClassPathRoots(target),
findAnnotationRoots(target),
target.isTests(),
// this excludes the output directories from the class path, to be removed for true incremental compilation
outputDirs
@@ -116,16 +115,6 @@ public class KotlinBuilderModuleScriptGenerator {
return outputDir;
}
private static DependencyProvider getKotlinModuleDependencies(final ModuleBuildTarget target) {
return new DependencyProvider() {
@Override
public void processClassPath(@NotNull DependencyProcessor processor) {
processor.processClassPathSection("Classpath", findClassPathRoots(target));
processor.processAnnotationRoots(findAnnotationRoots(target));
}
};
}
@NotNull
private static Collection<File> findClassPathRoots(@NotNull ModuleBuildTarget target) {
return getAllDependencies(target).classes().getRoots();