Package jadx.core.dex.nodes.parser

Source Code of jadx.core.dex.nodes.parser.LocalVar

package jadx.core.dex.nodes.parser;

import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.DexNode;
import jadx.core.utils.InsnUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

final class LocalVar {
  private static final Logger LOG = LoggerFactory.getLogger(LocalVar.class);

  private final int regNum;
  private String name;
  private ArgType type;

  private boolean isEnd;
  private int startAddr;
  private int endAddr;

  public LocalVar(DexNode dex, int rn, int nameId, int typeId, int signId) {
    this.regNum = rn;
    String name = nameId == DexNode.NO_INDEX ? null : dex.getString(nameId);
    ArgType type = typeId == DexNode.NO_INDEX ? null : dex.getType(typeId);
    String sign = signId == DexNode.NO_INDEX ? null : dex.getString(signId);

    init(name, type, sign);
  }

  public LocalVar(RegisterArg arg) {
    this.regNum = arg.getRegNum();
    init(arg.getName(), arg.getType(), null);
  }

  private void init(String name, ArgType type, String sign) {
    if (sign != null) {
      try {
        ArgType gType = ArgType.generic(sign);
        if (checkSignature(type, sign, gType)) {
          type = gType;
        }
      } catch (Exception e) {
        LOG.error("Can't parse signature for local variable: {}", sign, e);
      }
    }
    this.name = name;
    this.type = type;
  }

  private boolean checkSignature(ArgType type, String sign, ArgType gType) {
    boolean apply;
    ArgType el = gType.getArrayRootElement();
    if (el.isGeneric()) {
      if (!type.getArrayRootElement().getObject().equals(el.getObject())) {
        LOG.warn("Generic type in debug info not equals: {} != {}", type, gType);
      }
      apply = true;
    } else {
      apply = el.isGenericType();
    }
    return apply;
  }

  public void start(int addr, int line) {
    this.isEnd = false;
    this.startAddr = addr;
  }

  /**
   * Sets end address of local variable
   *
   * @param addr address
   * @param line source line
   * @return <b>true</b> if local variable was active, else <b>false</b>
   */
  public boolean end(int addr, int line) {
    if (!isEnd) {
      this.isEnd = true;
      this.endAddr = addr;
      return true;
    }
    return false;
  }

  public int getRegNum() {
    return regNum;
  }

  public String getName() {
    return name;
  }

  public ArgType getType() {
    return type;
  }

  public boolean isEnd() {
    return isEnd;
  }

  public int getStartAddr() {
    return startAddr;
  }

  public int getEndAddr() {
    return endAddr;
  }

  @Override
  public boolean equals(Object obj) {
    return super.equals(obj);
  }

  @Override
  public int hashCode() {
    return super.hashCode();
  }

  @Override
  public String toString() {
    return super.toString() + " " + (isEnd
        ? "end: " + InsnUtils.formatOffset(startAddr) + "-" + InsnUtils.formatOffset(endAddr)
        : "active: " + InsnUtils.formatOffset(startAddr));
  }
}
TOP

Related Classes of jadx.core.dex.nodes.parser.LocalVar

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.