Package jadx.api

Source Code of jadx.api.JavaClass

package jadx.api;

import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public final class JavaClass implements JavaNode {

  private final JadxDecompiler decompiler;
  private final ClassNode cls;
  private final JavaClass parent;

  private List<JavaClass> innerClasses = Collections.emptyList();
  private List<JavaField> fields = Collections.emptyList();
  private List<JavaMethod> methods = Collections.emptyList();

  JavaClass(ClassNode classNode, JadxDecompiler decompiler) {
    this.decompiler = decompiler;
    this.cls = classNode;
    this.parent = null;
  }

  /**
   * Inner classes constructor
   */
  JavaClass(ClassNode classNode, JavaClass parent) {
    this.decompiler = null;
    this.cls = classNode;
    this.parent = parent;
  }

  public String getCode() {
    CodeWriter code = cls.getCode();
    if (code == null) {
      decompile();
      code = cls.getCode();
    }
    if (code == null) {
      return "";
    }
    return code.toString();
  }

  public void decompile() {
    if (decompiler == null) {
      return;
    }
    if (cls.getCode() == null) {
      decompiler.processClass(cls);
      load();
    }
  }

  ClassNode getClassNode() {
    return cls;
  }

  private void load() {
    int inClsCount = cls.getInnerClasses().size();
    if (inClsCount != 0) {
      List<JavaClass> list = new ArrayList<JavaClass>(inClsCount);
      for (ClassNode inner : cls.getInnerClasses()) {
        if (!inner.contains(AFlag.DONT_GENERATE)) {
          JavaClass javaClass = new JavaClass(inner, this);
          javaClass.load();
          list.add(javaClass);
        }
      }
      this.innerClasses = Collections.unmodifiableList(list);
    }

    int fieldsCount = cls.getFields().size();
    if (fieldsCount != 0) {
      List<JavaField> flds = new ArrayList<JavaField>(fieldsCount);
      for (FieldNode f : cls.getFields()) {
        if (!f.contains(AFlag.DONT_GENERATE)) {
          flds.add(new JavaField(f, this));
        }
      }
      this.fields = Collections.unmodifiableList(flds);
    }

    int methodsCount = cls.getMethods().size();
    if (methodsCount != 0) {
      List<JavaMethod> mths = new ArrayList<JavaMethod>(methodsCount);
      for (MethodNode m : cls.getMethods()) {
        if (!m.contains(AFlag.DONT_GENERATE)) {
          mths.add(new JavaMethod(this, m));
        }
      }
      Collections.sort(mths, new Comparator<JavaMethod>() {
        @Override
        public int compare(JavaMethod o1, JavaMethod o2) {
          return o1.getName().compareTo(o2.getName());
        }
      });
      this.methods = Collections.unmodifiableList(mths);
    }
  }

  private Map<CodePosition, Object> getCodeAnnotations() {
    decompile();
    return cls.getCode().getAnnotations();
  }

  public CodePosition getDefinitionPosition(int line, int offset) {
    Map<CodePosition, Object> map = getCodeAnnotations();
    Object obj = map.get(new CodePosition(line, offset));
    if (!(obj instanceof LineAttrNode)) {
      return null;
    }
    ClassNode clsNode = null;
    if (obj instanceof ClassNode) {
      clsNode = (ClassNode) obj;
    } else if (obj instanceof MethodNode) {
      clsNode = ((MethodNode) obj).getParentClass();
    } else if (obj instanceof FieldNode) {
      clsNode = ((FieldNode) obj).getParentClass();
    }
    if (clsNode == null) {
      return null;
    }
    clsNode = clsNode.getTopParentClass();
    JavaClass jCls = decompiler.findJavaClass(clsNode);
    if (jCls == null) {
      return null;
    }
    jCls.decompile();
    int defLine = ((LineAttrNode) obj).getDecompiledLine();
    if (defLine == 0) {
      return null;
    }
    return new CodePosition(jCls, defLine, 0);
  }

  public Integer getSourceLine(int decompiledLine) {
    decompile();
    return cls.getCode().getLineMapping().get(decompiledLine);
  }

  @Override
  public String getName() {
    return cls.getShortName();
  }

  @Override
  public String getFullName() {
    return cls.getFullName();
  }

  public String getPackage() {
    return cls.getPackage();
  }

  @Override
  public JavaClass getDeclaringClass() {
    return parent;
  }

  public AccessInfo getAccessInfo() {
    return cls.getAccessFlags();
  }

  public List<JavaClass> getInnerClasses() {
    decompile();
    return innerClasses;
  }

  public List<JavaField> getFields() {
    decompile();
    return fields;
  }

  public List<JavaMethod> getMethods() {
    decompile();
    return methods;
  }

  public int getDecompiledLine() {
    return cls.getDecompiledLine();
  }

  @Override
  public boolean equals(Object o) {
    return this == o || o instanceof JavaClass && cls.equals(((JavaClass) o).cls);
  }

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

  @Override
  public String toString() {
    return getFullName();
  }
}
TOP

Related Classes of jadx.api.JavaClass

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.