#KT-1562 Fixed.

This commit is contained in:
Maxim Shafirov
2012-03-15 15:12:16 +04:00
parent 562893f83e
commit 43956b565a
3 changed files with 75 additions and 21 deletions
@@ -22,9 +22,9 @@ import org.jetbrains.jet.compiler.CompileEnvironment;
import org.jetbrains.jet.compiler.CompileEnvironmentException; import org.jetbrains.jet.compiler.CompileEnvironmentException;
import org.jetbrains.jet.compiler.CompilerPlugin; import org.jetbrains.jet.compiler.CompilerPlugin;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.io.File;
/** /**
@@ -133,7 +133,7 @@ public class BytecodeCompiler {
*/ */
public void moduleToJar ( @NotNull String module, @NotNull String jar, boolean includeRuntime, @Nullable String stdlib, @Nullable String[] classpath ) { public void moduleToJar ( @NotNull String module, @NotNull String jar, boolean includeRuntime, @Nullable String stdlib, @Nullable String[] classpath ) {
try { try {
boolean success = env( stdlib, classpath ).compileModuleScript( module, jar, null, includeRuntime ); boolean success = env( stdlib, classpath ).compileModuleScript( module, jar, null, includeRuntime);
if ( ! success ) { if ( ! success ) {
throw new CompileEnvironmentException( errorMessage( module, false )); throw new CompileEnvironmentException( errorMessage( module, false ));
} }
@@ -169,7 +169,7 @@ public class CompileEnvironment {
} }
public boolean compileModuleScript(String moduleScriptFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) { public boolean compileModuleScript(String moduleScriptFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
List<Module> modules = loadModuleScript(moduleScriptFile); List<Module> modules = copyEnvironment(false).loadModuleScript(moduleScriptFile);
if (modules == null) { if (modules == null) {
throw new CompileEnvironmentException("Module script " + moduleScriptFile + " compilation failed"); throw new CompileEnvironmentException("Module script " + moduleScriptFile + " compilation failed");
@@ -181,11 +181,7 @@ public class CompileEnvironment {
final String directory = new File(moduleScriptFile).getParent(); final String directory = new File(moduleScriptFile).getParent();
for (Module moduleBuilder : modules) { for (Module moduleBuilder : modules) {
CompileEnvironment compileEnvironment = new CompileEnvironment(myMessageRenderer, verbose); CompileEnvironment compileEnvironment = copyEnvironment(verbose);
compileEnvironment.setIgnoreErrors(ignoreErrors);
compileEnvironment.setErrorStream(myErrorStream);
// copy across any compiler plugins
compileEnvironment.getMyEnvironment().getCompilerPlugins().addAll(myEnvironment.getCompilerPlugins());
ClassFileFactory moduleFactory = compileEnvironment.compileModule(moduleBuilder, directory); ClassFileFactory moduleFactory = compileEnvironment.compileModule(moduleBuilder, directory);
if (moduleFactory == null) { if (moduleFactory == null) {
return false; return false;
@@ -205,6 +201,15 @@ public class CompileEnvironment {
return true; return true;
} }
private CompileEnvironment copyEnvironment(boolean verbose) {
CompileEnvironment compileEnvironment = new CompileEnvironment(myMessageRenderer, verbose);
compileEnvironment.setIgnoreErrors(ignoreErrors);
compileEnvironment.setErrorStream(myErrorStream);
// copy across any compiler plugins
compileEnvironment.getMyEnvironment().getCompilerPlugins().addAll(myEnvironment.getCompilerPlugins());
return compileEnvironment;
}
public List<Module> loadModuleScript(String moduleFile) { public List<Module> loadModuleScript(String moduleFile) {
CompileSession scriptCompileSession = newCompileSession(); CompileSession scriptCompileSession = newCompileSession();
scriptCompileSession.addSources(moduleFile); scriptCompileSession.addSources(moduleFile);
@@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin.compiler;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.compiler.impl.javaCompiler.ModuleChunk; import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
import com.intellij.compiler.impl.javaCompiler.OutputItemImpl;
import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.SimpleJavaParameters; import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.execution.process.*; import com.intellij.execution.process.*;
@@ -35,6 +36,7 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SimpleJavaSdkType; import com.intellij.openapi.projectRoots.SimpleJavaSdkType;
import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Chunk; import com.intellij.util.Chunk;
import com.intellij.util.SystemProperties; import com.intellij.util.SystemProperties;
@@ -99,11 +101,11 @@ public class JetCompiler implements TranslatingCompiler {
final Module module = compileContext.getModuleByFile(virtualFiles[0]); final Module module = compileContext.getModuleByFile(virtualFiles[0]);
doCompile(compileContext, moduleChunk, productionFiles, module, false); doCompile(compileContext, moduleChunk, productionFiles, module, outputSink, false);
doCompile(compileContext, moduleChunk, testFiles, module, true); doCompile(compileContext, moduleChunk, testFiles, module, outputSink, true);
} }
private void doCompile(CompileContext compileContext, Chunk<Module> moduleChunk, List<VirtualFile> files, Module module, boolean tests) { private void doCompile(CompileContext compileContext, Chunk<Module> moduleChunk, List<VirtualFile> files, Module module, OutputSink outputSink, boolean tests) {
if (files.isEmpty()) return; if (files.isEmpty()) return;
VirtualFile mainOutput = compileContext.getModuleOutputDirectory(module); VirtualFile mainOutput = compileContext.getModuleOutputDirectory(module);
@@ -137,13 +139,16 @@ public class JetCompiler implements TranslatingCompiler {
return; return;
} }
OutputItemsCollector collector = new OutputItemsCollector(outputDir.getPath());
if (RUN_OUT_OF_PROCESS) { if (RUN_OUT_OF_PROCESS) {
runOutOfProcess(compileContext, outputDir, kotlinHome, scriptFile); runOutOfProcess(compileContext, collector, outputDir, kotlinHome, scriptFile);
} }
else { else {
runInProcess(compileContext, outputDir, kotlinHome, scriptFile); runInProcess(compileContext, collector, outputDir, kotlinHome, scriptFile);
} }
outputSink.add(outputDir.getPath(), collector.getOutputs(), collector.getSources().toArray(VirtualFile.EMPTY_ARRAY));
// System.out.println("Generated module script:\n" + script.toString()); // System.out.println("Generated module script:\n" + script.toString());
// compileContext.addMessage(INFORMATION, "Generated module script:\n" + script.toString(), "file://" + path(mainOutput), 0, 1); // compileContext.addMessage(INFORMATION, "Generated module script:\n" + script.toString(), "file://" + path(mainOutput), 0, 1);
} }
@@ -231,13 +236,13 @@ public class JetCompiler implements TranslatingCompiler {
return answer; return answer;
} }
private void runInProcess(CompileContext compileContext, VirtualFile outputDir, File kotlinHome, File scriptFile) { private void runInProcess(CompileContext compileContext, OutputItemsCollector collector, VirtualFile outputDir, File kotlinHome, File scriptFile) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outputStream); PrintStream out = new PrintStream(outputStream);
int rc = execInProcess(kotlinHome, outputDir, scriptFile, out, compileContext); int rc = execInProcess(kotlinHome, outputDir, scriptFile, out, compileContext);
ProcessAdapter listener = createProcessListener(compileContext); ProcessAdapter listener = createProcessListener(compileContext, collector);
BufferedReader reader = new BufferedReader(new StringReader(outputStream.toString())); BufferedReader reader = new BufferedReader(new StringReader(outputStream.toString()));
while (true) { while (true) {
@@ -306,7 +311,7 @@ public class JetCompiler implements TranslatingCompiler {
return new URLClassLoader(urls, null); return new URLClassLoader(urls, null);
} }
private static void runOutOfProcess(CompileContext compileContext, VirtualFile outputDir, File kotlinHome, File scriptFile) { private static void runOutOfProcess(CompileContext compileContext, OutputItemsCollector collector, VirtualFile outputDir, File kotlinHome, File scriptFile) {
final SimpleJavaParameters params = new SimpleJavaParameters(); final SimpleJavaParameters params = new SimpleJavaParameters();
params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome())); params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome()));
params.setMainClass("org.jetbrains.jet.cli.KotlinCompiler"); params.setMainClass("org.jetbrains.jet.cli.KotlinCompiler");
@@ -337,7 +342,7 @@ public class JetCompiler implements TranslatingCompiler {
} }
}; };
ProcessAdapter processListener = createProcessListener(compileContext); ProcessAdapter processListener = createProcessListener(compileContext, collector);
processHandler.addProcessListener(processListener); processHandler.addProcessListener(processListener);
processHandler.startNotify(); processHandler.startNotify();
@@ -348,8 +353,44 @@ public class JetCompiler implements TranslatingCompiler {
} }
} }
private static ProcessAdapter createProcessListener(final CompileContext compileContext) { private static class OutputItemsCollector {
return new CompilerProcessListener(compileContext); private static final String FOR_SOURCE_PREFIX = "For source: ";
private static final String EMITTING_PREFIX = "Emitting: ";
private final String outputPath;
private VirtualFile currentSource;
private List<OutputItem> answer = new ArrayList<OutputItem>();
private List<VirtualFile> sources = new ArrayList<VirtualFile>();
private OutputItemsCollector(String outputPath) {
this.outputPath = outputPath;
}
public void learn(String message) {
message = message.trim();
if (message.startsWith(FOR_SOURCE_PREFIX)) {
currentSource = LocalFileSystem.getInstance().findFileByPath(message.substring(FOR_SOURCE_PREFIX.length()));
if (currentSource != null) {
sources.add(currentSource);
}
}
else if (message.startsWith(EMITTING_PREFIX)) {
if (currentSource != null) {
answer.add(new OutputItemImpl(outputPath + "/" + message.substring(EMITTING_PREFIX.length()), currentSource));
}
}
}
public List<OutputItem> getOutputs() {
return answer;
}
public List<VirtualFile> getSources() {
return sources;
}
}
private static ProcessAdapter createProcessListener(final CompileContext compileContext, OutputItemsCollector collector) {
return new CompilerProcessListener(compileContext, collector);
} }
private static String path(VirtualFile root) { private static String path(VirtualFile root) {
@@ -462,13 +503,15 @@ public class JetCompiler implements TranslatingCompiler {
} }
private final CompileContext compileContext; private final CompileContext compileContext;
private final OutputItemsCollector collector;
private final StringBuilder output = new StringBuilder(); private final StringBuilder output = new StringBuilder();
private int firstUnprocessedIndex = 0; private int firstUnprocessedIndex = 0;
private State state = State.WAITING; private State state = State.WAITING;
private CompilerMessage currentCompilerMessage; private CompilerMessage currentCompilerMessage;
public CompilerProcessListener(CompileContext compileContext) { public CompilerProcessListener(CompileContext compileContext, OutputItemsCollector collector) {
this.compileContext = compileContext; this.compileContext = compileContext;
this.collector = collector;
} }
@Override @Override
@@ -511,8 +554,14 @@ public class JetCompiler implements TranslatingCompiler {
case MESSAGE: { case MESSAGE: {
Matcher matcher = matcher(MESSAGE_PATTERN); Matcher matcher = matcher(MESSAGE_PATTERN);
if (find(matcher)) { if (find(matcher)) {
currentCompilerMessage.setMessage(matcher.group(1)); String message = matcher.group(1);
currentCompilerMessage.setMessage(message);
currentCompilerMessage.reportTo(compileContext); currentCompilerMessage.reportTo(compileContext);
if (currentCompilerMessage.messageCategory == STATISTICS) {
collector.learn(message);
}
state = State.WAITING; state = State.WAITING;
} }
break; break;