All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.dex2jar.ir.ts.CleanLabel Maven / Gradle / Ivy

package com.googlecode.dex2jar.ir.ts;

import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.LocalVar;
import com.googlecode.dex2jar.ir.Trap;
import com.googlecode.dex2jar.ir.stmt.BaseSwitchStmt;
import com.googlecode.dex2jar.ir.stmt.JumpStmt;
import com.googlecode.dex2jar.ir.stmt.LabelStmt;
import com.googlecode.dex2jar.ir.stmt.Stmt;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
import com.googlecode.dex2jar.ir.stmt.StmtList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Clean unused {@link LabelStmt}
 *
 * @author Panxiaobo
 */
public class CleanLabel implements Transformer {

    @Override
    public void transform(IrMethod irMethod) {
        Set useLabels = new HashSet<>();
        addTrap(irMethod.traps, useLabels);
        addVars(irMethod.vars, useLabels);
        addStmt(irMethod.stmts, useLabels);
        if (irMethod.phiLabels != null) {
            useLabels.addAll(irMethod.phiLabels);
        }
        addLineNumber(irMethod.stmts, useLabels);
        rmUnused(irMethod.stmts, useLabels);
    }

    private void addVars(List vars, Set useLabels) {
        if (vars != null) {
            for (LocalVar var : vars) {
                useLabels.add(var.start);
                useLabels.add(var.end);
            }
        }

    }

    private void rmUnused(StmtList stmts, Set useLabels) {
        Stmt p = stmts.getFirst();
        while (p != null) {
            if (p instanceof LabelStmt && p.st == ST.LABEL) {
                if (!useLabels.contains(p)) {
                    Stmt q = p.getNext();
                    stmts.remove(p);
                    p = q;
                    continue;
                }
            }
            p = p.getNext();
        }
    }

    private void addStmt(StmtList stmts, Set labels) {
        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
            if (p instanceof JumpStmt) {
                labels.add(((JumpStmt) p).getTarget());
            } else if (p instanceof BaseSwitchStmt) {
                BaseSwitchStmt stmt = (BaseSwitchStmt) p;
                labels.add(stmt.defaultTarget);
                Collections.addAll(labels, stmt.targets);
            }
        }
    }

    private void addTrap(List traps, Set labels) {
        if (traps != null) {
            for (Trap trap : traps) {
                labels.add(trap.start);
                labels.add(trap.end);
                Collections.addAll(labels, trap.handlers);
            }
        }
    }

    // fix https://github.com/pxb1988/dex2jar/issues/165
    private void addLineNumber(StmtList stmts, Set useLabels) {
        for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) {
            if (p instanceof LabelStmt && ((LabelStmt) p).lineNumber != -1) {
                useLabels.add((LabelStmt) p);
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy