Search in sources :

Example 1 with ClassReader

use of org.jetbrains.org.objectweb.asm.ClassReader in project kotlin by JetBrains.

the class FileBasedKotlinClass method loadClassAnnotations.

@Override
public void loadClassAnnotations(@NotNull final AnnotationVisitor annotationVisitor, @Nullable byte[] cachedContents) {
    byte[] fileContents = cachedContents != null ? cachedContents : getFileContents();
    new ClassReader(fileContents).accept(new ClassVisitor(ASM5) {

        @Override
        public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) {
            return convertAnnotationVisitor(annotationVisitor, desc, innerClasses);
        }

        @Override
        public void visitEnd() {
            annotationVisitor.visitEnd();
        }
    }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
}
Also used : ReadKotlinClassHeaderAnnotationVisitor(org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) ClassVisitor(org.jetbrains.org.objectweb.asm.ClassVisitor)

Example 2 with ClassReader

use of org.jetbrains.org.objectweb.asm.ClassReader in project kotlin by JetBrains.

the class FileBasedKotlinClass method visitMembers.

@Override
public void visitMembers(@NotNull final MemberVisitor memberVisitor, @Nullable byte[] cachedContents) {
    byte[] fileContents = cachedContents != null ? cachedContents : getFileContents();
    new ClassReader(fileContents).accept(new ClassVisitor(ASM5) {

        @Override
        public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) {
            final AnnotationVisitor v = memberVisitor.visitField(Name.identifier(name), desc, value);
            if (v == null)
                return null;
            return new FieldVisitor(ASM5) {

                @Override
                public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) {
                    return convertAnnotationVisitor(v, desc, innerClasses);
                }

                @Override
                public void visitEnd() {
                    v.visitEnd();
                }
            };
        }

        @Override
        public MethodVisitor visitMethod(int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions) {
            final MethodAnnotationVisitor v = memberVisitor.visitMethod(Name.identifier(name), desc);
            if (v == null)
                return null;
            return new MethodVisitor(ASM5) {

                @Override
                public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) {
                    return convertAnnotationVisitor(v, desc, innerClasses);
                }

                @Override
                public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitParameterAnnotation(int parameter, @NotNull String desc, boolean visible) {
                    AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, resolveNameByDesc(desc, innerClasses), SourceElement.NO_SOURCE);
                    return av == null ? null : convertAnnotationVisitor(av, innerClasses);
                }

                @Override
                public void visitEnd() {
                    v.visitEnd();
                }
            };
        }
    }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
}
Also used : ClassVisitor(org.jetbrains.org.objectweb.asm.ClassVisitor) FieldVisitor(org.jetbrains.org.objectweb.asm.FieldVisitor) MethodVisitor(org.jetbrains.org.objectweb.asm.MethodVisitor) ReadKotlinClassHeaderAnnotationVisitor(org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader)

Example 3 with ClassReader

use of org.jetbrains.org.objectweb.asm.ClassReader in project kotlin by JetBrains.

the class FileBasedKotlinClass method create.

