CompileEnvironment removed
What used to be CompileEnvironment, now is split into data (in CompileEnvironmentConfiguration) and utility methods (in CompileEnvironmentUtil). CompilerDependencies should be removed later. All the relevant stuff sits in the JetCoreEnvironment class
This commit is contained in:
@@ -20,11 +20,11 @@ import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.sampullara.cli.Args;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironment;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentException;
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin;
|
||||
import org.jetbrains.jet.compiler.*;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageLocation;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
@@ -135,23 +135,30 @@ public class KotlinCompiler {
|
||||
runtimeJar = null;
|
||||
}
|
||||
|
||||
CompilerDependencies dependencies = new CompilerDependencies(mode, jdkHeadersJar,runtimeJar);
|
||||
CompilerDependencies dependencies = new CompilerDependencies(mode, jdkHeadersJar, runtimeJar);
|
||||
PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
|
||||
CompileEnvironment environment = new CompileEnvironment(messageCollector, dependencies);
|
||||
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||
|
||||
JetCoreEnvironment environment = new JetCoreEnvironment(rootDisposable, dependencies);
|
||||
CompileEnvironmentConfiguration configuration = new CompileEnvironmentConfiguration(environment, dependencies, messageCollector);
|
||||
try {
|
||||
configureEnvironment(environment, arguments);
|
||||
configureEnvironment(configuration, arguments);
|
||||
|
||||
boolean noErrors;
|
||||
if (arguments.module != null) {
|
||||
noErrors = environment.compileModuleScript(arguments.module, arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileModuleScript(configuration,
|
||||
arguments.module, arguments.jar, arguments.outputDir,
|
||||
arguments.includeRuntime);
|
||||
}
|
||||
else {
|
||||
// TODO ideally we'd unify to just having a single field that supports multiple files/dirs
|
||||
if (arguments.getSourceDirs() != null) {
|
||||
noErrors = environment.compileBunchOfSourceDirectories(arguments.getSourceDirs(), arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSourceDirectories(configuration,
|
||||
arguments.getSourceDirs(), arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
}
|
||||
else {
|
||||
noErrors = environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSources(configuration,
|
||||
arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
}
|
||||
}
|
||||
return noErrors ? OK : COMPILATION_ERROR;
|
||||
@@ -161,7 +168,7 @@ public class KotlinCompiler {
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
finally {
|
||||
environment.dispose();
|
||||
Disposer.dispose(rootDisposable);
|
||||
messageCollector.printToErrStream();
|
||||
}
|
||||
}
|
||||
@@ -228,20 +235,20 @@ public class KotlinCompiler {
|
||||
* Strategy method to configure the environment, allowing compiler
|
||||
* based tools to customise their own plugins
|
||||
*/
|
||||
protected void configureEnvironment(CompileEnvironment environment, CompilerArguments arguments) {
|
||||
protected void configureEnvironment(CompileEnvironmentConfiguration configuration, CompilerArguments arguments) {
|
||||
// install any compiler plugins
|
||||
List<CompilerPlugin> plugins = arguments.getCompilerPlugins();
|
||||
if (plugins != null) {
|
||||
environment.getEnvironment().getCompilerPlugins().addAll(plugins);
|
||||
configuration.getEnvironment().getCompilerPlugins().addAll(plugins);
|
||||
}
|
||||
|
||||
if (environment.getCompilerDependencies().getRuntimeJar() != null) {
|
||||
environment.addToClasspath(environment.getCompilerDependencies().getRuntimeJar());
|
||||
if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
|
||||
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
|
||||
}
|
||||
|
||||
if (arguments.classpath != null) {
|
||||
final Iterable<String> classpath = Splitter.on(File.pathSeparatorChar).split(arguments.classpath);
|
||||
environment.addToClasspath(Iterables.toArray(classpath, String.class));
|
||||
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), Iterables.toArray(classpath, String.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GeneratedClassLoader;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.jetbrains.jet.plugin.JetMainDetector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The environment for compiling a bunch of source files or
|
||||
*
|
||||
* @author yole
|
||||
*/
|
||||
public class CompileEnvironment {
|
||||
private final Disposable rootDisposable;
|
||||
private JetCoreEnvironment environment;
|
||||
|
||||
private final MessageCollector messageCollector;
|
||||
|
||||
@NotNull
|
||||
private final CompilerDependencies compilerDependencies;
|
||||
|
||||
/**
|
||||
* NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
|
||||
* @see Disposer
|
||||
*/
|
||||
public CompileEnvironment(@NotNull MessageCollector messageCollector, @NotNull CompilerDependencies compilerDependencies) {
|
||||
this.messageCollector = messageCollector;
|
||||
this.compilerDependencies = compilerDependencies;
|
||||
this.rootDisposable = new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
this.environment = new JetCoreEnvironment(rootDisposable, compilerDependencies);
|
||||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
Disposer.dispose(rootDisposable);
|
||||
}
|
||||
|
||||
public boolean compileModuleScript(String moduleScriptFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
|
||||
List<Module> modules = CompileEnvironmentUtil.loadModuleScript(moduleScriptFile, messageCollector);
|
||||
|
||||
if (modules == null) {
|
||||
throw new CompileEnvironmentException("Module script " + moduleScriptFile + " compilation failed");
|
||||
}
|
||||
|
||||
if (modules.isEmpty()) {
|
||||
throw new CompileEnvironmentException("No modules where defined by " + moduleScriptFile);
|
||||
}
|
||||
|
||||
final String directory = new File(moduleScriptFile).getParent();
|
||||
for (Module moduleBuilder : modules) {
|
||||
if (compilerDependencies.getRuntimeJar() != null) {
|
||||
addToClasspath(compilerDependencies.getRuntimeJar());
|
||||
}
|
||||
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
|
||||
if (moduleFactory == null) {
|
||||
return false;
|
||||
}
|
||||
if (outputDir != null) {
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(moduleFactory, outputDir);
|
||||
}
|
||||
else {
|
||||
String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
|
||||
if (moduleBuilder.getSourceFiles().isEmpty()) {
|
||||
throw new CompileEnvironmentException("No source files where defined");
|
||||
}
|
||||
|
||||
for (String sourceFile : moduleBuilder.getSourceFiles()) {
|
||||
File source = new File(sourceFile);
|
||||
if (!source.isAbsolute()) {
|
||||
source = new File(directory, sourceFile);
|
||||
}
|
||||
|
||||
if (!source.exists()) {
|
||||
throw new CompileEnvironmentException("'" + source + "' does not exist");
|
||||
}
|
||||
|
||||
environment.addSources(source.getPath());
|
||||
}
|
||||
for (String classpathRoot : moduleBuilder.getClasspathRoots()) {
|
||||
environment.addToClasspath(new File(classpathRoot));
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(environment, compilerDependencies);
|
||||
|
||||
return analyze();
|
||||
}
|
||||
|
||||
public ClassLoader compileText(String code) {
|
||||
environment.addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
|
||||
|
||||
ClassFileFactory factory = analyze();
|
||||
if (factory == null) {
|
||||
return null;
|
||||
}
|
||||
return new GeneratedClassLoader(factory);
|
||||
}
|
||||
|
||||
public boolean compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
|
||||
environment.addSources(sourceFileOrDir);
|
||||
|
||||
return compileBunchOfSources(jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
public boolean compileBunchOfSourceDirectories(List<String> sources, String jar, String outputDir, boolean includeRuntime) {
|
||||
for (String source : sources) {
|
||||
environment.addSources(source);
|
||||
}
|
||||
|
||||
return compileBunchOfSources(jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
private boolean compileBunchOfSources(String jar, String outputDir, boolean includeRuntime) {
|
||||
FqName mainClass = null;
|
||||
for (JetFile file : environment.getSourceFiles()) {
|
||||
if (JetMainDetector.hasMain(file.getDeclarations())) {
|
||||
FqName fqName = JetPsiUtil.getFQName(file);
|
||||
mainClass = fqName.child(JvmAbi.PACKAGE_CLASS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(environment, compilerDependencies);
|
||||
|
||||
ClassFileFactory factory = analyze();
|
||||
if (factory == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (jar != null) {
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + jar, e);
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ClassFileFactory analyze() {
|
||||
boolean stubs = compilerDependencies.getCompilerSpecialMode().isStubs();
|
||||
GenerationState generationState =
|
||||
KotlinToJVMBytecodeCompiler
|
||||
.analyzeAndGenerate(environment, compilerDependencies, messageCollector, stubs);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
return generationState.getFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public void addToClasspath(File ... paths) {
|
||||
for (File path : paths) {
|
||||
if (!path.exists()) {
|
||||
throw new CompileEnvironmentException("'" + path + "' does not exist");
|
||||
}
|
||||
environment.addToClasspath(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public void addToClasspath(String ... paths) {
|
||||
for (String path : paths) {
|
||||
addToClasspath( new File(path));
|
||||
}
|
||||
}
|
||||
|
||||
public void setStdlib(String stdlib) {
|
||||
File file = new File(stdlib);
|
||||
addToClasspath(file);
|
||||
}
|
||||
|
||||
public JetCoreEnvironment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompilerDependencies getCompilerDependencies() {
|
||||
return compilerDependencies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompileEnvironmentConfiguration {
|
||||
private final JetCoreEnvironment environment;
|
||||
private final CompilerDependencies compilerDependencies;
|
||||
private final MessageCollector messageCollector;
|
||||
|
||||
/**
|
||||
* NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
|
||||
* @see Disposer
|
||||
*/
|
||||
public CompileEnvironmentConfiguration(@NotNull JetCoreEnvironment environment,
|
||||
@NotNull CompilerDependencies compilerDependencies, @NotNull MessageCollector messageCollector) {
|
||||
this.messageCollector = messageCollector;
|
||||
this.compilerDependencies = compilerDependencies;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public JetCoreEnvironment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompilerDependencies getCompilerDependencies() {
|
||||
return compilerDependencies;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MessageCollector getMessageCollector() {
|
||||
return messageCollector;
|
||||
}
|
||||
}
|
||||
@@ -51,9 +51,17 @@ import java.util.jar.*;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompileEnvironmentUtil {
|
||||
public static Disposable createMockDisposable() {
|
||||
return new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getUnpackedRuntimePath() {
|
||||
URL url = CompileEnvironment.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
if (url != null && url.getProtocol().equals("file")) {
|
||||
return new File(url.getPath()).getParentFile().getParentFile();
|
||||
}
|
||||
@@ -62,7 +70,7 @@ public class CompileEnvironmentUtil {
|
||||
|
||||
@Nullable
|
||||
public static File getRuntimeJarPath() {
|
||||
URL url = CompileEnvironment.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
if (url != null && url.getProtocol().equals("jar")) {
|
||||
String path = url.getPath();
|
||||
return new File(path.substring(path.indexOf(":") + 1, path.indexOf("!/")));
|
||||
@@ -187,7 +195,7 @@ public class CompileEnvironmentUtil {
|
||||
}
|
||||
}
|
||||
else {
|
||||
loader = new GeneratedClassLoader(factory, CompileEnvironment.class.getClassLoader());
|
||||
loader = new GeneratedClassLoader(factory, CompileEnvironmentConfiguration.class.getClassLoader());
|
||||
}
|
||||
try {
|
||||
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
|
||||
@@ -301,4 +309,29 @@ public class CompileEnvironmentUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param environment compilation environment to add to
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public static void addToClasspath(JetCoreEnvironment environment, File ... paths) {
|
||||
for (File path : paths) {
|
||||
if (!path.exists()) {
|
||||
throw new CompileEnvironmentException("'" + path + "' does not exist");
|
||||
}
|
||||
environment.addToClasspath(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param environment compilation environment to add to
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public static void addToClasspath(JetCoreEnvironment environment, String ... paths) {
|
||||
for (String path : paths) {
|
||||
addToClasspath(environment, new File(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,13 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiErrorElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.codegen.ClassBuilderFactories;
|
||||
import org.jetbrains.jet.codegen.CompilationErrorHandler;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageLocation;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
@@ -41,12 +42,20 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.jetbrains.jet.plugin.JetMainDetector;
|
||||
import org.jetbrains.jet.utils.Progress;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -56,6 +65,163 @@ import java.util.List;
|
||||
*/
|
||||
public class KotlinToJVMBytecodeCompiler {
|
||||
|
||||
@Nullable
|
||||
public static ClassFileFactory compileModule(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
Module moduleBuilder,
|
||||
String directory
|
||||
) {
|
||||
if (moduleBuilder.getSourceFiles().isEmpty()) {
|
||||
throw new CompileEnvironmentException("No source files where defined");
|
||||
}
|
||||
|
||||
for (String sourceFile : moduleBuilder.getSourceFiles()) {
|
||||
File source = new File(sourceFile);
|
||||
if (!source.isAbsolute()) {
|
||||
source = new File(directory, sourceFile);
|
||||
}
|
||||
|
||||
if (!source.exists()) {
|
||||
throw new CompileEnvironmentException("'" + source + "' does not exist");
|
||||
}
|
||||
|
||||
configuration.getEnvironment().addSources(source.getPath());
|
||||
}
|
||||
for (String classpathRoot : moduleBuilder.getClasspathRoots()) {
|
||||
configuration.getEnvironment().addToClasspath(new File(classpathRoot));
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
return generationState.getFactory();
|
||||
}
|
||||
|
||||
public static boolean compileModuleScript(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
@NotNull String moduleScriptFile,
|
||||
@Nullable String jarPath,
|
||||
@Nullable String outputDir,
|
||||
boolean jarRuntime) {
|
||||
List<Module> modules = CompileEnvironmentUtil.loadModuleScript(moduleScriptFile, configuration.getMessageCollector());
|
||||
|
||||
if (modules == null) {
|
||||
throw new CompileEnvironmentException("Module script " + moduleScriptFile + " compilation failed");
|
||||
}
|
||||
|
||||
if (modules.isEmpty()) {
|
||||
throw new CompileEnvironmentException("No modules where defined by " + moduleScriptFile);
|
||||
}
|
||||
|
||||
final String directory = new File(moduleScriptFile).getParent();
|
||||
for (Module moduleBuilder : modules) {
|
||||
// TODO: this should be done only once for the environment
|
||||
if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
|
||||
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
|
||||
}
|
||||
ClassFileFactory moduleFactory = KotlinToJVMBytecodeCompiler.compileModule(configuration, moduleBuilder, directory);
|
||||
if (moduleFactory == null) {
|
||||
return false;
|
||||
}
|
||||
if (outputDir != null) {
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(moduleFactory, outputDir);
|
||||
}
|
||||
else {
|
||||
String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean compileBunchOfSources(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
String jar,
|
||||
String outputDir,
|
||||
boolean includeRuntime
|
||||
) {
|
||||
FqName mainClass = null;
|
||||
for (JetFile file : configuration.getEnvironment().getSourceFiles()) {
|
||||
if (JetMainDetector.hasMain(file.getDeclarations())) {
|
||||
FqName fqName = JetPsiUtil.getFQName(file);
|
||||
mainClass = fqName.child(JvmAbi.PACKAGE_CLASS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClassFileFactory factory = generationState.getFactory();
|
||||
if (jar != null) {
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + jar, e);
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean compileBunchOfSources(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
|
||||
configuration.getEnvironment().addSources(sourceFileOrDir);
|
||||
|
||||
return compileBunchOfSources(configuration, jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
public static boolean compileBunchOfSourceDirectories(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
List<String> sources, String jar, String outputDir, boolean includeRuntime) {
|
||||
for (String source : sources) {
|
||||
configuration.getEnvironment().addSources(source);
|
||||
}
|
||||
|
||||
return compileBunchOfSources(configuration, jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassLoader compileText(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
String code) {
|
||||
configuration.getEnvironment().addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
return new GeneratedClassLoader(generationState.getFactory());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GenerationState analyzeAndGenerate(CompileEnvironmentConfiguration configuration) {
|
||||
return analyzeAndGenerate(configuration.getEnvironment(), configuration.getCompilerDependencies(), configuration.getMessageCollector(), configuration.getCompilerDependencies().getCompilerSpecialMode().isStubs());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GenerationState analyzeAndGenerate(
|
||||
JetCoreEnvironment environment,
|
||||
|
||||
Reference in New Issue
Block a user