<kotlinc> ant task now supports <src> element and multiple source directories

This commit is contained in:
Andrey Breslav
2013-10-08 15:03:32 +04:00
parent ed006a66c5
commit bf49bc0220
10 changed files with 103 additions and 19 deletions
@@ -20,9 +20,11 @@ import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.jetbrains.jet.buildtools.core.BytecodeCompiler;
import org.jetbrains.jet.buildtools.core.Util;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
import java.io.File;
import java.util.Arrays;
import static org.jetbrains.jet.buildtools.core.Util.getPath;
@@ -40,7 +42,7 @@ public class BytecodeCompilerTask extends Task {
private File output;
private File jar;
private File stdlib;
private File src;
private Path src;
private File module;
private Path compileClasspath;
private boolean includeRuntime = true;
@@ -57,10 +59,17 @@ public class BytecodeCompilerTask extends Task {
this.stdlib = stdlib;
}
public void setSrc(File src) {
public void setSrc(Path src) {
this.src = src;
}
public Path createSrc() {
if (src == null) {
src = new Path(getProject());
}
return src.createPath();
}
public void setModule(File module) {
this.module = module;
}
@@ -121,10 +130,10 @@ public class BytecodeCompilerTask extends Task {
throw new CompileEnvironmentException("\"output\" or \"jar\" should be specified");
}
String source = getPath(this.src);
String[] source = Util.getPaths(this.src.list());
String destination = getPath(this.output != null ? this.output : this.jar);
log(String.format("Compiling [%s] => [%s]", source, destination));
log(String.format("Compiling [%s] => [%s]", Arrays.toString(source), destination));
if (this.output != null) {
compiler.sourcesToDir(source, destination, stdlibPath, classpath);
@@ -16,13 +16,20 @@
package org.jetbrains.jet.buildtools.core;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import jet.modules.Module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.cli.common.CLIConfigurationKeys;
import org.jetbrains.jet.cli.common.CompilerPlugin;
import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream;
import org.jetbrains.jet.cli.jvm.compiler.*;
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.utils.KotlinPaths;
@@ -42,6 +49,7 @@ import static org.jetbrains.jet.cli.jvm.JVMConfigurationKeys.CLASSPATH_KEY;
* Wrapper class for Kotlin bytecode compiler.
*/
public class BytecodeCompiler {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private List<CompilerPlugin> compilerPlugins = new ArrayList<CompilerPlugin>();
@@ -87,6 +95,12 @@ public class BytecodeCompiler {
}
configuration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, Arrays.asList(sourceRoots));
for (String sourceRoot : sourceRoots) {
File file = new File(sourceRoot);
if (!file.isFile() || !"kt".equals(FileUtilRt.getExtension(file.getName()))) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, file);
}
}
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollectorPlainTextToStream.PLAIN_TEXT_TO_SYSTEM_ERR);
// lets register any compiler plugins
@@ -101,24 +115,37 @@ public class BytecodeCompiler {
* @param exceptionThrown whether compilation failed due to exception thrown
* @return compilation error message
*/
private static String errorMessage(@NotNull String source, boolean exceptionThrown) {
return String.format("[%s] compilation failed" +
(exceptionThrown ? "" : ", see \"ERROR:\" messages above for more details."),
new File(source).getAbsolutePath());
private static String errorMessage(@NotNull String[] source, boolean exceptionThrown) {
return String.format("Compilation of the following source roots failed:" + LINE_SEPARATOR +
getAbsolutePaths(source) +
(exceptionThrown ? "" : LINE_SEPARATOR + "see \"ERROR:\" messages above for more details."));
}
private static String getAbsolutePaths(String[] source) {
return StringUtil.join(
source,
new Function<String, String>() {
@Override
public String fun(String s) {
return " * " + new File(s).getAbsolutePath();
}
},
LINE_SEPARATOR
);
}
/**
* {@code CompileEnvironment#compileBunchOfSources} wrapper.
*
* @param src compilation source (directory or file)
* @param src compilation source (directories or files)
* @param output compilation destination directory
* @param stdlib "kotlin-runtime.jar" path
* @param classpath compilation classpath, can be <code>null</code> or empty
*/
public void sourcesToDir(@NotNull String src, @NotNull String output, @Nullable String stdlib, @Nullable String[] classpath) {
public void sourcesToDir(@NotNull String[] src, @NotNull String output, @Nullable String stdlib, @Nullable String[] classpath) {
try {
JetCoreEnvironment environment = env(stdlib, classpath, new String[]{src});
JetCoreEnvironment environment = env(stdlib, classpath, src);
boolean success = KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment, null, new File(output), true);
if (!success) {
@@ -140,13 +167,13 @@ public class BytecodeCompiler {
* @param stdlib "kotlin-runtime.jar" path
* @param classpath compilation classpath, can be <code>null</code> or empty
*/
public void sourcesToJar(@NotNull String src,
public void sourcesToJar(@NotNull String[] src,
@NotNull String jar,
boolean includeRuntime,
@Nullable String stdlib,
@Nullable String[] classpath) {
try {
JetCoreEnvironment environment = env(stdlib, classpath, new String[]{src});
JetCoreEnvironment environment = env(stdlib, classpath, src);
boolean success = KotlinToJVMBytecodeCompiler.compileBunchOfSources(environment, new File(jar), null, includeRuntime);
if (!success) {
@@ -184,11 +211,11 @@ public class BytecodeCompiler {
File directory = new File(module).getParentFile();
boolean success = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules, directory, new File(jar), null, includeRuntime);
if (!success) {
throw new CompileEnvironmentException(errorMessage(module, false));
throw new CompileEnvironmentException(errorMessage(new String[]{module}, false));
}
}
catch (Exception e) {
throw new CompileEnvironmentException(errorMessage(module, true), e);
throw new CompileEnvironmentException(errorMessage(new String[]{module}, true), e);
}
}
@@ -43,4 +43,13 @@ public final class Util {
throw new RuntimeException(String.format("Failed to resolve canonical file of [%s]: %s", f, e), e);
}
}
public static String[] getPaths(String[] paths) {
String[] result = new String[paths.length];
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
result[i] = getPath(new File(path));
}
return result;
}
}
@@ -23,8 +23,7 @@ import java.io.File;
import static junit.framework.Assert.assertEquals;
public class AntTaskTest extends KotlinIntegrationTestBase {
@Test
public void antTaskJvm() throws Exception {
private void doAntTest() throws Exception {
String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
String runtime = new File("dist/kotlinc/lib/kotlin-runtime.jar").getAbsolutePath();
@@ -32,6 +31,16 @@ public class AntTaskTest extends KotlinIntegrationTestBase {
runJava("hello.run", "-cp", jar + File.pathSeparator + runtime, "Hello.HelloPackage");
}
@Test
public void antTaskJvm() throws Exception {
doAntTest();
}
@Test
public void antTaskJvmManyRoots() throws Exception {
doAntTest();
}
@Override
protected String normalizeOutput(String content) {
return super.normalizeOutput(content)
@@ -1,7 +1,7 @@
OUT Buildfile: build.xml
OUT
OUT build:
OUT [kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar]
OUT [kotlinc] Compiling [[[TestData]/hello.kt]] => [[Temp]/hello.jar]
OUT
OUT BUILD SUCCESSFUL
OUT Total time: [time]
@@ -0,0 +1,8 @@
OUT Buildfile: build.xml
OUT
OUT build:
OUT [kotlinc] Compiling [[[TestData]/root1, [TestData]/root2]] => [[Temp]/hello.jar]
OUT
OUT BUILD SUCCESSFUL
OUT Total time: [time]
Return code: 0
@@ -0,0 +1,10 @@
<project name="Ant Task Test" default="build">
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
<target name="build">
<kotlinc output="${temp}/hello.jar">
<src path="${test.data}/root1"/>
<src path="${test.data}/root2"/>
</kotlinc>
</target>
</project>
@@ -0,0 +1,2 @@
OUT Hello, a!
Return code: 0
@@ -0,0 +1,7 @@
package Hello
fun main(args : Array<String>) {
for (s in arrayList("a"))
println("Hello, $s!")
foo()
}
@@ -0,0 +1,3 @@
package Hello
fun foo() {}