diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml
index 2d499134d9c..e9b1e4e22be 100644
--- a/.idea/artifacts/KotlinPlugin.xml
+++ b/.idea/artifacts/KotlinPlugin.xml
@@ -16,6 +16,7 @@
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 3c414759cd4..b208f13d4ec 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -13,6 +13,7 @@
+
diff --git a/ide-compiler-runner/ide-compiler-runner.iml b/ide-compiler-runner/ide-compiler-runner.iml
new file mode 100644
index 00000000000..8aa91671dfd
--- /dev/null
+++ b/ide-compiler-runner/ide-compiler-runner.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinModuleScriptGenerator.java b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinModuleScriptGenerator.java
new file mode 100644
index 00000000000..ba66efdfeda
--- /dev/null
+++ b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/KotlinModuleScriptGenerator.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.compiler.runner;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+public class KotlinModuleScriptGenerator {
+
+ public interface DependencyProvider {
+ void processClassPath(@NotNull DependencyProcessor processor);
+ }
+
+ public interface DependencyProcessor {
+ void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection paths);
+ void processAnnotationRoots(@NotNull List paths);
+ }
+
+ public static CharSequence generateModuleScript(String moduleName,
+ DependencyProvider dependencyProvider,
+ List sourceFilePaths,
+ boolean tests,
+ final Set directoriesToFilterOut) {
+ final StringBuilder script = new StringBuilder();
+
+ if (tests) {
+ script.append("// Module script for tests\n");
+ }
+ else {
+ script.append("// Module script for production\n");
+ }
+
+ script.append("import kotlin.modules.*\n");
+ script.append("fun project() {\n");
+ script.append(" module(\"" + moduleName + "\") {\n");
+
+ for (String sourceFile : sourceFilePaths) {
+ script.append(" sources += \"" + sourceFile + "\"\n");
+ }
+
+ dependencyProvider.processClassPath(new DependencyProcessor() {
+ @Override
+ public void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection paths) {
+ script.append(" // " + sectionDescription + "\n");
+ for (String path : paths) {
+ if (directoriesToFilterOut.contains(path)) {
+ // 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 += \"" + path + "\"\n");
+ }
+ }
+
+ @Override
+ public void processAnnotationRoots(@NotNull List paths) {
+ script.append(" // External annotations\n");
+ for (String path : paths) {
+ script.append(" annotationsPath += \"").append(path).append("\"\n");
+ }
+ }
+ });
+
+ script.append(" }\n");
+ script.append("}\n");
+ return script;
+ }
+}
diff --git a/idea/idea.iml b/idea/idea.iml
index f2f75412f36..423f3f24465 100644
--- a/idea/idea.iml
+++ b/idea/idea.iml
@@ -29,6 +29,7 @@
+
diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
index a2e35482e99..7af40db1c5d 100644
--- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
+++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java
@@ -16,13 +16,13 @@
package org.jetbrains.jet.plugin.compiler;
-import com.google.common.collect.Sets;
import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.compiler.TranslatingCompiler;
import com.intellij.openapi.compiler.ex.CompileContextEx;
import com.intellij.openapi.module.Module;
@@ -35,9 +35,12 @@ import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Chunk;
+import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
+import com.intellij.util.containers.ContainerUtil;
import jet.Function1;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.compiler.runner.KotlinModuleScriptGenerator;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.project.JsModuleDetector;
@@ -119,9 +122,9 @@ public class JetCompiler implements TranslatingCompiler {
return;
}
- File scriptFile =
- tryToWriteScriptFile(compileContext, moduleChunk, files, module, tests, compileContext.getModuleOutputDirectory(module),
- environment.getOutput());
+ File scriptFile = tryToWriteScriptFile(compileContext, moduleChunk, files, module, tests,
+ compileContext.getModuleOutputDirectory(module),
+ environment.getOutput());
if (scriptFile == null) return;
@@ -142,96 +145,67 @@ public class JetCompiler implements TranslatingCompiler {
}
}
- private static File tryToWriteScriptFile(CompileContext compileContext,
+ public static File tryToWriteScriptFile(
+ CompileContext compileContext,
Chunk moduleChunk,
List files,
Module module,
- boolean tests, VirtualFile mainOutput, VirtualFile outputDir) {
- ModuleChunk
- chunk = new ModuleChunk((CompileContextEx)compileContext, moduleChunk, Collections.>emptyMap());
+ boolean tests, VirtualFile mainOutput, VirtualFile outputDir
+ ) {
+ ArrayList sourceFilePaths = ContainerUtil.newArrayList(paths(files));
+ ModuleChunk chunk = new ModuleChunk((CompileContextEx)compileContext, moduleChunk, Collections.>emptyMap());
String moduleName = moduleChunk.getNodes().iterator().next().getName();
+ String outputDirectoryForTests = path(compileContext.getModuleOutputDirectoryForTests(module));
+ String moduleOutputDirectory = path(compileContext.getModuleOutputDirectory(module));
// Filter the output we are writing to
- Set outputDirectoriesToFilter = Sets.newHashSet(compileContext.getModuleOutputDirectoryForTests(module));
+ Set outputDirectoriesToFilter = ContainerUtil.newHashSet(outputDirectoryForTests);
if (!tests) {
- outputDirectoriesToFilter.add(compileContext.getModuleOutputDirectory(module));
+ outputDirectoriesToFilter.add(moduleOutputDirectory);
}
- CharSequence script = generateModuleScript(moduleName, chunk, files, tests, mainOutput, outputDirectoriesToFilter);
+ CharSequence script = KotlinModuleScriptGenerator.generateModuleScript(
+ moduleName,
+ getDependencyProvider(chunk, tests, mainOutput),
+ sourceFilePaths,
+ tests,
+ outputDirectoriesToFilter
+ );
File scriptFile = new File(path(outputDir), "script.kts");
try {
FileUtil.writeToFile(scriptFile, script.toString());
}
catch (IOException e) {
- compileContext.addMessage(ERROR, "[Internal Error] Cannot write script to " + scriptFile.getAbsolutePath(), "", -1, -1);
+ compileContext.addMessage(CompilerMessageCategory.ERROR, "[Internal Error] Cannot write script to " + scriptFile.getAbsolutePath(), "", -1, -1);
return null;
}
return scriptFile;
}
- private static CharSequence generateModuleScript(String moduleName,
- ModuleChunk chunk,
- List files,
- boolean tests,
- VirtualFile mainOutput,
- Set directoriesToFilterOut) {
- StringBuilder script = new StringBuilder();
+ private static KotlinModuleScriptGenerator.DependencyProvider getDependencyProvider(
+ final ModuleChunk chunk,
+ final boolean tests,
+ final VirtualFile mainOutputPath
+ ) {
+ return new KotlinModuleScriptGenerator.DependencyProvider() {
+ @Override
+ public void processClassPath(@NotNull KotlinModuleScriptGenerator.DependencyProcessor processor) {
+ // TODO: have a bootclasspath in script API
+ processor.processClassPathSection("Boot classpath", paths(chunk.getCompilationBootClasspathFiles()));
- if (tests) {
- script.append("// Module script for tests\n");
- }
- else {
- script.append("// Module script for production\n");
- }
+ processor.processClassPathSection("Compilation classpath", paths(chunk.getCompilationClasspathFiles()));
- script.append("import kotlin.modules.*\n");
- script.append("fun project() {\n");
- script.append(" module(\"" + moduleName + "\") {\n");
+ // This is for java files in same roots
+ processor.processClassPathSection("Java classpath (for Java sources)", paths(Arrays.asList(chunk.getSourceRoots())));
- for (VirtualFile sourceFile : files) {
- script.append(" sources += \"" + path(sourceFile) + "\"\n");
- }
- // TODO: have a bootclasspath in script API
- script.append(" // Boot classpath\n");
- for (VirtualFile root : chunk.getCompilationBootClasspathFiles()) {
- script.append(" classpath += \"" + path(root) + "\"\n");
- }
+ if (tests && mainOutputPath != null) {
+ processor.processClassPathSection("Main output", Arrays.asList(path(mainOutputPath)));
+ }
- script.append(" // Compilation classpath\n");
- for (VirtualFile root : chunk.getCompilationClasspathFiles()) {
- String path = path(root);
- if (directoriesToFilterOut.contains(root)) {
- // 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(" // ");
+ processor.processAnnotationRoots(getAnnotationRootPaths(chunk));
}
- script.append(" classpath += \"" + path + "\"\n");
- }
-
- // This is for java files in same roots
- script.append(" // Java classpath (for Java sources)\n");
- for (VirtualFile root : chunk.getSourceRoots()) {
- script.append(" classpath += \"" + path(root) + "\"\n");
- }
-
- script.append(" // Main output\n");
- if (tests && mainOutput != null) {
- script.append(" classpath += \"" + path(mainOutput) + "\"\n");
- }
-
- script.append(" // External annotations\n");
- for (Module module : chunk.getModules()) {
- for (VirtualFile file : OrderEnumerator.orderEntries(module).roots(AnnotationOrderRootType.getInstance()).getRoots()) {
- script.append(" annotationsPath += \"").append(path(file)).append("\"\n");
- }
- }
-
- script.append(" }\n");
- script.append("}\n");
- return script;
+ };
}
private static void runInProcess(final CompileContext compileContext,
@@ -331,6 +305,25 @@ public class JetCompiler implements TranslatingCompiler {
}
}
+ private static List getAnnotationRootPaths(ModuleChunk chunk) {
+ List annotationPaths = ContainerUtil.newArrayList();
+ for (Module module : chunk.getModules()) {
+ for (VirtualFile file : OrderEnumerator.orderEntries(module).roots(AnnotationOrderRootType.getInstance()).getRoots()) {
+ annotationPaths.add(path(file));
+ }
+ }
+ return annotationPaths;
+ }
+
+ private static Collection paths(Collection files) {
+ return ContainerUtil.map(files, new Function() {
+ @Override
+ public String fun(VirtualFile file) {
+ return path(file);
+ }
+ });
+ }
+
private static String path(VirtualFile root) {
String path = root.getPath();
if (path.endsWith("!/")) {