diff --git a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java index 2f54fecb550..0b30e52148e 100644 --- a/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java +++ b/build-tools/core/src/org/jetbrains/jet/buildtools/core/BytecodeCompiler.java @@ -206,7 +206,7 @@ public class BytecodeCompiler { } CompilerConfiguration configuration = createConfiguration(stdlib, classpath, sourcesRoots.toArray(new String[0])); File directory = new File(module).getParentFile(); - boolean success = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules, directory, new File(jar), null, includeRuntime); + boolean success = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules, directory, new File(jar), includeRuntime); if (!success) { throw new CompileEnvironmentException(errorMessage(new String[]{module}, false)); } diff --git a/compiler/cli/cli-common/src/org/jetbrains/jet/cli/common/messages/MessageCollector.java b/compiler/cli/cli-common/src/org/jetbrains/jet/cli/common/messages/MessageCollector.java index 14cbe06dd41..7044d8928a5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/jet/cli/common/messages/MessageCollector.java +++ b/compiler/cli/cli-common/src/org/jetbrains/jet/cli/common/messages/MessageCollector.java @@ -20,6 +20,15 @@ import org.jetbrains.annotations.NotNull; public interface MessageCollector { + MessageCollector NONE = new MessageCollector() { + @Override + public void report( + @NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location + ) { + // Do nothing + } + }; + void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location); } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java index 5e1f1e134fb..25abb4862f1 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java @@ -128,9 +128,14 @@ public class K2JVMCompiler extends CLICompiler { MessageCollector sanitizedCollector = new FilteringMessageCollector(messageCollector, in(CompilerMessageSeverity.VERBOSE)); ModuleChunk modules = CompileEnvironmentUtil.loadModuleDescriptions(paths, arguments.module, sanitizedCollector); + if (outputDir != null) { + messageCollector.report(CompilerMessageSeverity.WARNING, "The '-output' option is ignored because '-module' is specified", + CompilerMessageLocation.NO_LOCATION); + } + File directory = new File(arguments.module).getAbsoluteFile().getParentFile(); KotlinToJVMBytecodeCompiler.compileModules(configuration, modules, - directory, jar, outputDir, + directory, jar, arguments.includeRuntime); } else if (arguments.script) { diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java index 68d0c4339b2..2fa4f1c6dae 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -27,8 +27,7 @@ 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.messages.MessageCollector; -import org.jetbrains.jet.cli.common.messages.MessageRenderer; +import org.jetbrains.jet.cli.common.messages.*; import org.jetbrains.jet.cli.common.modules.ModuleDescription; import org.jetbrains.jet.cli.common.modules.ModuleXmlParser; import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys; @@ -39,13 +38,11 @@ import org.jetbrains.jet.config.CommonConfigurationKeys; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.utils.ExceptionUtils; import org.jetbrains.jet.utils.KotlinPaths; import org.jetbrains.jet.utils.PathUtil; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.OutputStream; +import java.io.*; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -181,7 +178,7 @@ public class CompileEnvironmentUtil { } // TODO: includeRuntime should be not a flag but a path to runtime - public static void writeToJar(ClassFileFactory factory, OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) { + private static void doWriteToJar(ClassFileFactory factory, OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) { try { Manifest manifest = new Manifest(); Attributes mainAttributes = manifest.getMainAttributes(); @@ -205,6 +202,24 @@ public class CompileEnvironmentUtil { } } + public static void writeToJar(File jarPath, boolean jarRuntime, FqName mainClass, ClassFileFactory moduleFactory) { + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(jarPath); + doWriteToJar(moduleFactory, outputStream, mainClass, jarRuntime); + outputStream.close(); + } + catch (FileNotFoundException e) { + throw new CompileEnvironmentException("Invalid jar path " + jarPath, e); + } + catch (IOException e) { + throw ExceptionUtils.rethrow(e); + } + finally { + ExceptionUtils.closeQuietly(outputStream); + } + } + private static void writeRuntimeToJar(final JarOutputStream stream) throws IOException { File runtimeJarPath = getRuntimeJarPath(); if (runtimeJarPath != null) { @@ -255,6 +270,37 @@ public class CompileEnvironmentUtil { return moduleScriptText; } + static void writeOutputToDirOrJar( + @Nullable File jar, + @Nullable File outputDir, + boolean includeRuntime, + @Nullable FqName mainClass, + @NotNull ClassFileFactory factory, + @NotNull MessageCollector messageCollector + ) { + if (jar != null) { + writeToJar(jar, includeRuntime, mainClass, factory); + } + else if (outputDir != null) { + reportOutputs(factory, messageCollector); + writeToOutputDirectory(factory, outputDir); + } + else { + throw new CompileEnvironmentException("Output directory or jar file is not specified - no files will be saved to the disk"); + } + } + + private static void reportOutputs(ClassFileFactory factory, MessageCollector messageCollector) { + for (String outputFile : factory.files()) { + List sourceFiles = factory.getSourceFiles(outputFile); + messageCollector.report( + CompilerMessageSeverity.OUTPUT, + OutputMessageUtil.formatOutputMessage(sourceFiles, new File(outputFile)), + CompilerMessageLocation.NO_LOCATION); + + } + } + private static class DescriptionToModuleAdapter implements Module { private final ModuleDescription description; diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index d29e5693908..9e739eaccc4 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -53,9 +53,6 @@ import org.jetbrains.jet.utils.KotlinPaths; import org.jetbrains.jet.utils.PathUtil; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; @@ -115,40 +112,30 @@ public class KotlinToJVMBytecodeCompiler { } } + private static void writeOutput( + CompilerConfiguration configuration, + ClassFileFactory moduleFactory, File outputDir, File jarPath, + boolean jarRuntime, + FqName mainClass + ) { + MessageCollector messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE); + CompileEnvironmentUtil.writeOutputToDirOrJar(jarPath, outputDir, jarRuntime, mainClass, moduleFactory, messageCollector); + } + public static boolean compileModules( CompilerConfiguration configuration, @NotNull ModuleChunk modules, @NotNull File directory, @Nullable File jarPath, - @Nullable File outputDir, - boolean jarRuntime) { - + boolean jarRuntime + ) { for (Module moduleBuilder : modules.getModules()) { ClassFileFactory moduleFactory = compileModule(configuration, moduleBuilder, directory); if (moduleFactory == null) { return false; } - if (outputDir != null) { - CompileEnvironmentUtil.writeToOutputDirectory(moduleFactory, outputDir); - } - else { - File path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar"); - FileOutputStream outputStream = null; - try { - outputStream = new FileOutputStream(path); - CompileEnvironmentUtil.writeToJar(moduleFactory, outputStream, null, jarRuntime); - outputStream.close(); - } - catch (FileNotFoundException e) { - throw new CompileEnvironmentException("Invalid jar path " + path, e); - } - catch (IOException e) { - throw ExceptionUtils.rethrow(e); - } - finally { - ExceptionUtils.closeQuietly(outputStream); - } - } + File outputDir = new File(moduleBuilder.getOutputDirectory()); + writeOutput(configuration, moduleFactory, outputDir, jarPath, jarRuntime, null); } return true; } @@ -184,30 +171,7 @@ public class KotlinToJVMBytecodeCompiler { } try { - ClassFileFactory factory = generationState.getFactory(); - if (jar != null) { - FileOutputStream os = null; - try { - os = new FileOutputStream(jar); - CompileEnvironmentUtil.writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime); - os.close(); - } - catch (FileNotFoundException e) { - throw new CompileEnvironmentException("Invalid jar path " + jar, e); - } - catch (IOException e) { - throw ExceptionUtils.rethrow(e); - } - finally { - ExceptionUtils.closeQuietly(os); - } - } - else if (outputDir != null) { - CompileEnvironmentUtil.writeToOutputDirectory(factory, outputDir); - } - else { - throw new CompileEnvironmentException("Output directory or jar file is not specified - no files will be saved to the disk"); - } + writeOutput(environment.getConfiguration(), generationState.getFactory(), outputDir, jar, includeRuntime, mainClass); return true; } finally { diff --git a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java index 3174bd34797..dc69dfad1cd 100644 --- a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java +++ b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinCompilerRunner.java @@ -50,7 +50,7 @@ public class KotlinCompilerRunner { OutputItemsCollector collector, boolean runOutOfProcess ) { - String[] arguments = createArgumentsForJvmCompiler(environment.getOutput(), moduleFile); + String[] arguments = createArgumentsForJvmCompiler(moduleFile); if (runOutOfProcess) { runOutOfProcess(K2JVM_COMPILER, arguments, messageCollector, collector, environment); @@ -106,10 +106,9 @@ public class KotlinCompilerRunner { } } - private static String[] createArgumentsForJvmCompiler(File outputDir, File moduleFile) { + private static String[] createArgumentsForJvmCompiler(File moduleFile) { return new String[]{ "-module", moduleFile.getAbsolutePath(), - "-output", outputDir.getPath(), "-tags", "-verbose", "-version", "-notNullAssertions", "-notNullParamAssertions", "-noStdlib", "-noJdkAnnotations", "-noJdk"};