Corrected and simplified compilation of module chunk.
This commit is contained in:
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 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.cli.common.output
|
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
public trait OutputDirector {
|
|
||||||
public fun getOutputDirectory(sourceFiles: Collection<File>): File
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SingleDirectoryDirector(private val dir: File): OutputDirector {
|
|
||||||
override public fun getOutputDirectory(sourceFiles : Collection<File>) : File = dir
|
|
||||||
}
|
|
||||||
@@ -21,15 +21,13 @@ import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation
|
|||||||
import org.jetbrains.jet.cli.common.messages.OutputMessageUtil
|
import org.jetbrains.jet.cli.common.messages.OutputMessageUtil
|
||||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity
|
||||||
import org.jetbrains.jet.cli.common.messages.MessageCollector
|
import org.jetbrains.jet.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.jet.cli.common.output.OutputDirector
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import org.jetbrains.jet.cli.common.output.SingleDirectoryDirector
|
|
||||||
|
|
||||||
public fun OutputFileCollection.writeAll(outputDirector: OutputDirector, report: (sources: List<File>, output: File) -> Unit) {
|
public fun OutputFileCollection.writeAll(outputDir: File, report: (sources: List<File>, output: File) -> Unit) {
|
||||||
for (file in asList()) {
|
for (file in asList()) {
|
||||||
val sources = file.sourceFiles
|
val sources = file.sourceFiles
|
||||||
val output = File(outputDirector.getOutputDirectory(sources), file.relativePath)
|
val output = File(outputDir, file.relativePath)
|
||||||
report(sources, output)
|
report(sources, output)
|
||||||
FileUtil.writeToFile(output, file.asByteArray())
|
FileUtil.writeToFile(output, file.asByteArray())
|
||||||
}
|
}
|
||||||
@@ -38,11 +36,11 @@ public fun OutputFileCollection.writeAll(outputDirector: OutputDirector, report:
|
|||||||
private val REPORT_NOTHING = { (sources: List<File>, output: File) -> }
|
private val REPORT_NOTHING = { (sources: List<File>, output: File) -> }
|
||||||
|
|
||||||
public fun OutputFileCollection.writeAllTo(outputDir: File) {
|
public fun OutputFileCollection.writeAllTo(outputDir: File) {
|
||||||
writeAll(SingleDirectoryDirector(outputDir), REPORT_NOTHING)
|
writeAll(outputDir, REPORT_NOTHING)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun OutputFileCollection.writeAll(outputDirector: OutputDirector, messageCollector: MessageCollector) {
|
public fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector) {
|
||||||
writeAll(outputDirector) { sources, output ->
|
writeAll(outputDir) { sources, output ->
|
||||||
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION)
|
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output), CompilerMessageLocation.NO_LOCATION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,8 +38,6 @@ import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
|
|||||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
||||||
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
||||||
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||||
import org.jetbrains.jet.cli.common.output.OutputDirector;
|
|
||||||
import org.jetbrains.jet.cli.common.output.SingleDirectoryDirector;
|
|
||||||
import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage;
|
import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage;
|
||||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||||
import org.jetbrains.jet.config.CommonConfigurationKeys;
|
import org.jetbrains.jet.config.CommonConfigurationKeys;
|
||||||
@@ -136,8 +134,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
|
|
||||||
OutputFileCollection outputFiles = translate(mainCallParameters, config, sourcesFiles, outputFile, outputPrefixFile, outputPostfixFile);
|
OutputFileCollection outputFiles = translate(mainCallParameters, config, sourcesFiles, outputFile, outputPrefixFile, outputPostfixFile);
|
||||||
|
|
||||||
OutputDirector outputDirector = new SingleDirectoryDirector(outputFile.getParentFile());
|
OutputUtilsPackage.writeAll(outputFiles, outputFile.getParentFile(), messageCollector);
|
||||||
OutputUtilsPackage.writeAll(outputFiles, outputDirector, messageCollector);
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,11 @@ package org.jetbrains.jet.cli.jvm.compiler
|
|||||||
import kotlin.modules.Module
|
import kotlin.modules.Module
|
||||||
|
|
||||||
class ChunkAsOneModule(private val chunk: ModuleChunk) : Module {
|
class ChunkAsOneModule(private val chunk: ModuleChunk) : Module {
|
||||||
override fun getModuleName(): String = "chunk" + chunk.getModules().map { it.getModuleName() }.toString()
|
fun getModules(): List<Module> {
|
||||||
|
return chunk.getModules()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModuleName(): String = "chunk" + getModules().map { it.getModuleName() }.toString()
|
||||||
|
|
||||||
override fun getOutputDirectory(): String {
|
override fun getOutputDirectory(): String {
|
||||||
throw UnsupportedOperationException("Each module in a chunk has its own output directory")
|
throw UnsupportedOperationException("Each module in a chunk has its own output directory")
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
|||||||
import org.jetbrains.jet.cli.common.messages.MessageRenderer;
|
import org.jetbrains.jet.cli.common.messages.MessageRenderer;
|
||||||
import org.jetbrains.jet.cli.common.modules.ModuleDescription;
|
import org.jetbrains.jet.cli.common.modules.ModuleDescription;
|
||||||
import org.jetbrains.jet.cli.common.modules.ModuleXmlParser;
|
import org.jetbrains.jet.cli.common.modules.ModuleXmlParser;
|
||||||
import org.jetbrains.jet.cli.common.output.OutputDirector;
|
|
||||||
import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage;
|
import org.jetbrains.jet.cli.common.output.outputUtils.OutputUtilsPackage;
|
||||||
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
@@ -249,7 +248,7 @@ public class CompileEnvironmentUtil {
|
|||||||
|
|
||||||
static void writeOutputToDirOrJar(
|
static void writeOutputToDirOrJar(
|
||||||
@Nullable File jar,
|
@Nullable File jar,
|
||||||
@Nullable OutputDirector outputDir,
|
@Nullable File outputDir,
|
||||||
boolean includeRuntime,
|
boolean includeRuntime,
|
||||||
@Nullable FqName mainClass,
|
@Nullable FqName mainClass,
|
||||||
@NotNull ClassFileFactory outputFiles,
|
@NotNull ClassFileFactory outputFiles,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.cli.jvm.compiler;
|
package org.jetbrains.jet.cli.jvm.compiler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||||
import com.intellij.core.CoreApplicationEnvironment;
|
import com.intellij.core.CoreApplicationEnvironment;
|
||||||
import com.intellij.core.CoreJavaFileManager;
|
import com.intellij.core.CoreJavaFileManager;
|
||||||
@@ -31,13 +32,15 @@ import com.intellij.openapi.fileTypes.PlainTextFileType;
|
|||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
|
||||||
import com.intellij.psi.PsiElementFinder;
|
import com.intellij.psi.PsiElementFinder;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.PsiManager;
|
import com.intellij.psi.PsiManager;
|
||||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
import com.intellij.psi.compiled.ClassFileDecompilers;
|
||||||
import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy;
|
import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy;
|
||||||
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
|
import kotlin.io.IoPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.jet.CompilerModeProvider;
|
import org.jetbrains.jet.CompilerModeProvider;
|
||||||
@@ -203,9 +206,14 @@ public class JetCoreEnvironment {
|
|||||||
for (File path : configuration.getList(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY)) {
|
for (File path : configuration.getList(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY)) {
|
||||||
addExternalAnnotationsRoot(path);
|
addExternalAnnotationsRoot(path);
|
||||||
}
|
}
|
||||||
for (String path : configuration.getList(CommonConfigurationKeys.SOURCE_ROOTS_KEY)) {
|
sourceFiles.addAll(
|
||||||
addSources(path);
|
getJetFiles(this, configuration.getList(CommonConfigurationKeys.SOURCE_ROOTS_KEY), new Function1<String, Unit>() {
|
||||||
}
|
@Override
|
||||||
|
public Unit invoke(String s) {
|
||||||
|
report(ERROR, s);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
JetScriptDefinitionProvider.getInstance(project).addScriptDefinitions(
|
JetScriptDefinitionProvider.getInstance(project).addScriptDefinitions(
|
||||||
configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
|
configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
|
||||||
@@ -240,42 +248,43 @@ public class JetCoreEnvironment {
|
|||||||
annotationsManager.addExternalAnnotationsRoot(PathUtil.jarFileOrDirectoryToVirtualFile(path));
|
annotationsManager.addExternalAnnotationsRoot(PathUtil.jarFileOrDirectoryToVirtualFile(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSources(File file) {
|
@NotNull
|
||||||
if (file.isDirectory()) {
|
public static List<JetFile> getJetFiles(@NotNull final JetCoreEnvironment environment, @NotNull List<String> sourceRoots, @NotNull Function1<String, Unit> reportError) {
|
||||||
File[] files = file.listFiles();
|
final List<JetFile> result = Lists.newArrayList();
|
||||||
if (files != null) {
|
|
||||||
for (File child : files) {
|
for (String sourceRootPath : sourceRoots) {
|
||||||
addSources(child);
|
if (sourceRootPath == null) {
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
VirtualFile vFile = environment.getMyApplicationEnvironment().getLocalFileSystem().findFileByPath(sourceRootPath);
|
||||||
VirtualFile fileByPath = getMyApplicationEnvironment().getLocalFileSystem().findFileByPath(file.getAbsolutePath());
|
if (vFile == null) {
|
||||||
if (fileByPath != null) {
|
reportError.invoke("Source file or directory not found: " + sourceRootPath);
|
||||||
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(fileByPath);
|
continue;
|
||||||
if (psiFile instanceof JetFile) {
|
}
|
||||||
sourceFiles.add((JetFile) psiFile);
|
if (!vFile.isDirectory() && vFile.getFileType() != JetFileType.INSTANCE) {
|
||||||
}
|
reportError.invoke("Source entry is not a Kotlin file: " + sourceRootPath);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addSources(String path) {
|
IoPackage.recurse(new File(sourceRootPath), new Function1<File, Unit>() {
|
||||||
if (path == null) {
|
@Override
|
||||||
return;
|
public Unit invoke(File file) {
|
||||||
|
if (file.isFile()) {
|
||||||
|
VirtualFile fileByPath = environment.getMyApplicationEnvironment().getLocalFileSystem().findFileByPath(file.getAbsolutePath());
|
||||||
|
if (fileByPath != null) {
|
||||||
|
PsiFile psiFile = PsiManager.getInstance(environment.getProject()).findFile(fileByPath);
|
||||||
|
if (psiFile instanceof JetFile) {
|
||||||
|
result.add((JetFile) psiFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFile vFile = getMyApplicationEnvironment().getLocalFileSystem().findFileByPath(path);
|
return result;
|
||||||
if (vFile == null) {
|
|
||||||
report(ERROR, "Source file or directory not found: " + path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!vFile.isDirectory() && vFile.getFileType() != JetFileType.INSTANCE) {
|
|
||||||
report(ERROR, "Source entry is not a Kotlin file: " + path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addSources(new File(path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addToClasspath(File path) {
|
private void addToClasspath(File path) {
|
||||||
|
|||||||
+79
-68
@@ -17,10 +17,14 @@
|
|||||||
package org.jetbrains.jet.cli.jvm.compiler;
|
package org.jetbrains.jet.cli.jvm.compiler;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.util.Disposer;
|
import com.intellij.openapi.util.Disposer;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import kotlin.Function0;
|
import kotlin.Function0;
|
||||||
|
import kotlin.Function1;
|
||||||
|
import kotlin.Unit;
|
||||||
import kotlin.modules.AllModules;
|
import kotlin.modules.AllModules;
|
||||||
import kotlin.modules.Module;
|
import kotlin.modules.Module;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -31,8 +35,6 @@ import org.jetbrains.jet.cli.common.CompilerPlugin;
|
|||||||
import org.jetbrains.jet.cli.common.CompilerPluginContext;
|
import org.jetbrains.jet.cli.common.CompilerPluginContext;
|
||||||
import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
|
import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
|
||||||
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||||
import org.jetbrains.jet.cli.common.output.OutputDirector;
|
|
||||||
import org.jetbrains.jet.cli.common.output.SingleDirectoryDirector;
|
|
||||||
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys;
|
||||||
import org.jetbrains.jet.codegen.*;
|
import org.jetbrains.jet.codegen.*;
|
||||||
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
||||||
@@ -56,26 +58,73 @@ import org.jetbrains.jet.utils.KotlinPaths;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class KotlinToJVMBytecodeCompiler {
|
public class KotlinToJVMBytecodeCompiler {
|
||||||
|
|
||||||
private static final boolean COMPILE_CHUNK_AS_ONE_MODULE = true;
|
|
||||||
|
|
||||||
private KotlinToJVMBytecodeCompiler() {
|
private KotlinToJVMBytecodeCompiler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static ClassFileFactory compileModule(CompilerConfiguration configuration, Module module, File directory) {
|
public static Map<Module, ClassFileFactory> compileModule(
|
||||||
List<String> sourceFiles = module.getSourceFiles();
|
@NotNull CompilerConfiguration configuration,
|
||||||
if (sourceFiles.isEmpty()) {
|
@NotNull List<Module> modules,
|
||||||
throw new CompileEnvironmentException("No source files where defined in module " + module.getModuleName());
|
@NotNull File directory
|
||||||
|
) {
|
||||||
|
CompilerConfiguration compilerConfiguration = configuration.copy();
|
||||||
|
for (Module module : modules) {
|
||||||
|
compilerConfiguration.addAll(CommonConfigurationKeys.SOURCE_ROOTS_KEY, getAbsolutePaths(directory, module));
|
||||||
|
|
||||||
|
for (String classpathRoot : module.getClasspathRoots()) {
|
||||||
|
compilerConfiguration.add(JVMConfigurationKeys.CLASSPATH_KEY, new File(classpathRoot));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String annotationsRoot : module.getAnnotationsRoots()) {
|
||||||
|
compilerConfiguration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, new File(annotationsRoot));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerConfiguration compilerConfiguration = configuration.copy();
|
Disposable parentDisposable = Disposer.newDisposable();
|
||||||
for (String sourceFile : sourceFiles) {
|
JetCoreEnvironment moduleEnvironment = null;
|
||||||
|
try {
|
||||||
|
moduleEnvironment = JetCoreEnvironment.createForProduction(parentDisposable, compilerConfiguration);
|
||||||
|
|
||||||
|
AnalyzeExhaust exhaust = analyze(moduleEnvironment);
|
||||||
|
if (exhaust == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
exhaust.throwIfError();
|
||||||
|
|
||||||
|
Map<Module, ClassFileFactory> result = Maps.newHashMap();
|
||||||
|
|
||||||
|
for (Module module : modules) {
|
||||||
|
List<JetFile> jetFiles = JetCoreEnvironment.getJetFiles(
|
||||||
|
moduleEnvironment, getAbsolutePaths(directory, module), new Function1<String, Unit>() {
|
||||||
|
@Override
|
||||||
|
public Unit invoke(String s) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
GenerationState generationState = generate(moduleEnvironment, exhaust, jetFiles);
|
||||||
|
result.put(module, generationState.getFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (moduleEnvironment != null) {
|
||||||
|
Disposer.dispose(parentDisposable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<String> getAbsolutePaths(@NotNull File directory, @NotNull Module module) {
|
||||||
|
List<String> result = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (String sourceFile : module.getSourceFiles()) {
|
||||||
File source = new File(sourceFile);
|
File source = new File(sourceFile);
|
||||||
if (!source.isAbsolute()) {
|
if (!source.isAbsolute()) {
|
||||||
source = new File(directory, sourceFile);
|
source = new File(directory, sourceFile);
|
||||||
@@ -85,39 +134,15 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
throw new CompileEnvironmentException("'" + source + "' does not exist in module " + module.getModuleName());
|
throw new CompileEnvironmentException("'" + source + "' does not exist in module " + module.getModuleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
compilerConfiguration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, source.getPath());
|
result.add(source.getAbsolutePath());
|
||||||
}
|
|
||||||
|
|
||||||
for (String classpathRoot : module.getClasspathRoots()) {
|
|
||||||
compilerConfiguration.add(JVMConfigurationKeys.CLASSPATH_KEY, new File(classpathRoot));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String annotationsRoot : module.getAnnotationsRoots()) {
|
|
||||||
compilerConfiguration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, new File(annotationsRoot));
|
|
||||||
}
|
|
||||||
|
|
||||||
Disposable parentDisposable = Disposer.newDisposable();
|
|
||||||
JetCoreEnvironment moduleEnvironment = null;
|
|
||||||
try {
|
|
||||||
moduleEnvironment = JetCoreEnvironment.createForProduction(parentDisposable, compilerConfiguration);
|
|
||||||
|
|
||||||
|
|
||||||
GenerationState generationState = analyzeAndGenerate(moduleEnvironment);
|
|
||||||
if (generationState == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return generationState.getFactory();
|
|
||||||
} finally {
|
|
||||||
if (moduleEnvironment != null) {
|
|
||||||
Disposer.dispose(parentDisposable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeOutput(
|
private static void writeOutput(
|
||||||
CompilerConfiguration configuration,
|
CompilerConfiguration configuration,
|
||||||
ClassFileFactory outputFiles,
|
ClassFileFactory outputFiles,
|
||||||
OutputDirector outputDir,
|
File outputDir,
|
||||||
File jarPath,
|
File jarPath,
|
||||||
boolean jarRuntime,
|
boolean jarRuntime,
|
||||||
FqName mainClass
|
FqName mainClass
|
||||||
@@ -127,37 +152,20 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean compileModules(
|
public static boolean compileModules(
|
||||||
CompilerConfiguration configuration,
|
@NotNull CompilerConfiguration configuration,
|
||||||
@NotNull final ModuleChunk chunk,
|
@NotNull ModuleChunk chunk,
|
||||||
@NotNull File directory,
|
@NotNull File directory,
|
||||||
@Nullable File jarPath,
|
@Nullable File jarPath,
|
||||||
boolean jarRuntime
|
boolean jarRuntime
|
||||||
) {
|
) {
|
||||||
List<Module> modules = chunk.getModules();
|
List<Module> modules = chunk.getModules();
|
||||||
if (COMPILE_CHUNK_AS_ONE_MODULE && modules.size() > 1) {
|
|
||||||
modules = Collections.<Module>singletonList(new ChunkAsOneModule(chunk));
|
Map<Module, ClassFileFactory> outputFiles = compileModule(configuration, modules, directory);
|
||||||
|
if (outputFiles == null) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
for (Module module : modules) {
|
for (Module module : modules) {
|
||||||
ClassFileFactory outputFiles = compileModule(configuration, module, directory);
|
writeOutput(configuration, outputFiles.get(module), new File(module.getOutputDirectory()), jarPath, jarRuntime, null);
|
||||||
if (outputFiles == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
OutputDirector outputDir = new OutputDirector() {
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public File getOutputDirectory(@NotNull Collection<? extends File> sourceFiles) {
|
|
||||||
for (File sourceFile : sourceFiles) {
|
|
||||||
// Note that here we track original modules:
|
|
||||||
Module module = chunk.findModuleBySourceFile(sourceFile);
|
|
||||||
if (module != null) {
|
|
||||||
return new File(module.getOutputDirectory());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("No module found for source files: " + sourceFiles);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
writeOutput(configuration, outputFiles, outputDir, jarPath, jarRuntime, null);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -194,8 +202,7 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
FqName mainClass = findMainClass(generationState, environment.getSourceFiles());
|
FqName mainClass = findMainClass(generationState, environment.getSourceFiles());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OutputDirector outputDirector = outputDir != null ? new SingleDirectoryDirector(outputDir) : null;
|
writeOutput(environment.getConfiguration(), generationState.getFactory(), outputDir, jar, includeRuntime, mainClass);
|
||||||
writeOutput(environment.getConfiguration(), generationState.getFactory(), outputDirector, jar, includeRuntime, mainClass);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
@@ -262,7 +269,7 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
|
|
||||||
exhaust.throwIfError();
|
exhaust.throwIfError();
|
||||||
|
|
||||||
return generate(environment, exhaust);
|
return generate(environment, exhaust, environment.getSourceFiles());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -301,11 +308,15 @@ public class KotlinToJVMBytecodeCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static GenerationState generate(@NotNull JetCoreEnvironment environment, @NotNull AnalyzeExhaust exhaust) {
|
private static GenerationState generate(
|
||||||
|
@NotNull JetCoreEnvironment environment,
|
||||||
|
@NotNull AnalyzeExhaust exhaust,
|
||||||
|
@NotNull List<JetFile> sourceFiles
|
||||||
|
) {
|
||||||
CompilerConfiguration configuration = environment.getConfiguration();
|
CompilerConfiguration configuration = environment.getConfiguration();
|
||||||
GenerationState generationState = new GenerationState(
|
GenerationState generationState = new GenerationState(
|
||||||
environment.getProject(), ClassBuilderFactories.BINARIES, Progress.DEAF,
|
environment.getProject(), ClassBuilderFactories.BINARIES, Progress.DEAF,
|
||||||
exhaust.getModuleDescriptor(), exhaust.getBindingContext(), environment.getSourceFiles(),
|
exhaust.getModuleDescriptor(), exhaust.getBindingContext(), sourceFiles,
|
||||||
configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_ASSERTIONS, false),
|
configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_ASSERTIONS, false),
|
||||||
configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_PARAMETER_ASSERTIONS, false),
|
configuration.get(JVMConfigurationKeys.GENERATE_NOT_NULL_PARAMETER_ASSERTIONS, false),
|
||||||
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
||||||
|
|||||||
@@ -16,39 +16,24 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.cli.jvm.compiler;
|
package org.jetbrains.jet.cli.jvm.compiler;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import kotlin.modules.Module;
|
import kotlin.modules.Module;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ModuleChunk {
|
public class ModuleChunk {
|
||||||
|
|
||||||
public static final ModuleChunk EMPTY = new ModuleChunk(Collections.<Module>emptyList());
|
public static final ModuleChunk EMPTY = new ModuleChunk(Collections.<Module>emptyList());
|
||||||
|
|
||||||
private final List<Module> modules;
|
private final List<Module> modules;
|
||||||
private final Map<File, Module> sourceFileToModule = Maps.newHashMap();
|
|
||||||
|
|
||||||
public ModuleChunk(@NotNull List<Module> modules) {
|
public ModuleChunk(@NotNull List<Module> modules) {
|
||||||
this.modules = modules;
|
this.modules = modules;
|
||||||
for (Module module : modules) {
|
|
||||||
for (String file : module.getSourceFiles()) {
|
|
||||||
sourceFileToModule.put(new File(file).getAbsoluteFile(), module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<Module> getModules() {
|
public List<Module> getModules() {
|
||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Module findModuleBySourceFile(@NotNull File sourceFile) {
|
|
||||||
return sourceFileToModule.get(sourceFile.getAbsoluteFile());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,15 @@ import org.jetbrains.jps.model.java.JpsJavaDependencyScope;
|
|||||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
|
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
|
||||||
import org.jetbrains.jps.model.module.JpsModule;
|
import org.jetbrains.jps.model.module.JpsModule;
|
||||||
import org.jetbrains.jps.util.JpsPathUtil;
|
import org.jetbrains.jps.util.JpsPathUtil;
|
||||||
|
import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||||
|
import org.jetbrains.org.objectweb.asm.ClassVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public class KotlinJpsBuildTest extends AbstractKotlinJpsBuildTestCase {
|
public class KotlinJpsBuildTest extends AbstractKotlinJpsBuildTestCase {
|
||||||
private static final String PROJECT_NAME = "kotlinProject";
|
private static final String PROJECT_NAME = "kotlinProject";
|
||||||
@@ -204,6 +210,34 @@ public class KotlinJpsBuildTest extends AbstractKotlinJpsBuildTestCase {
|
|||||||
checkPackageDeletedFromOutputWhen(Operation.CHANGE, "module2", "module2/src/kt1.kt", "kt1.Kt1Package");
|
checkPackageDeletedFromOutputWhen(Operation.CHANGE, "module2", "module2/src/kt1.kt", "kt1.Kt1Package");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCircularDependenciesSamePackage() throws IOException {
|
||||||
|
initProject();
|
||||||
|
BuildResult result = makeAll();
|
||||||
|
result.assertSuccessful();
|
||||||
|
|
||||||
|
// Check that outputs are located properly
|
||||||
|
File facadeWithA = findFileInOutputDir(findModule("module1"), "test/TestPackage.class");
|
||||||
|
File facadeWithB = findFileInOutputDir(findModule("module2"), "test/TestPackage.class");
|
||||||
|
assertSameElements(getMethodsOfClass(facadeWithA), "a", "getA");
|
||||||
|
assertSameElements(getMethodsOfClass(facadeWithB), "b", "getB", "setB");
|
||||||
|
|
||||||
|
checkPackageDeletedFromOutputWhen(Operation.CHANGE, "module1", "module1/src/a.kt", "test.TestPackage");
|
||||||
|
checkPackageDeletedFromOutputWhen(Operation.CHANGE, "module2", "module2/src/b.kt", "test.TestPackage");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Set<String> getMethodsOfClass(@NotNull File classFile) throws IOException {
|
||||||
|
final Set<String> result = new TreeSet<String>();
|
||||||
|
new ClassReader(FileUtil.loadFileBytes(classFile)).accept(new ClassVisitor(Opcodes.ASM5) {
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||||
|
result.add(name);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void testReexportedDependency() {
|
public void testReexportedDependency() {
|
||||||
initProject();
|
initProject();
|
||||||
addKotlinRuntimeDependency(JpsJavaDependencyScope.COMPILE,
|
addKotlinRuntimeDependency(JpsJavaDependencyScope.COMPILE,
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||||
|
<resourceExtensions />
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile default="true" name="Default" enabled="false">
|
||||||
|
<processorPath useClasspath="true" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
</component>
|
||||||
|
<component name="CopyrightManager" default="">
|
||||||
|
<module2copyright />
|
||||||
|
</component>
|
||||||
|
<component name="DependencyValidationManager">
|
||||||
|
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||||
|
</component>
|
||||||
|
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/module1/module1.iml" filepath="$PROJECT_DIR$/module1/module1.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/module2/module2.iml" filepath="$PROJECT_DIR$/module2/module2.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="xUTF-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="IDEA_JDK" jdkType="JavaSDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="module2" />
|
||||||
|
<orderEntry type="library" name="KotlinRuntime" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun a() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val a = ""
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?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="IDEA_JDK" jdkType="JavaSDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="module1" />
|
||||||
|
<orderEntry type="library" name="KotlinRuntime" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun b() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var b = ""
|
||||||
Reference in New Issue
Block a user