// TODO public to be accessible in companion object of subclass, workaround for KT-3974
@Nullable
public static <T extends FileBasedKotlinClass> T create(@NotNull byte[] fileContents, @NotNull Function4<ClassId, Integer, KotlinClassHeader, InnerClassesInfo, T> factory) {
    final ReadKotlinClassHeaderAnnotationVisitor readHeaderVisitor = new ReadKotlinClassHeaderAnnotationVisitor();
    final Ref<String> classNameRef = Ref.create();
    final Ref<Integer> classVersion = Ref.create();
    final InnerClassesInfo innerClasses = new InnerClassesInfo();
    new ClassReader(fileContents).accept(new ClassVisitor(ASM5) {

        @Override
        public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
            classNameRef.set(name);
            classVersion.set(version);
        }

        @Override
        public void visitInnerClass(@NotNull String name, String outerName, String innerName, int access) {
            innerClasses.add(name, outerName, innerName);
        }

        @Override
        public org.jetbrains.org.objectweb.asm.AnnotationVisitor visitAnnotation(@NotNull String desc, boolean visible) {
            return convertAnnotationVisitor(readHeaderVisitor, desc, innerClasses);
        }

        @Override
        public void visitEnd() {
            readHeaderVisitor.visitEnd();
        }
    }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
    String className = classNameRef.get();
    if (className == null)
        return null;
    KotlinClassHeader header = readHeaderVisitor.createHeader();
    if (header == null)
        return null;
    ClassId id = resolveNameByInternalName(className, innerClasses);
    return factory.invoke(id, classVersion.get(), header, innerClasses);
}
Also used : KotlinClassHeader(org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader) ClassId(org.jetbrains.kotlin.name.ClassId) ClassVisitor(org.jetbrains.org.objectweb.asm.ClassVisitor) ReadKotlinClassHeaderAnnotationVisitor(org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor) ReadKotlinClassHeaderAnnotationVisitor(org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with ClassReader

use of org.jetbrains.org.objectweb.asm.ClassReader in project intellij-community by JetBrains.

the class FormsInstrumenter method instrumentForms.

private Map<File, Collection<File>> instrumentForms(CompileContext context, ModuleChunk chunk, final Map<File, String> chunkSourcePath, final InstrumentationClassFinder finder, Collection<File> forms, OutputConsumer outConsumer) throws ProjectBuildException {
    final Map<File, Collection<File>> instrumented = new THashMap<>(FileUtil.FILE_HASHING_STRATEGY);
    final Map<String, File> class2form = new HashMap<>();
    final MyNestedFormLoader nestedFormsLoader = new MyNestedFormLoader(chunkSourcePath, ProjectPaths.getOutputPathsWithDependents(chunk), finder);
    for (File formFile : forms) {
        final LwRootContainer rootContainer;
        try {
            rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader()));
        } catch (AlienFormFileException e) {
            // ignore non-IDEA forms
            continue;
        } catch (UnexpectedFormElementException e) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, e.getMessage(), formFile.getPath()));
            LOG.info(e);
            continue;
        } catch (UIDesignerException e) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, e.getMessage(), formFile.getPath()));
            LOG.info(e);
            continue;
        } catch (Exception e) {
            throw new ProjectBuildException("Cannot process form file " + formFile.getAbsolutePath(), e);
        }
        final String classToBind = rootContainer.getClassToBind();
        if (classToBind == null) {
            continue;
        }
        final CompiledClass compiled = findClassFile(outConsumer, classToBind);
        if (compiled == null) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, "Class to bind does not exist: " + classToBind, formFile.getAbsolutePath()));
            continue;
        }
        final File alreadyProcessedForm = class2form.get(classToBind);
        if (alreadyProcessedForm != null) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, formFile.getAbsolutePath() + ": The form is bound to the class " + classToBind + ".\nAnother form " + alreadyProcessedForm.getAbsolutePath() + " is also bound to this class", formFile.getAbsolutePath()));
            continue;
        }
        class2form.put(classToBind, formFile);
        for (File file : compiled.getSourceFiles()) {
            addBinding(file, formFile, instrumented);
        }
        try {
            context.processMessage(new ProgressMessage("Instrumenting forms... [" + chunk.getPresentableShortName() + "]"));
            final BinaryContent originalContent = compiled.getContent();
            final ClassReader classReader = new FailSafeClassReader(originalContent.getBuffer(), originalContent.getOffset(), originalContent.getLength());
            final int version = ClassProcessingBuilder.getClassFileVersion(classReader);
            final InstrumenterClassWriter classWriter = new InstrumenterClassWriter(classReader, ClassProcessingBuilder.getAsmClassWriterFlags(version), finder);
            final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, nestedFormsLoader, false, classWriter);
            final byte[] patchedBytes = codeGenerator.patchClass(classReader);
            if (patchedBytes != null) {
                compiled.setContent(new BinaryContent(patchedBytes));
            }
            final FormErrorInfo[] warnings = codeGenerator.getWarnings();
            for (final FormErrorInfo warning : warnings) {
                context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.WARNING, warning.getErrorMessage(), formFile.getAbsolutePath()));
            }
            final FormErrorInfo[] errors = codeGenerator.getErrors();
            if (errors.length > 0) {
                StringBuilder message = new StringBuilder();
                for (final FormErrorInfo error : errors) {
                    if (message.length() > 0) {
                        message.append("\n");
                    }
                    message.append(formFile.getAbsolutePath()).append(": ").append(error.getErrorMessage());
                }
                context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, message.toString()));
            }
        } catch (Exception e) {
            context.processMessage(new CompilerMessage(getPresentableName(), BuildMessage.Kind.ERROR, "Forms instrumentation failed" + e.getMessage(), formFile.getAbsolutePath()));
        }
    }
    return instrumented;
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) THashMap(gnu.trove.THashMap) LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) THashMap(gnu.trove.THashMap) InstrumenterClassWriter(com.intellij.compiler.instrumentation.InstrumenterClassWriter) CompiledClassPropertiesProvider(com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader) ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader)

