Introducing KotlinPaths to impose some discipline on compiler/library location

This commit is contained in:
Andrey Breslav
2012-11-21 18:16:09 +04:00
parent 4ee76a6649
commit 4ed07cd9ae
20 changed files with 244 additions and 164 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.jet.codegen.CompilationException;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
@@ -60,9 +61,10 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
@Override
@NotNull
protected ExitCode doExecute(K2JVMCompilerArguments arguments, PrintingMessageCollector messageCollector, Disposable rootDisposable) {
KotlinPaths paths = PathUtil.getKotlinPathsForCompiler();
CompilerConfiguration configuration = new CompilerConfiguration();
configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(arguments));
configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(arguments));
configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(paths, arguments));
configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(paths, arguments));
final List<String> argumentsSourceDirs = arguments.getSourceDirs();
if (!arguments.script &&
@@ -124,7 +126,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
if (arguments.module != null) {
boolean oldVerbose = messageCollector.isVerbose();
messageCollector.setVerbose(false);
List<Module> modules = CompileEnvironmentUtil.loadModuleScript(arguments.module, messageCollector);
List<Module> modules = CompileEnvironmentUtil.loadModuleScript(paths, arguments.module, messageCollector);
messageCollector.setVerbose(oldVerbose);
File directory = new File(arguments.module).getParentFile();
noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules,
@@ -134,7 +136,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
else if (arguments.script) {
List<String> scriptArgs = arguments.freeArgs.subList(1, arguments.freeArgs.size());
JetCoreEnvironment environment = new JetCoreEnvironment(rootDisposable, configuration);
noErrors = KotlinToJVMBytecodeCompiler.compileAndExecuteScript(environment, scriptArgs);
noErrors = KotlinToJVMBytecodeCompiler.compileAndExecuteScript(paths, environment, scriptArgs);
}
else {
JetCoreEnvironment environment = new JetCoreEnvironment(rootDisposable, configuration);
@@ -180,13 +182,13 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
}
@NotNull
private static List<File> getClasspath(@NotNull K2JVMCompilerArguments arguments) {
private static List<File> getClasspath(@NotNull KotlinPaths paths, @NotNull K2JVMCompilerArguments arguments) {
List<File> classpath = Lists.newArrayList();
if (!arguments.noJdk) {
classpath.add(PathUtil.findRtJar());
}
if (!arguments.noStdlib) {
classpath.add(PathUtil.getDefaultRuntimePath());
classpath.add(paths.getRuntimePath());
}
if (arguments.classpath != null) {
for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.classpath)) {
@@ -197,10 +199,10 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
}
@NotNull
private static List<File> getAnnotationsPath(@NotNull K2JVMCompilerArguments arguments) {
private static List<File> getAnnotationsPath(@NotNull KotlinPaths paths, @NotNull K2JVMCompilerArguments arguments) {
List<File> annotationsPath = Lists.newArrayList();
if (!arguments.noJdkAnnotations) {
annotationsPath.add(PathUtil.getJdkAnnotationsPath());
annotationsPath.add(paths.getJdkAnnotationsPath());
}
if (arguments.annotations != null) {
for (String element : Splitter.on(File.pathSeparatorChar).split(arguments.annotations)) {
@@ -35,6 +35,7 @@ import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
@@ -81,7 +82,7 @@ public class CompileEnvironmentUtil {
}
@NotNull
public static List<Module> loadModuleScript(String moduleScriptFile, MessageCollector messageCollector) {
public static List<Module> loadModuleScript(KotlinPaths paths, String moduleScriptFile, MessageCollector messageCollector) {
Disposable disposable = new Disposable() {
@Override
public void dispose() {
@@ -89,13 +90,13 @@ public class CompileEnvironmentUtil {
}
};
CompilerConfiguration configuration = new CompilerConfiguration();
File defaultRuntimePath = PathUtil.getDefaultRuntimePath();
if (defaultRuntimePath != null) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, defaultRuntimePath);
File runtimePath = paths.getRuntimePath();
if (runtimePath.exists()) {
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, runtimePath);
}
configuration.add(JVMConfigurationKeys.CLASSPATH_KEY, PathUtil.findRtJar());
File jdkAnnotationsPath = PathUtil.getJdkAnnotationsPath();
if (jdkAnnotationsPath != null) {
File jdkAnnotationsPath = paths.getJdkAnnotationsPath();
if (jdkAnnotationsPath.exists()) {
configuration.add(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, jdkAnnotationsPath);
}
configuration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, moduleScriptFile);
@@ -109,7 +110,7 @@ public class CompileEnvironmentUtil {
loadModuleScriptText(moduleScriptFile));
}
List<Module> modules = runDefineModules(moduleScriptFile, generationState.getFactory());
List<Module> modules = runDefineModules(paths, moduleScriptFile, generationState.getFactory());
Disposer.dispose(disposable);
@@ -123,10 +124,10 @@ public class CompileEnvironmentUtil {
return modules;
}
private static List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
File stdlibJar = PathUtil.getDefaultRuntimePath();
private static List<Module> runDefineModules(KotlinPaths paths, String moduleFile, ClassFileFactory factory) {
File stdlibJar = paths.getRuntimePath();
GeneratedClassLoader loader;
if (stdlibJar != null) {
if (stdlibJar.exists()) {
try {
loader = new GeneratedClassLoader(factory, new URLClassLoader(new URL[]{stdlibJar.toURI().toURL()},
AllModules.class.getClassLoader()));
@@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.plugin.JetMainDetector;
import org.jetbrains.jet.utils.ExceptionUtils;
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
@@ -222,9 +223,10 @@ public class KotlinToJVMBytecodeCompiler {
}
public static boolean compileAndExecuteScript(
@NotNull KotlinPaths paths,
@NotNull JetCoreEnvironment environment,
@NotNull List<String> scriptArgs) {
Class<?> scriptClass = compileScript(environment, null);
Class<?> scriptClass = compileScript(paths, environment, null);
if(scriptClass == null)
return false;
@@ -240,8 +242,8 @@ public class KotlinToJVMBytecodeCompiler {
return true;
}
public static Class<?> compileScript(
@NotNull JetCoreEnvironment environment, ClassLoader parentLoader) {
private static Class<?> compileScript(
@NotNull KotlinPaths paths, @NotNull JetCoreEnvironment environment, @Nullable ClassLoader parentLoader) {
GenerationState generationState = analyzeAndGenerate(environment);
if (generationState == null) {
@@ -253,7 +255,7 @@ public class KotlinToJVMBytecodeCompiler {
try {
GeneratedClassLoader classLoader = new GeneratedClassLoader(factory, new URLClassLoader(new URL[]{
// TODO: add all classpath
PathUtil.getDefaultRuntimePath().toURI().toURL()
paths.getRuntimePath().toURI().toURL()
},
parentLoader == null ? AllModules.class.getClassLoader() : parentLoader));
JetFile scriptFile = environment.getSourceFiles().get(0);
@@ -364,8 +366,9 @@ public class KotlinToJVMBytecodeCompiler {
}
public static Class compileScript(
ClassLoader parentLoader,
String scriptPath,
@NotNull ClassLoader parentLoader,
@NotNull KotlinPaths paths,
@NotNull String scriptPath,
@Nullable List<AnalyzerScriptParameter> scriptParameters,
@Nullable List<JetScriptDefinition> scriptDefinitions) {
final MessageRenderer messageRenderer = MessageRenderer.PLAIN;
@@ -377,7 +380,7 @@ public class KotlinToJVMBytecodeCompiler {
compilerConfiguration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(parentLoader));
compilerConfiguration.add(JVMConfigurationKeys.CLASSPATH_KEY, PathUtil.findRtJar());
compilerConfiguration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, Collections.singletonList(
PathUtil.getJdkAnnotationsPath()));
paths.getJdkAnnotationsPath()));
compilerConfiguration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, scriptPath);
compilerConfiguration.addAll(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY,
scriptDefinitions != null ? scriptDefinitions : Collections.<JetScriptDefinition>emptyList());
@@ -387,7 +390,7 @@ public class KotlinToJVMBytecodeCompiler {
try {
JetScriptDefinitionProvider.getInstance(environment.getProject()).markFileAsScript(environment.getSourceFiles().get(0));
return compileScript(environment, parentLoader);
return compileScript(paths, environment, parentLoader);
}
catch (CompilationException e) {
messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e),
@@ -1,5 +1,7 @@
package Hello
fun main(args : Array<String>) {
System.out.println("Hello!")
for (s in arrayList("a"))
println("Hello, $s!")
}
@@ -1,2 +1,2 @@
OUT Hello!
OUT Hello, a!
Return code: 0
@@ -25,10 +25,11 @@ import static junit.framework.Assert.assertEquals;
public class AntTaskTest extends KotlinIntegrationTestBase {
@Test
public void antTaskJvm() throws Exception {
final String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
String jar = tmpdir.getTmpDir().getAbsolutePath() + File.separator + "hello.jar";
String runtime = new File("dist/kotlinc/lib/kotlin-runtime.jar").getAbsolutePath();
assertEquals("compilation failed", 0, runAnt("build.log", "build.xml"));
runJava("hello.run", "-cp", jar, "Hello.namespace");
runJava("hello.run", "-cp", jar + ":" + runtime, "Hello.namespace");
}
@Override
@@ -49,6 +49,7 @@ import org.jetbrains.jet.test.TestMetadata;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.SlicedMap;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import org.jetbrains.jet.utils.KotlinPaths;
import org.junit.Assert;
import javax.tools.*;
@@ -469,4 +470,8 @@ public class JetTestUtils {
private static String getSimpleName(String generatorClassFqName) {
return generatorClassFqName.substring(generatorClassFqName.lastIndexOf(".") + 1);
}
public static KotlinPaths getPathsForTests() {
return new KotlinPaths(new File("dist/kotlinc"));
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.jet.cli.jvm;
import com.intellij.openapi.util.io.FileUtil;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.cli.common.CLICompiler;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
@@ -170,7 +171,7 @@ public class CliTest {
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.ktscript", scriptParameters, null);
.compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.ktscript", scriptParameters, null);
Assert.assertNotNull(aClass);
try {
@@ -187,7 +188,7 @@ public class CliTest {
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.kt", scriptParameters, null);
.compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.kt", scriptParameters, null);
Assert.assertNotNull(aClass);
try {
@@ -205,7 +206,7 @@ public class CliTest {
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.fib.kt", null, Arrays.asList(new JetScriptDefinition(".fib.kt",scriptParameters)));
.compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.fib.kt", null, Arrays.asList(new JetScriptDefinition(".fib.kt",scriptParameters)));
Assert.assertNotNull(aClass);
try {
@@ -37,7 +37,6 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.jetbrains.jet.test.TestCaseWithTmpdir;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.io.IOException;
@@ -64,14 +63,14 @@ public class AnnotationJavaDescriptorResolverTest extends TestCaseWithTmpdir {
StringBuilder builder = new StringBuilder(tmpdir.getAbsolutePath());
builder.append(File.pathSeparator);
File runtimePath = PathUtil.getDefaultRuntimePath();
if (runtimePath != null) {
File runtimePath = JetTestUtils.getPathsForTests().getRuntimePath();
if (runtimePath.exists()) {
builder.append(runtimePath.getAbsolutePath());
builder.append(File.pathSeparator);
}
File annotationsPath = PathUtil.getJdkAnnotationsPath();
if (annotationsPath != null) {
File annotationsPath = JetTestUtils.getPathsForTests().getJdkAnnotationsPath();
if (annotationsPath.exists()) {
builder.append(annotationsPath.getAbsolutePath());
}
@@ -0,0 +1,65 @@
/*
* 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.utils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class KotlinPaths {
// kotlinc directory
private final File homePath;
public KotlinPaths(@NotNull File homePath) {
this.homePath = homePath;
}
@NotNull
public File getHomePath() {
return homePath;
}
@NotNull
public File getLibPath() {
return new File(homePath, "lib");
}
@NotNull
public File getRuntimePath() {
return getLibraryFile("kotlin-runtime.jar");
}
@NotNull
public File getJdkAnnotationsPath() {
return getLibraryFile(PathUtil.JDK_ANNOTATIONS_JAR);
}
@NotNull
public File getJsLibJsPath() {
return getLibraryFile(PathUtil.JS_LIB_JS_NAME);
}
@NotNull
public File getJsLibJarPath() {
return getLibraryFile(PathUtil.JS_LIB_JAR_NAME);
}
@NotNull
private File getLibraryFile(@NotNull String fileName) {
return new File(getLibPath(), fileName);
}
}
@@ -24,7 +24,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -34,87 +33,86 @@ public class PathUtil {
public static final String JS_LIB_JS_NAME = "kotlinEcma3.js";
public static final String JDK_ANNOTATIONS_JAR = "kotlin-jdk-annotations.jar";
private static final File NO_PATH = new File("<no_path>");
private PathUtil() {}
public static File getDefaultCompilerPath() {
File plugin_jar_path = new File(getJarPathForClass(PathUtil.class));
if (!plugin_jar_path.exists()) return null;
if (plugin_jar_path.getName().equals("kotlin-plugin.jar")) {
File lib = plugin_jar_path.getParentFile();
File pluginHome = lib.getParentFile();
File answer = new File(pluginHome, "kotlinc");
return answer.exists() ? answer : null;
}
if (plugin_jar_path.getName().equals("kotlin-compiler.jar")) {
File lib = plugin_jar_path.getParentFile();
File answer = lib.getParentFile();
return answer.exists() ? answer : null;
}
File current = new File("").getAbsoluteFile(); // CWD
do {
File atDevHome = new File(current, "dist/kotlinc");
if (atDevHome.exists()) return atDevHome;
current = current.getParentFile();
} while (current != null);
return null;
}
public static File getCompilerPathForJpsPlugin() {
File plugin_jar_path = new File(getJarPathForClass(PathUtil.class));
if (!plugin_jar_path.exists()) return null;
if (plugin_jar_path.getName().equals("kotlin-jps-plugin.jar")) {
File pluginHome = plugin_jar_path.getParentFile().getParentFile().getParentFile();
File answer = new File(pluginHome, "kotlinc");
return answer.exists() ? answer : null;
}
return null;
}
@Nullable
public static File getDefaultRuntimePath() {
return getFilePackedIntoLib("kotlin-runtime.jar");
}
@Nullable
public static File getDefaultJsLibJsPath() {
return getFilePackedIntoLib(JS_LIB_JS_NAME);
}
@Nullable
public static File getDefaultJsLibJarPath() {
return getFilePackedIntoLib(JS_LIB_JAR_NAME);
}
@Nullable
private static File getFilePackedIntoLib(@NotNull String filePathFromLib) {
File compilerPath = getDefaultCompilerPath();
if (compilerPath == null) return null;
File answer = new File(compilerPath, "lib/" + filePathFromLib);
return answer.exists() ? answer : null;
}
@Nullable
public static File getJdkAnnotationsPath() {
return getFilePackedIntoLib(JDK_ANNOTATIONS_JAR);
@NotNull
public static KotlinPaths getKotlinPathsForIdeaPlugin() {
return new KotlinPaths(getCompilerPathForIdeaPlugin());
}
@NotNull
public static String getJarPathForClass(@NotNull Class aClass) {
public static KotlinPaths getKotlinPathsForJpsPlugin() {
return new KotlinPaths(getCompilerPathForJpsPlugin());
}
@NotNull
public static KotlinPaths getKotlinPathsForCompiler() {
if (!getPathUtilJar().isFile()) {
// Not running from a jar, i.e. it is it must be a unit test
return getKotlinPathsForDistDirectory();
}
return new KotlinPaths(getCompilerPathForCompilerJar());
}
@NotNull
public static KotlinPaths getKotlinPathsForDistDirectory() {
return new KotlinPaths(new File("dist/kotlinc"));
}
@NotNull
private static File getCompilerPathForCompilerJar() {
File jar = getPathUtilJar();
if (!jar.exists()) return NO_PATH;
if (jar.getName().equals("kotlin-compiler.jar")) {
File lib = jar.getParentFile();
return lib.getParentFile();
}
return NO_PATH;
}
@NotNull
private static File getCompilerPathForJpsPlugin() {
File jar = getPathUtilJar();
if (!jar.exists()) return NO_PATH;
if (jar.getName().equals("kotlin-jps-plugin.jar")) {
File pluginHome = jar.getParentFile().getParentFile().getParentFile();
return new File(pluginHome, "kotlinc");
}
return NO_PATH;
}
@NotNull
private static File getCompilerPathForIdeaPlugin() {
File jar = getPathUtilJar();
if (!jar.exists()) return NO_PATH;
if (jar.getName().equals("kotlin-plugin.jar")) {
File lib = jar.getParentFile();
File pluginHome = lib.getParentFile();
return new File(pluginHome, "kotlinc");
}
return NO_PATH;
}
private static File getPathUtilJar() {
return getJarPathForClass(PathUtil.class);
}
@NotNull
public static File getJarPathForClass(@NotNull Class aClass) {
String resourceRoot = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class");
return new File(resourceRoot).getAbsoluteFile().getAbsolutePath();
return new File(resourceRoot).getAbsoluteFile();
}
@NotNull