Пример #1
0
  private static boolean verifyWithAsm(@NotNull OutputFile file, ClassLoader loader) {
    ClassNode classNode = new ClassNode();
    new ClassReader(file.asByteArray()).accept(classNode, 0);

    SimpleVerifier verifier = new SimpleVerifier();
    verifier.setClassLoader(loader);
    Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(verifier);

    boolean noErrors = true;
    for (MethodNode method : classNode.methods) {
      try {
        analyzer.analyze(classNode.name, method);
      } catch (Throwable e) {
        System.err.println(file.asText());
        System.err.println(classNode.name + "::" + method.name + method.desc);

        //noinspection InstanceofCatchParameter
        if (e instanceof AnalyzerException) {
          // Print the erroneous instruction
          TraceMethodVisitor tmv = new TraceMethodVisitor(new Textifier());
          ((AnalyzerException) e).node.accept(tmv);
          PrintWriter pw = new PrintWriter(System.err);
          tmv.p.print(pw);
          pw.flush();
        }

        e.printStackTrace();
        noErrors = false;
      }
    }
    return noErrors;
  }
Пример #2
0
  protected void doTest(String path) throws Exception {
    File ktFile = new File(path);
    assertTrue("Cannot find a file " + ktFile.getAbsolutePath(), ktFile.exists());

    String fileText = FileUtil.loadFile(ktFile, true);

    KtFile psiFile =
        KotlinTestUtils.createFile(ktFile.getName(), fileText, jetCoreEnvironment.getProject());

    OutputFileCollection outputFiles =
        GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, jetCoreEnvironment);

    List<TestedObject> testedObjects = parseExpectedTestedObject(fileText);
    for (TestedObject testedObject : testedObjects) {
      String className = null;
      for (OutputFile outputFile : outputFiles.asList()) {
        String filePath = outputFile.getRelativePath();
        if (testedObject.isFullContainingClassName
            && filePath.equals(testedObject.containingClass + ".class")) {
          className = filePath;
        } else if (!testedObject.isFullContainingClassName
            && filePath.startsWith(testedObject.containingClass)) {
          className = filePath;
        }
      }

      assertNotNull(
          "Couldn't find a class file with name " + testedObject.containingClass, className);

      OutputFile outputFile = outputFiles.get(className);
      assertNotNull(outputFile);

      ClassReader cr = new ClassReader(outputFile.asByteArray());
      TestClassVisitor classVisitor = getClassVisitor(testedObject.kind, testedObject.name, false);
      cr.accept(classVisitor, ClassReader.SKIP_CODE);

      if (!classVisitor.isExists()) {
        classVisitor = getClassVisitor(testedObject.kind, testedObject.name, true);
        cr.accept(classVisitor, ClassReader.SKIP_CODE);
      }

      boolean isObjectExists =
          !Boolean.valueOf(findStringWithPrefixes(testedObject.textData, "// ABSENT: "));
      assertEquals(
          "Wrong object existence state: " + testedObject, isObjectExists, classVisitor.isExists());

      if (isObjectExists) {
        assertEquals(
            "Wrong access flag for " + testedObject + " \n" + outputFile.asText(),
            getExpectedFlags(testedObject.textData),
            classVisitor.getAccess());
      }
    }
  }
Пример #3
0
 @NotNull
 /* package */ static ClassReader buildClassReaderByInternalName(
     @NotNull GenerationState state, @NotNull String internalName) {
   // try to find just compiled classes then in dependencies
   try {
     OutputFile outputFile = state.getFactory().get(internalName + ".class");
     if (outputFile != null) {
       return new ClassReader(outputFile.asByteArray());
     } else {
       VirtualFile file = findVirtualFile(state.getProject(), internalName);
       if (file == null) {
         throw new RuntimeException("Couldn't find virtual file for " + internalName);
       }
       return new ClassReader(file.contentsToByteArray());
     }
   } catch (IOException e) {
     throw new RuntimeException(e);
   }
 }
  @NotNull
  private List<InnerClassAttribute> extractInnerClasses(@NotNull String className) {
    OutputFile outputFile = generateClassesInFile().get(className + ".class");
    assertNotNull(outputFile);
    byte[] bytes = outputFile.asByteArray();
    ClassReader reader = new ClassReader(bytes);
    final List<InnerClassAttribute> result = new ArrayList<InnerClassAttribute>();

    reader.accept(
        new ClassVisitor(ASM5) {
          @Override
          public void visitInnerClass(
              @NotNull String name, String outerName, String innerName, int access) {
            result.add(new InnerClassAttribute(name, outerName, innerName, access));
          }
        },
        ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);

    return result;
  }
Пример #5
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).append("\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) psiFileFactory.trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
    assert psiFile != null : "Script file not analyzed at line " + lineNumber + ": " + fullText;

    ReplMessageCollectorWrapper errorCollector = new ReplMessageCollectorWrapper();

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

    if (syntaxErrorReport.isHasErrors() && syntaxErrorReport.isAllErrorsAtEof()) {
      previousIncompleteLines.add(line);
      return LineResult.incomplete();
    }

    previousIncompleteLines.clear();

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

    prepareForTheNextReplLine(topDownAnalysisContext);
    trace.clearDiagnostics();

    //noinspection ConstantConditions
    psiFile.getScript().putUserData(ScriptPriorities.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()));
    }

    GenerationState state =
        new GenerationState(
            psiFile.getProject(),
            ClassBuilderFactories.BINARIES,
            module,
            trace.getBindingContext(),
            Collections.singletonList(psiFile));

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

    for (OutputFile outputFile : state.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(renderStackTrace(e.getCause()));
      }
      Field rvField = scriptClass.getDeclaredField("rv");
      rvField.setAccessible(true);
      Object rv = rvField.get(scriptInstance);

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

      JetType returnType = scriptDescriptor.getScriptCodeDescriptor().getReturnType();
      return LineResult.successful(rv, returnType != null && KotlinBuiltIns.isUnit(returnType));
    } catch (Throwable e) {
      @SuppressWarnings("UseOfSystemOutOrSystemErr")
      PrintWriter writer = new PrintWriter(System.err);
      classLoader.dumpClasses(writer);
      writer.flush();
      throw UtilsPackage.rethrow(e);
    }
  }