Пример #1
0
  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;
  }
Пример #2
0
  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;
    }
  }
Пример #3
0
  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;
    }
  }
Пример #4
0
  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);
  }