Example 5 with ClassReader

use of org.jetbrains.org.objectweb.asm.ClassReader in project intellij-community by JetBrains.

the class FormsBuilderTest method isInstrumented.

private static boolean isInstrumented(JpsModule m, final String classPath) {
    File file = new File(JpsJavaExtensionService.getInstance().getOutputDirectory(m, false), classPath);
    assertTrue(file.getAbsolutePath() + " not found", file.exists());
    final Ref<Boolean> instrumented = Ref.create(false);
    ClassVisitor visitor = new ClassVisitor(Opcodes.API_VERSION) {

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            if (name.equals("$$$setupUI$$$")) {
                instrumented.set(true);
            }
            return null;
        }
    };
    try {
        ClassReader reader = new ClassReader(FileUtil.loadFileBytes(file));
        reader.accept(visitor, 0);
        return instrumented.get();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : ClassReader(org.jetbrains.org.objectweb.asm.ClassReader) ClassVisitor(org.jetbrains.org.objectweb.asm.ClassVisitor) IOException(java.io.IOException) File(java.io.File)

Aggregations

ClassReader (org.jetbrains.org.objectweb.asm.ClassReader)30 ClassVisitor (org.jetbrains.org.objectweb.asm.ClassVisitor)12 File (java.io.File)6 IOException (java.io.IOException)6 OutputFile (org.jetbrains.kotlin.backend.common.output.OutputFile)5 ClassWriter (org.jetbrains.org.objectweb.asm.ClassWriter)4 FailSafeClassReader (com.intellij.compiler.instrumentation.FailSafeClassReader)3 NotNull (org.jetbrains.annotations.NotNull)3 Nullable (org.jetbrains.annotations.Nullable)3 CompilerMessage (org.jetbrains.jps.incremental.messages.CompilerMessage)3 ReadKotlinClassHeaderAnnotationVisitor (org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor)3 MethodVisitor (org.jetbrains.org.objectweb.asm.MethodVisitor)3 ClassNode (org.jetbrains.org.objectweb.asm.tree.ClassNode)3 InstrumenterClassWriter (com.intellij.compiler.instrumentation.InstrumenterClassWriter)2 PsiJavaFileStubImpl (com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl)2 SourceLineCounter (com.intellij.rt.coverage.instrumentation.SourceLineCounter)2 PrintWriter (java.io.PrintWriter)2 ProgressMessage (org.jetbrains.jps.incremental.messages.ProgressMessage)2 OutputFileCollection (org.jetbrains.kotlin.backend.common.output.OutputFileCollection)2 MethodNode (org.jetbrains.org.objectweb.asm.tree.MethodNode)2