aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java')
-rw-r--r--third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java584
1 files changed, 584 insertions, 0 deletions
diff --git a/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java b/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java
new file mode 100644
index 0000000000..a2137f19f1
--- /dev/null
+++ b/third_party/java/proguard/proguard5.3.3/src/proguard/classfile/ProgramClass.java
@@ -0,0 +1,584 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2017 Eric Lafortune @ GuardSquare
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile;
+
+import proguard.classfile.attribute.Attribute;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.ClassSubHierarchyInitializer;
+import proguard.classfile.visitor.*;
+
+/**
+ * This Clazz is a complete representation of the data in a Java class.
+ *
+ * @author Eric Lafortune
+ */
+public class ProgramClass implements Clazz
+{
+ public int u4magic;
+ public int u4version;
+ public int u2constantPoolCount;
+ public Constant[] constantPool;
+ public int u2accessFlags;
+ public int u2thisClass;
+ public int u2superClass;
+ public int u2interfacesCount;
+ public int[] u2interfaces;
+ public int u2fieldsCount;
+ public ProgramField[] fields;
+ public int u2methodsCount;
+ public ProgramMethod[] methods;
+ public int u2attributesCount;
+ public Attribute[] attributes;
+
+ /**
+ * An extra field pointing to the subclasses of this class.
+ * This field is filled out by the {@link ClassSubHierarchyInitializer}.
+ */
+ public Clazz[] subClasses;
+
+ /**
+ * An extra field in which visitors can store information.
+ */
+ public Object visitorInfo;
+
+
+ /**
+ * Creates an uninitialized ProgramClass.
+ */
+ public ProgramClass() {}
+
+
+ /**
+ * Returns the Constant at the given index in the constant pool.
+ */
+ public Constant getConstant(int constantIndex)
+ {
+ return constantPool[constantIndex];
+ }
+
+
+ // Implementations for Clazz.
+
+ public int getAccessFlags()
+ {
+ return u2accessFlags;
+ }
+
+ public String getName()
+ {
+ return getClassName(u2thisClass);
+ }
+
+ public String getSuperName()
+ {
+ return u2superClass == 0 ? null : getClassName(u2superClass);
+ }
+
+ public int getInterfaceCount()
+ {
+ return u2interfacesCount;
+ }
+
+ public String getInterfaceName(int index)
+ {
+ return getClassName(u2interfaces[index]);
+ }
+
+ public int getTag(int constantIndex)
+ {
+ return constantPool[constantIndex].getTag();
+ }
+
+ public String getString(int constantIndex)
+ {
+ try
+ {
+ return ((Utf8Constant)constantPool[constantIndex]).getString();
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getStringString(int constantIndex)
+ {
+ try
+ {
+ return ((StringConstant)constantPool[constantIndex]).getString(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getClassName(int constantIndex)
+ {
+ try
+ {
+ return ((ClassConstant)constantPool[constantIndex]).getName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected ClassConstant at index ["+constantIndex+"]").initCause(ex));
+ }
+ }
+
+ public String getName(int constantIndex)
+ {
+ try
+ {
+ return ((NameAndTypeConstant)constantPool[constantIndex]).getName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getType(int constantIndex)
+ {
+ try
+ {
+ return ((NameAndTypeConstant)constantPool[constantIndex]).getType(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+
+ public String getRefClassName(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getClassName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getRefName(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getRefType(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getType(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+
+ public void addSubClass(Clazz clazz)
+ {
+ if (subClasses == null)
+ {
+ subClasses = new Clazz[1];
+ }
+ else
+ {
+ // Copy the old elements into new larger array.
+ Clazz[] temp = new Clazz[subClasses.length+1];
+ System.arraycopy(subClasses, 0, temp, 0, subClasses.length);
+ subClasses = temp;
+ }
+
+ subClasses[subClasses.length-1] = clazz;
+ }
+
+
+ public Clazz getSuperClass()
+ {
+ return u2superClass != 0 ?
+ ((ClassConstant)constantPool[u2superClass]).referencedClass :
+ null;
+ }
+
+
+ public Clazz getInterface(int index)
+ {
+ return ((ClassConstant)constantPool[u2interfaces[index]]).referencedClass;
+ }
+
+
+ public boolean extends_(Clazz clazz)
+ {
+ if (this.equals(clazz))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ return superClass != null &&
+ superClass.extends_(clazz);
+ }
+
+
+ public boolean extends_(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ return superClass != null &&
+ superClass.extends_(className);
+ }
+
+
+ public boolean extendsOrImplements(Clazz clazz)
+ {
+ if (this.equals(clazz))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ if (superClass != null &&
+ superClass.extendsOrImplements(clazz))
+ {
+ return true;
+ }
+
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ Clazz interfaceClass = getInterface(index);
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(clazz))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ public boolean extendsOrImplements(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ if (superClass != null &&
+ superClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ Clazz interfaceClass = getInterface(index);
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ public Field findField(String name, String descriptor)
+ {
+ for (int index = 0; index < u2fieldsCount; index++)
+ {
+ Field field = fields[index];
+ if ((name == null || field.getName(this).equals(name)) &&
+ (descriptor == null || field.getDescriptor(this).equals(descriptor)))
+ {
+ return field;
+ }
+ }
+
+ return null;
+ }
+
+
+ public Method findMethod(String name, String descriptor)
+ {
+ for (int index = 0; index < u2methodsCount; index++)
+ {
+ Method method = methods[index];
+ if ((name == null || method.getName(this).equals(name)) &&
+ (descriptor == null || method.getDescriptor(this).equals(descriptor)))
+ {
+ return method;
+ }
+ }
+
+ return null;
+ }
+
+
+ public void accept(ClassVisitor classVisitor)
+ {
+ classVisitor.visitProgramClass(this);
+ }
+
+
+ public void hierarchyAccept(boolean visitThisClass,
+ boolean visitSuperClass,
+ boolean visitInterfaces,
+ boolean visitSubclasses,
+ ClassVisitor classVisitor)
+ {
+ // First visit the current classfile.
+ if (visitThisClass)
+ {
+ accept(classVisitor);
+ }
+
+ // Then visit its superclass, recursively.
+ if (visitSuperClass)
+ {
+ Clazz superClass = getSuperClass();
+ if (superClass != null)
+ {
+ superClass.hierarchyAccept(true,
+ true,
+ visitInterfaces,
+ false,
+ classVisitor);
+ }
+ }
+
+ // Then visit its interfaces, recursively.
+ if (visitInterfaces)
+ {
+ // Visit the interfaces of the superclasses, if we haven't done so yet.
+ if (!visitSuperClass)
+ {
+ Clazz superClass = getSuperClass();
+ if (superClass != null)
+ {
+ superClass.hierarchyAccept(false,
+ false,
+ true,
+ false,
+ classVisitor);
+ }
+ }
+
+ // Visit the interfaces.
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ Clazz interfaceClass = getInterface(index);
+ if (interfaceClass != null)
+ {
+ interfaceClass.hierarchyAccept(true,
+ false,
+ true,
+ false,
+ classVisitor);
+ }
+ }
+ }
+
+ // Then visit its subclasses, recursively.
+ if (visitSubclasses)
+ {
+ if (subClasses != null)
+ {
+ for (int index = 0; index < subClasses.length; index++)
+ {
+ Clazz subClass = subClasses[index];
+ subClass.hierarchyAccept(true,
+ false,
+ false,
+ true,
+ classVisitor);
+ }
+ }
+ }
+ }
+
+
+ public void subclassesAccept(ClassVisitor classVisitor)
+ {
+ if (subClasses != null)
+ {
+ for (int index = 0; index < subClasses.length; index++)
+ {
+ subClasses[index].accept(classVisitor);
+ }
+ }
+ }
+
+
+ public void constantPoolEntriesAccept(ConstantVisitor constantVisitor)
+ {
+ for (int index = 1; index < u2constantPoolCount; index++)
+ {
+ if (constantPool[index] != null)
+ {
+ constantPool[index].accept(this, constantVisitor);
+ }
+ }
+ }
+
+
+ public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor)
+ {
+ constantPool[index].accept(this, constantVisitor);
+ }
+
+
+ public void thisClassConstantAccept(ConstantVisitor constantVisitor)
+ {
+ constantPool[u2thisClass].accept(this, constantVisitor);
+ }
+
+
+ public void superClassConstantAccept(ConstantVisitor constantVisitor)
+ {
+ if (u2superClass != 0)
+ {
+ constantPool[u2superClass].accept(this, constantVisitor);
+ }
+ }
+
+
+ public void interfaceConstantsAccept(ConstantVisitor constantVisitor)
+ {
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ constantPool[u2interfaces[index]].accept(this, constantVisitor);
+ }
+ }
+
+
+ public void fieldsAccept(MemberVisitor memberVisitor)
+ {
+ for (int index = 0; index < u2fieldsCount; index++)
+ {
+ fields[index].accept(this, memberVisitor);
+ }
+ }
+
+
+ public void fieldAccept(String name, String descriptor, MemberVisitor memberVisitor)
+ {
+ Field field = findField(name, descriptor);
+ if (field != null)
+ {
+ field.accept(this, memberVisitor);
+ }
+ }
+
+
+ public void methodsAccept(MemberVisitor memberVisitor)
+ {
+ for (int index = 0; index < u2methodsCount; index++)
+ {
+ methods[index].accept(this, memberVisitor);
+ }
+ }
+
+
+ public void methodAccept(String name, String descriptor, MemberVisitor memberVisitor)
+ {
+ Method method = findMethod(name, descriptor);
+ if (method != null)
+ {
+ method.accept(this, memberVisitor);
+ }
+ }
+
+
+ public boolean mayHaveImplementations(Method method)
+ {
+ return
+ (u2accessFlags & ClassConstants.ACC_FINAL) == 0 &&
+ (method == null ||
+ ((method.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
+ ClassConstants.ACC_STATIC |
+ ClassConstants.ACC_FINAL)) == 0 &&
+ !method.getName(this).equals(ClassConstants.METHOD_NAME_INIT)));
+ }
+
+
+ public void attributesAccept(AttributeVisitor attributeVisitor)
+ {
+ for (int index = 0; index < u2attributesCount; index++)
+ {
+ attributes[index].accept(this, attributeVisitor);
+ }
+ }
+
+
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor)
+ {
+ for (int index = 0; index < u2attributesCount; index++)
+ {
+ Attribute attribute = attributes[index];
+ if (attribute.getAttributeName(this).equals(name))
+ {
+ attribute.accept(this, attributeVisitor);
+ }
+ }
+ }
+
+
+ // Implementations for VisitorAccepter.
+
+ public Object getVisitorInfo()
+ {
+ return visitorInfo;
+ }
+
+ public void setVisitorInfo(Object visitorInfo)
+ {
+ this.visitorInfo = visitorInfo;
+ }
+
+
+ // Implementations for Object.
+
+ public String toString()
+ {
+ return "ProgramClass("+getName()+")";
+ }
+}