diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 5059abe55fa..4f0bab2e07a 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -30,35 +30,29 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.CompilerPlugin; import org.jetbrains.jet.cli.common.CompilerPluginContext; -import org.jetbrains.jet.cli.common.messages.*; +import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport; +import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.cli.jvm.JVMConfigurationKeys; import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.Progress; import org.jetbrains.jet.config.CommonConfigurationKeys; import org.jetbrains.jet.config.CompilerConfiguration; -import org.jetbrains.jet.lang.parsing.JetScriptDefinition; -import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; -import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.ScriptNameUtil; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; 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; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; public class KotlinToJVMBytecodeCompiler { @@ -203,16 +197,16 @@ public class KotlinToJVMBytecodeCompiler { } } - public static boolean compileAndExecuteScript( + public static void compileAndExecuteScript( @NotNull KotlinPaths paths, @NotNull JetCoreEnvironment environment, - @NotNull List scriptArgs) { - Class scriptClass = compileScript(paths, environment, null); - if(scriptClass == null) - return false; + @NotNull List scriptArgs + ) { + Class scriptClass = compileScript(paths, environment); + if (scriptClass == null) return; try { - scriptClass.getConstructor(String[].class).newInstance(new Object[]{scriptArgs.toArray(new String[0])}); + scriptClass.getConstructor(String[].class).newInstance(new Object[]{scriptArgs.toArray(new String[scriptArgs.size()])}); } catch (RuntimeException e) { throw e; @@ -220,29 +214,25 @@ public class KotlinToJVMBytecodeCompiler { catch (Exception e) { throw new RuntimeException("Failed to evaluate script: " + e, e); } - return true; } - private static Class compileScript( - @NotNull KotlinPaths paths, @NotNull JetCoreEnvironment environment, @Nullable ClassLoader parentLoader) { - - GenerationState generationState = analyzeAndGenerate(environment); - if (generationState == null) { + @Nullable + public static Class compileScript(@NotNull KotlinPaths paths, @NotNull JetCoreEnvironment environment) { + GenerationState state = analyzeAndGenerate(environment); + if (state == null) { return null; } GeneratedClassLoader classLoader = null; try { - ClassFileFactory factory = generationState.getFactory(); - classLoader = new GeneratedClassLoader(factory, - new URLClassLoader(new URL[] { - // TODO: add all classpath - paths.getRuntimePath().toURI().toURL() - }, - parentLoader == null ? AllModules.class.getClassLoader() : parentLoader)); + classLoader = new GeneratedClassLoader(state.getFactory(), + new URLClassLoader(new URL[] { + // TODO: add all classpath + paths.getRuntimePath().toURI().toURL() + }, AllModules.class.getClassLoader()) + ); - JetFile scriptFile = environment.getSourceFiles().get(0); - return classLoader.loadClass(ScriptNameUtil.classNameForScript(scriptFile)); + return classLoader.loadClass(ScriptNameUtil.classNameForScript(environment.getSourceFiles().get(0))); } catch (Exception e) { throw new RuntimeException("Failed to evaluate script: " + e, e); @@ -251,14 +241,12 @@ public class KotlinToJVMBytecodeCompiler { if (classLoader != null) { classLoader.dispose(); } - generationState.destroy(); + state.destroy(); } } @Nullable - public static GenerationState analyzeAndGenerate( - JetCoreEnvironment environment - ) { + public static GenerationState analyzeAndGenerate(@NotNull JetCoreEnvironment environment) { AnalyzeExhaust exhaust = analyze(environment); if (exhaust == null) { @@ -271,7 +259,7 @@ public class KotlinToJVMBytecodeCompiler { } @Nullable - private static AnalyzeExhaust analyze(final JetCoreEnvironment environment) { + private static AnalyzeExhaust analyze(@NotNull final JetCoreEnvironment environment) { AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport( environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)); analyzerWithCompilerReport.analyzeAndReport( @@ -296,10 +284,7 @@ public class KotlinToJVMBytecodeCompiler { } @NotNull - private static GenerationState generate( - JetCoreEnvironment environment, - AnalyzeExhaust exhaust - ) { + private static GenerationState generate(@NotNull JetCoreEnvironment environment, @NotNull AnalyzeExhaust exhaust) { Project project = environment.getProject(); CompilerConfiguration configuration = environment.getConfiguration(); GenerationState generationState = new GenerationState( @@ -316,79 +301,4 @@ public class KotlinToJVMBytecodeCompiler { } return generationState; } - - public static Class compileScript( - @NotNull ClassLoader parentLoader, - @NotNull KotlinPaths paths, - @NotNull String scriptPath, - @Nullable List scriptParameters, - @Nullable List scriptDefinitions) { - MessageRenderer messageRenderer = MessageRenderer.PLAIN; - GroupingMessageCollector messageCollector = new GroupingMessageCollector(new PrintingMessageCollector(System.err, messageRenderer, false)); - Disposable rootDisposable = Disposer.newDisposable(); - try { - CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); - compilerConfiguration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); - compilerConfiguration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(parentLoader)); - compilerConfiguration.add(JVMConfigurationKeys.CLASSPATH_KEY, PathUtil.findRtJar()); - compilerConfiguration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, Collections.singletonList( - paths.getJdkAnnotationsPath())); - compilerConfiguration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, scriptPath); - compilerConfiguration.addAll(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY, - scriptDefinitions != null ? scriptDefinitions : Collections.emptyList()); - compilerConfiguration.put(JVMConfigurationKeys.SCRIPT_PARAMETERS, scriptParameters); - - JetCoreEnvironment environment = JetCoreEnvironment.createForProduction(rootDisposable, compilerConfiguration); - - try { - JetScriptDefinitionProvider.getInstance(environment.getProject()).markFileAsScript(environment.getSourceFiles().get(0)); - return compileScript(paths, environment, parentLoader); - } - catch (CompilationException e) { - messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e), - MessageUtil.psiElementToMessageLocation(e.getElement())); - return null; - } - catch (Throwable t) { - MessageCollectorUtil.reportException(messageCollector, t); - return null; - } - - } - finally { - messageCollector.flush(); - Disposer.dispose(rootDisposable); - } - } - - private static Collection getClasspath(ClassLoader loader) { - return getClasspath(loader, new LinkedList()); - } - - private static Collection getClasspath(ClassLoader loader, LinkedList files) { - ClassLoader parent = loader.getParent(); - if(parent != null) - getClasspath(parent, files); - - if(loader instanceof URLClassLoader) { - for (URL url : ((URLClassLoader) loader).getURLs()) { - String urlFile = url.getFile(); - - if (urlFile.contains("%")) { - try { - urlFile = url.toURI().getPath(); - } - catch (URISyntaxException e) { - throw ExceptionUtils.rethrow(e); - } - } - - File file = new File(urlFile); - if(file.exists() && (file.isDirectory() || file.getName().endsWith(".jar"))) { - files.add(file); - } - } - } - return files; - } } diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 603cf8b7fd9..0415ba8cc58 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -65,8 +65,6 @@ 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.jetbrains.jet.utils.KotlinPathsFromHomeDir; import org.jetbrains.jet.utils.PathUtil; import org.junit.Assert; @@ -626,10 +624,6 @@ public class JetTestUtils { return generatorClassFqName.substring(generatorClassFqName.lastIndexOf(".") + 1); } - public static KotlinPaths getPathsForTests() { - return new KotlinPathsFromHomeDir(new File("dist/kotlinc")); - } - public static JetFile loadJetFile(@NotNull Project project, @NotNull File ioFile) throws IOException { String text = FileUtil.loadFile(ioFile); return JetPsiFactory.createPhysicalFile(project, ioFile.getName(), text); diff --git a/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java b/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java index 009797719ac..f1f66c1854b 100644 --- a/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java +++ b/compiler/tests/org/jetbrains/jet/cli/jvm/CliTest.java @@ -16,14 +16,26 @@ package org.jetbrains.jet.cli.jvm; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import junit.framework.Assert; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.ConfigurationKind; import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.TestJdkKind; import org.jetbrains.jet.cli.common.CLICompiler; +import org.jetbrains.jet.cli.common.CLIConfigurationKeys; import org.jetbrains.jet.cli.common.ExitCode; +import org.jetbrains.jet.cli.common.messages.*; import org.jetbrains.jet.cli.js.K2JSCompiler; +import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler; +import org.jetbrains.jet.codegen.CompilationException; +import org.jetbrains.jet.config.CommonConfigurationKeys; +import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.lang.parsing.JetScriptDefinition; +import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider; import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -31,6 +43,8 @@ import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.ref.JetTypeName; import org.jetbrains.jet.test.Tmpdir; import org.jetbrains.jet.utils.ExceptionUtils; +import org.jetbrains.jet.utils.KotlinPaths; +import org.jetbrains.jet.utils.KotlinPathsFromHomeDir; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -38,8 +52,8 @@ import org.junit.rules.TestName; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintStream; -import java.util.Arrays; -import java.util.LinkedList; +import java.util.Collections; +import java.util.List; public class CliTest { @@ -65,6 +79,46 @@ public class CliTest { } } + @Nullable + private static Class compileScript( + @NotNull String scriptPath, + @Nullable List scriptParameters, + @NotNull List scriptDefinitions + ) { + KotlinPaths paths = new KotlinPathsFromHomeDir(new File("dist/kotlinc")); + GroupingMessageCollector messageCollector = + new GroupingMessageCollector(new PrintingMessageCollector(System.err, MessageRenderer.PLAIN, false)); + Disposable rootDisposable = Disposer.newDisposable(); + try { + CompilerConfiguration configuration = + JetTestUtils.compilerConfigurationForTests(ConfigurationKind.JDK_AND_ANNOTATIONS, TestJdkKind.MOCK_JDK); + configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector); + configuration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, "compiler/testData/cli/" + scriptPath); + configuration.addAll(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY, scriptDefinitions); + configuration.put(JVMConfigurationKeys.SCRIPT_PARAMETERS, scriptParameters); + + JetCoreEnvironment environment = JetCoreEnvironment.createForProduction(rootDisposable, configuration); + + try { + JetScriptDefinitionProvider.getInstance(environment.getProject()).markFileAsScript(environment.getSourceFiles().get(0)); + return KotlinToJVMBytecodeCompiler.compileScript(paths, environment); + } + catch (CompilationException e) { + messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e), + MessageUtil.psiElementToMessageLocation(e.getElement())); + return null; + } + catch (Throwable t) { + MessageCollectorUtil.reportException(messageCollector, t); + return null; + } + } + finally { + messageCollector.flush(); + Disposer.dispose(rootDisposable); + } + } + private void executeCompilerCompareOutput(@NotNull CLICompiler compiler, @NotNull String[] args) { String actual = executeCompilerGrabOutput(compiler, args) .replace(new File("compiler/testData/cli/").getAbsolutePath(), "$TESTDATA_DIR$") @@ -168,54 +222,30 @@ public class CliTest { } @Test - public void testScript() { - LinkedList scriptParameters = new LinkedList(); - AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int")); - scriptParameters.add(parameter); - Class aClass = KotlinToJVMBytecodeCompiler - .compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.ktscript", scriptParameters, null); + public void testScript() throws Exception { + Class aClass = compileScript("fib.ktscript", numIntParam(), Collections.emptyList()); Assert.assertNotNull(aClass); - - try { - aClass.getConstructor(int.class).newInstance(4); - } - catch (Exception e) { - throw new RuntimeException(e); - } + aClass.getConstructor(int.class).newInstance(4); } @Test - public void testScriptStandardExt() { - LinkedList scriptParameters = new LinkedList(); - AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int")); - scriptParameters.add(parameter); - Class aClass = KotlinToJVMBytecodeCompiler - .compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.kt", scriptParameters, null); + public void testScriptStandardExt() throws Exception { + Class aClass = compileScript("fib.kt", numIntParam(), Collections.emptyList()); Assert.assertNotNull(aClass); - - try { - aClass.getConstructor(int.class).newInstance(4); - } - catch (Exception e) { - throw new RuntimeException(e); - } + aClass.getConstructor(int.class).newInstance(4); } @Test - public void testScriptWithScriptDefinition() { - LinkedList scriptParameters = new LinkedList(); - AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int")); - scriptParameters.add(parameter); - Class aClass = KotlinToJVMBytecodeCompiler - .compileScript(getClass().getClassLoader(), JetTestUtils.getPathsForTests(), "compiler/testData/cli/fib.fib.kt", null, Arrays.asList(new JetScriptDefinition(".fib.kt",scriptParameters))); + public void testScriptWithScriptDefinition() throws Exception { + Class aClass = compileScript("fib.fib.kt", null, + Collections.singletonList(new JetScriptDefinition(".fib.kt", numIntParam()))); Assert.assertNotNull(aClass); + aClass.getConstructor(int.class).newInstance(4); + } - try { - aClass.getConstructor(int.class).newInstance(4); - } - catch (Exception e) { - throw new RuntimeException(e); - } + @NotNull + private static List numIntParam() { + return Collections.singletonList(new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"))); } @Test