private static List<File> kompilerClasspath(File kotlinHome, CompileContext context) { File libs = new File(kotlinHome, "lib"); if (!libs.exists() || libs.isFile()) { context.addMessage( ERROR, "Broken compiler at '" + libs.getAbsolutePath() + "'. Make sure plugin is properly installed", "", -1, -1); return Collections.emptyList(); } ArrayList<File> answer = new ArrayList<File>(); File[] jars = libs.listFiles(); if (jars != null) { for (File jar : jars) { if (jar.isFile() && jar.getName().endsWith(".jar")) { answer.add(jar); } } } return answer; }
private static void runOutOfProcess( CompileContext compileContext, VirtualFile outputDir, File kotlinHome, File scriptFile) { final SimpleJavaParameters params = new SimpleJavaParameters(); params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome())); params.setMainClass("org.jetbrains.jet.cli.KotlinCompiler"); params.getProgramParametersList().add("-module", scriptFile.getAbsolutePath()); params.getProgramParametersList().add("-output", path(outputDir)); params.getProgramParametersList().add("-tags"); for (File jar : kompilerClasspath(kotlinHome, compileContext)) { params.getClassPath().add(jar); } params.getVMParametersList().addParametersString("-Djava.awt.headless=true -Xmx512m"); // params.getVMParametersList().addParametersString("-agentlib:yjpagent=sampling"); Sdk sdk = params.getJdk(); final GeneralCommandLine commandLine = JdkUtil.setupJVMCommandLine( ((JavaSdkType) sdk.getSdkType()).getVMExecutablePath(sdk), params, false); compileContext.addMessage( INFORMATION, "Invoking out-of-process compiler with arguments: " + commandLine, "", -1, -1); try { final OSProcessHandler processHandler = new OSProcessHandler(commandLine.createProcess(), commandLine.getCommandLineString()) { @Override public Charset getCharset() { return commandLine.getCharset(); } }; ProcessAdapter processListener = createProcessListener(compileContext); processHandler.addProcessListener(processListener); processHandler.startNotify(); processHandler.waitFor(); } catch (Exception e) { compileContext.addMessage(ERROR, "[Internal Error] " + e.getLocalizedMessage(), "", -1, -1); return; } }
private static int execInProcess( File kotlinHome, VirtualFile outputDir, File scriptFile, PrintStream out, CompileContext context) { URLClassLoader loader = getOrCreateClassloader(kotlinHome, context); try { String compilerClassName = "org.jetbrains.jet.cli.KotlinCompiler"; Class<?> kompiler = Class.forName(compilerClassName, true, loader); Method exec = kompiler.getDeclaredMethod("exec", PrintStream.class, String[].class); String[] arguments = { "-module", scriptFile.getAbsolutePath(), "-output", path(outputDir), "-tags" }; context.addMessage(INFORMATION, "Using kotlinHome=" + kotlinHome, "", -1, -1); context.addMessage( INFORMATION, "Invoking in-process compiler " + compilerClassName + " with arguments " + Arrays.asList(arguments), "", -1, -1); Object rc = exec.invoke(null, out, arguments); if (rc instanceof Integer) { return ((Integer) rc).intValue(); } else { throw new IllegalStateException("Unexpected return: " + rc); } } catch (Throwable e) { LOG.error(e); return -1; } }
private void doCompile( CompileContext compileContext, Chunk<Module> moduleChunk, List<VirtualFile> files, Module module, boolean tests) { if (files.isEmpty()) return; VirtualFile mainOutput = compileContext.getModuleOutputDirectory(module); final VirtualFile outputDir = tests ? compileContext.getModuleOutputDirectoryForTests(module) : mainOutput; if (outputDir == null) { compileContext.addMessage(ERROR, "[Internal Error] No output directory", "", -1, -1); return; } File kotlinHome = PathUtil.getDefaultCompilerPath(); if (kotlinHome == null) { compileContext.addMessage( ERROR, "Cannot find kotlinc home. Make sure plugin is properly installed", "", -1, -1); return; } ModuleChunk chunk = new ModuleChunk( (CompileContextEx) compileContext, moduleChunk, Collections.<Module, List<VirtualFile>>emptyMap()); String moduleName = moduleChunk.getNodes().iterator().next().getName(); // Filter the output we are writing to Set<VirtualFile> outputDirectoriesToFilter = Sets.newHashSet(compileContext.getModuleOutputDirectoryForTests(module)); if (!tests) { outputDirectoriesToFilter.add(compileContext.getModuleOutputDirectory(module)); } CharSequence script = generateModuleScript( moduleName, chunk, files, tests, mainOutput, outputDirectoriesToFilter); File scriptFile = new File(path(outputDir), "script.kts"); try { FileUtil.writeToFile(scriptFile, script.toString()); } catch (IOException e) { compileContext.addMessage( ERROR, "[Internal Error] Cannot write script to " + scriptFile.getAbsolutePath(), "", -1, -1); return; } if (RUN_OUT_OF_PROCESS) { runOutOfProcess(compileContext, outputDir, kotlinHome, scriptFile); } else { runInProcess(compileContext, outputDir, kotlinHome, scriptFile); } // compileContext.addMessage(INFORMATION, "Generated module script:\n" + // script.toString(), "file://" + path(mainOutput), 0, 1); }