Refactoring: common logic extracted and moved to a util class

This commit is contained in:
Andrey Breslav
2013-10-09 20:56:21 +04:00
parent d4a89d04d7
commit 9e0e67d19d
6 changed files with 86 additions and 63 deletions
@@ -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));
}
@@ -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);
}
@@ -128,9 +128,14 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
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) {
@@ -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<File> 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;
@@ -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 {
@@ -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"};