de.loskutov.bco.asm.DecompilerHelper.java Source code

Java tutorial

Introduction

Here is the source code for de.loskutov.bco.asm.DecompilerHelper.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Eric Bruneton.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 * Contributor:  Eric Bruneton - initial API and implementation
 * Contributor:  Andrey Loskutov - fixes
 *******************************************************************************/
package de.loskutov.bco.asm;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.TraceClassVisitor;

import de.loskutov.bco.preferences.BCOConstants;

/**
 * @author Eric Bruneton
 */
public class DecompilerHelper {

    public static DecompiledClass getDecompiledClass(final InputStream is, DecompilerOptions options)
            throws IOException, UnsupportedClassVersionError {
        ClassReader cr = new ClassReader(is);
        ClassNode cn = new ClassNode(Opcodes.ASM5);
        int crFlags = 0;
        if (options.modes.get(BCOConstants.F_EXPAND_STACKMAP)) {
            crFlags |= ClassReader.EXPAND_FRAMES;
        }
        cr.accept(cn, crFlags);
        ICommentedClassVisitor printer;
        if (options.modes.get(BCOConstants.F_SHOW_ASMIFIER_CODE)) {
            printer = new CommentedASMifierClassVisitor(cn, options);
        } else {
            printer = new CommentedClassVisitor(cn, options);
        }
        TraceClassVisitor dcv = new TraceClassVisitor(null, (Printer) printer, null);
        cn.accept(dcv);
        return getResult(printer, options, cn);
    }

    private static DecompiledClass getResult(ICommentedClassVisitor printer, DecompilerOptions options,
            ClassNode classNode) {
        List<Object> classText = new ArrayList<Object>();
        formatText(printer.getText(), new StringBuffer(), classText, options.cl);
        while (classText.size() > 0 && classText.get(0).equals("\n")) {
            classText.remove(0);
        }

        DecompiledClassInfo classInfo = printer.getClassInfo();
        return new DecompiledClass(classText, classInfo, classNode);
    }

    private static void formatText(final List input, final StringBuffer line, final List<Object> result,
            final ClassLoader cl) {
        for (int i = 0; i < input.size(); ++i) {
            Object o = input.get(i);
            if (o instanceof List) {
                formatText((List) o, line, result, cl);
            } else if (o instanceof DecompiledMethod) {
                result.add(o);
            } else {
                String s = o.toString();
                int p;
                do {
                    p = s.indexOf('\n');
                    if (p == -1) {
                        line.append(s);
                    } else {
                        result.add(line.toString() + s.substring(0, p + 1));
                        s = s.substring(p + 1);
                        line.setLength(0);
                    }
                } while (p != -1);
            }
        }
    }

}