Module script generation moved to a separate module
To be re-used by the external build later
This commit is contained in:
Generated
+1
@@ -16,6 +16,7 @@
|
||||
<element id="module-output" name="j2k" />
|
||||
<element id="module-output" name="js.translator" />
|
||||
<element id="module-output" name="cli-common" />
|
||||
<element id="module-output" name="ide-compiler-runner" />
|
||||
</element>
|
||||
<element id="library" level="project" name="js-libs" />
|
||||
<element id="archive" name="kotlin-js-libraries.zip">
|
||||
|
||||
Generated
+1
@@ -13,6 +13,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/frontend/frontend.iml" filepath="$PROJECT_DIR$/compiler/frontend/frontend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" filepath="$PROJECT_DIR$/compiler/frontend.java/frontend.java.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/ide-compiler-runner/ide-compiler-runner.iml" filepath="$PROJECT_DIR$/ide-compiler-runner/ide-compiler-runner.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea_runner/idea_runner.iml" filepath="$PROJECT_DIR$/idea_runner/idea_runner.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/injector-generator/injector-generator.iml" filepath="$PROJECT_DIR$/injector-generator/injector-generator.iml" />
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.6" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="idea-full" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
+87
@@ -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<String> paths);
|
||||
void processAnnotationRoots(@NotNull List<String> paths);
|
||||
}
|
||||
|
||||
public static CharSequence generateModuleScript(String moduleName,
|
||||
DependencyProvider dependencyProvider,
|
||||
List<String> sourceFilePaths,
|
||||
boolean tests,
|
||||
final Set<String> 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<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
<orderEntry type="module" module-name="j2k" />
|
||||
<orderEntry type="module" module-name="js.translator" />
|
||||
<orderEntry type="module" module-name="cli" scope="TEST" />
|
||||
<orderEntry type="module" module-name="ide-compiler-runner" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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<Module> moduleChunk,
|
||||
List<VirtualFile> files,
|
||||
Module module,
|
||||
boolean tests, VirtualFile mainOutput, VirtualFile outputDir) {
|
||||
ModuleChunk
|
||||
chunk = new ModuleChunk((CompileContextEx)compileContext, moduleChunk, Collections.<Module, List<VirtualFile>>emptyMap());
|
||||
boolean tests, VirtualFile mainOutput, VirtualFile outputDir
|
||||
) {
|
||||
ArrayList<String> sourceFilePaths = ContainerUtil.newArrayList(paths(files));
|
||||
ModuleChunk chunk = new ModuleChunk((CompileContextEx)compileContext, moduleChunk, Collections.<Module, List<VirtualFile>>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<VirtualFile> outputDirectoriesToFilter = Sets.newHashSet(compileContext.getModuleOutputDirectoryForTests(module));
|
||||
Set<String> 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<VirtualFile> files,
|
||||
boolean tests,
|
||||
VirtualFile mainOutput,
|
||||
Set<VirtualFile> 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<String> getAnnotationRootPaths(ModuleChunk chunk) {
|
||||
List<String> 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<String> paths(Collection<VirtualFile> files) {
|
||||
return ContainerUtil.map(files, new Function<VirtualFile, String>() {
|
||||
@Override
|
||||
public String fun(VirtualFile file) {
|
||||
return path(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static String path(VirtualFile root) {
|
||||
String path = root.getPath();
|
||||
if (path.endsWith("!/")) {
|
||||
|
||||
Reference in New Issue
Block a user