Package ru.andrew.jclazz.decompiler.engine.blocks

Source Code of ru.andrew.jclazz.decompiler.engine.blocks.IfBlock

package ru.andrew.jclazz.decompiler.engine.blocks;

import ru.andrew.jclazz.decompiler.engine.ops.*;

import java.util.*;
import java.util.ArrayList;
import ru.andrew.jclazz.decompiler.engine.CodeItem;

public class IfBlock extends Block
{
    private List andConditions = new ArrayList();

    private Else elseBlock;

    private boolean isNegConditions = false;

    public IfBlock(Block parent)
    {
        super(parent);
    }

    public void setElseBlock(Else elseBlock)
    {
        this.elseBlock = elseBlock;
        // Remove last goto
        if (getLastOperation() instanceof GoToView)
        {
            removeLastOperation();
        }
    }

    public Else getElseBlock()
    {
        return elseBlock;
    }

    private boolean isElseIf = false;   // For printing only

    public void setElseIf(boolean elseIf)
    {
        isElseIf = elseIf;
    }

    public long getStartByte()
    {
        if (andConditions != null && andConditions.size() > 0 && ((List) andConditions.get(0)).size() > 0)
        {
            Condition cond = (Condition) ((List) andConditions.get(0)).get(0);
            return cond.getStartByte();
        }
        return super.getStartByte();
    }

    public String getSource()
    {
        StringBuffer sb = new StringBuffer();
        sb.append(indent).append(isElseIf ? "else " : "").append("if ");
        sb.append(getSourceConditions());
        sb.append(NL).append(super.getSource());
        return sb.toString();
    }

    /**
     * @deprecated
     */
    public String getSourceConditions()
    {
        /*
        StringBuffer sb = new StringBuffer();
        if (isNegConditions) sb.append("(!");
        if (andConditions.size() > 1) sb.append("(");
        for (Iterator i = andConditions.iterator(); i.hasNext();)
        {
            List orConditions = (List) i.next();
            if (orConditions.size() > 1) sb.append("(");
            for (Iterator j = orConditions.iterator(); j.hasNext();)
            {
                Condition cond = (Condition) j.next();
                if (j.hasNext() && orConditions.size() > 1) cond.setNeedReverseOperation(false);
                sb.append("(" + cond.str() + ")");
                if (j.hasNext()) sb.append(" || ");
            }
            if (orConditions.size() > 1) sb.append(")");
            if (i.hasNext()) sb.append(" && ");
        }
        if (andConditions.size() > 1) sb.append(")");
        if (isNegConditions) sb.append(")");
        return sb.toString();
         */
        StringBuffer sb = new StringBuffer();
        Iterator i = getSourceConditionsView().iterator();
        while (i.hasNext())
        {
            Object obj = i.next();
            if (obj instanceof String)
            {
                sb.append((String) obj);
            }
            else
            {
                sb.append(((OperationView) obj).source2());
            }
        }
        return sb.toString();
    }

    public List getSourceConditionsView()
    {
        List src = new ArrayList();
        if (isNegConditions) src.add("(!");
        if (andConditions.size() > 1) src.add("(");
        for (Iterator i = andConditions.iterator(); i.hasNext();)
        {
            List orConditions = (List) i.next();
            if (orConditions.size() > 1) src.add("(");
            for (Iterator j = orConditions.iterator(); j.hasNext();)
            {
                Condition cond = (Condition) j.next();
                if (j.hasNext() && orConditions.size() > 1) cond.setNeedReverseOperation(false);
                src.add("(");
                src.addAll(cond.getView());
                src.add(")");
                if (j.hasNext()) src.add(" || ");
            }
            if (orConditions.size() > 1) src.add(")");
            if (i.hasNext()) src.add(" && ");
        }
        if (andConditions.size() > 1) src.add(")");
        if (isNegConditions) src.add(")");
        return src;
    }

    public void addAndConditions(List ops)
    {
        List orConditions = new ArrayList();
        List newOps = new ArrayList();
        Iterator i = ops.iterator();
        while (i.hasNext())
        {
            CodeItem ci = (CodeItem) i.next();
            newOps.add(ci);
            if (ci instanceof IfView)
            {
                orConditions.add(new Condition((IfView) ci, this, new ArrayList(newOps)));
                newOps.clear();
            }
        }

        andConditions.add(orConditions);
    }

    public void analyze(Block block)
    {
        for (Iterator i = andConditions.iterator(); i.hasNext();)
        {
            List orConditions = (List) i.next();
            for (Iterator j = orConditions.iterator(); j.hasNext();)
            {
                Condition cond = (Condition) j.next();
                cond.analyze(block);
            }
        }

        // Can be break in back loop
        List firstOrConditions = (List) andConditions.get(0);
        long target = ((Condition) firstOrConditions.get(firstOrConditions.size() - 1)).getIfOperation().getTargetOperation();
        long start = ((Condition) firstOrConditions.get(firstOrConditions.size() - 1)).getIfOperation().getStartByte();
        if (block.getLastOperation().getStartByte() < target && block instanceof Loop)
        {
            Block par = block;
            do
            {
                par = par.getParent();
                if (par == null) break;
            }
            while (par.getOperationByStartByte(target) == null);
           
            if (par != null && par.getOperationPriorTo(target) instanceof Loop)
            {
                GoToView got = new FakeGoToView(start, target);
                got.setBreak(true);
                ops.add(ops.size(), got);
                isNegConditions = true;
            }
        }
    }

    private int stackSizeChange;
    private boolean isPushShortForm = false;

    public void preanalyze(Block block)
    {
        stackSizeChange = getMethodView().getMethodContext().stackSize();
    }

    public void postanalyze(Block block)
    {
        stackSizeChange = getMethodView().getMethodContext().stackSize() - stackSizeChange;
        isPushShortForm = stackSizeChange == 1;
    }

    public boolean isIsPushShortForm()
    {
        return isPushShortForm;
    }
}
TOP

Related Classes of ru.andrew.jclazz.decompiler.engine.blocks.IfBlock

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.