Exemple #1
0
  @Nullable
  private ScriptDescriptor doAnalyze(
      @NotNull JetFile psiFile, @NotNull MessageCollector messageCollector) {
    WritableScope scope =
        new WritableScopeImpl(
            JetScope.EMPTY,
            module,
            new TraceBasedRedeclarationHandler(trace),
            "Root scope in analyzePackage");

    scope.changeLockLevel(WritableScope.LockLevel.BOTH);

    // Import a scope that contains all top-level packages that come from dependencies
    // This makes the packages visible at all, does not import themselves
    scope.importScope(module.getPackage(FqName.ROOT).getMemberScope());

    if (lastLineScope != null) {
      scope.importScope(lastLineScope);
    }

    scope.changeLockLevel(WritableScope.LockLevel.READING);

    // dummy builder is used because "root" is module descriptor,
    // packages added to module explicitly in
    injector
        .getTopDownAnalyzer()
        .doProcess(
            topDownAnalysisContext,
            scope,
            new PackageLikeBuilderDummy(),
            Collections.singletonList(psiFile));

    boolean hasErrors =
        AnalyzerWithCompilerReport.reportDiagnostics(trace.getBindingContext(), messageCollector);
    if (hasErrors) {
      return null;
    }

    ScriptDescriptor scriptDescriptor =
        topDownAnalysisContext.getScripts().get(psiFile.getScript());
    lastLineScope = trace.get(BindingContext.SCRIPT_SCOPE, scriptDescriptor);
    if (lastLineScope == null) {
      throw new IllegalStateException("last line scope is not initialized");
    }

    return scriptDescriptor;
  }
Exemple #2
0
  @NotNull
  public LineResult eval(@NotNull String line) {
    ++lineNumber;

    FqName scriptFqName = new FqName("Line" + lineNumber);
    Type scriptClassType = asmTypeByFqNameWithoutInnerClasses(scriptFqName);

    StringBuilder fullText = new StringBuilder();
    for (String prevLine : previousIncompleteLines) {
      fullText.append(prevLine + "\n");
    }
    fullText.append(line);

    LightVirtualFile virtualFile =
        new LightVirtualFile(
            "line" + lineNumber + JetParserDefinition.STD_SCRIPT_EXT,
            JetLanguage.INSTANCE,
            fullText.toString());
    virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
    JetFile psiFile =
        (JetFile)
            ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject()))
                .trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);

    MessageCollectorToString errorCollector = new MessageCollectorToString();

    AnalyzerWithCompilerReport.SyntaxErrorReport syntaxErrorReport =
        AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorCollector);

    if (syntaxErrorReport.isOnlyErrorAtEof()) {
      previousIncompleteLines.add(line);
      return LineResult.incomplete();
    }

    previousIncompleteLines.clear();

    if (syntaxErrorReport.isHasErrors()) {
      return LineResult.error(errorCollector.getString());
    }

    prepareForTheNextReplLine(topDownAnalysisContext);
    trace.clearDiagnostics();

    psiFile.getScript().putUserData(ScriptHeaderResolver.PRIORITY_KEY, lineNumber);

    ScriptDescriptor scriptDescriptor = doAnalyze(psiFile, errorCollector);
    if (scriptDescriptor == null) {
      return LineResult.error(errorCollector.getString());
    }

    List<Pair<ScriptDescriptor, Type>> earlierScripts = Lists.newArrayList();

    for (EarlierLine earlierLine : earlierLines) {
      earlierScripts.add(
          Pair.create(earlierLine.getScriptDescriptor(), earlierLine.getClassType()));
    }

    BindingContext bindingContext =
        AnalyzeExhaust.success(trace.getBindingContext(), module).getBindingContext();
    GenerationState generationState =
        new GenerationState(
            psiFile.getProject(),
            ClassBuilderFactories.BINARIES,
            bindingContext,
            Collections.singletonList(psiFile),
            CompilerArgumentsUtil.DEFAULT_INLINE_FLAG);

    compileScript(
        psiFile.getScript(),
        scriptClassType,
        earlierScripts,
        generationState,
        CompilationErrorHandler.THROW_EXCEPTION);

    for (OutputFile outputFile : generationState.getFactory().asList()) {
      classLoader.addClass(
          JvmClassName.byInternalName(outputFile.getRelativePath().replaceFirst("\\.class$", "")),
          outputFile.asByteArray());
    }

    try {
      Class<?> scriptClass = classLoader.loadClass(scriptFqName.asString());

      Class<?>[] constructorParams = new Class<?>[earlierLines.size()];
      Object[] constructorArgs = new Object[earlierLines.size()];

      for (int i = 0; i < earlierLines.size(); ++i) {
        constructorParams[i] = earlierLines.get(i).getScriptClass();
        constructorArgs[i] = earlierLines.get(i).getScriptInstance();
      }

      Constructor<?> scriptInstanceConstructor = scriptClass.getConstructor(constructorParams);
      Object scriptInstance;
      try {
        scriptInstance = scriptInstanceConstructor.newInstance(constructorArgs);
      } catch (Throwable e) {
        return LineResult.error(Throwables.getStackTraceAsString(e));
      }
      Field rvField = scriptClass.getDeclaredField("rv");
      rvField.setAccessible(true);
      Object rv = rvField.get(scriptInstance);

      earlierLines.add(
          new EarlierLine(line, scriptDescriptor, scriptClass, scriptInstance, scriptClassType));

      return LineResult.successful(
          rv,
          KotlinBuiltIns.getInstance()
              .getUnitType()
              .equals(scriptDescriptor.getScriptCodeDescriptor().getReturnType()));
    } catch (Throwable e) {
      PrintWriter writer = new PrintWriter(System.err);
      classLoader.dumpClasses(writer);
      writer.flush();
      throw UtilsPackage.rethrow(e);
    }
  }