diff --git a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java index 55f32945..a23b90a3 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/immutable/ImmutableClassDef.java @@ -33,12 +33,15 @@ package org.jf.dexlib2.immutable; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import org.jf.dexlib2.base.reference.BaseTypeReference; import org.jf.dexlib2.iface.Annotation; import org.jf.dexlib2.iface.ClassDef; import org.jf.dexlib2.iface.Field; import org.jf.dexlib2.iface.Method; +import org.jf.dexlib2.util.FieldUtil; +import org.jf.dexlib2.util.MethodUtil; import org.jf.util.ImmutableConverter; import org.jf.util.ImmutableUtils; @@ -60,6 +63,26 @@ public class ImmutableClassDef extends BaseTypeReference implements ClassDef { @Nonnull protected final ImmutableSortedSet directMethods; @Nonnull protected final ImmutableSortedSet virtualMethods; + public ImmutableClassDef(@Nonnull String type, + int accessFlags, + @Nullable String superclass, + @Nullable Collection interfaces, + @Nullable String sourceFile, + @Nullable Collection annotations, + @Nullable Iterable fields, + @Nullable Iterable methods) { + this.type = type; + this.accessFlags = accessFlags; + this.superclass = superclass; + this.interfaces = interfaces==null ? ImmutableSet.of() : ImmutableSet.copyOf(interfaces); + this.sourceFile = sourceFile; + this.annotations = ImmutableAnnotation.immutableSetOf(annotations); + this.staticFields = ImmutableField.immutableSetOf(Iterables.filter(fields, FieldUtil.FIELD_IS_STATIC)); + this.instanceFields = ImmutableField.immutableSetOf(Iterables.filter(fields, FieldUtil.FIELD_IS_INSTANCE)); + this.directMethods = ImmutableMethod.immutableSetOf(Iterables.filter(methods, MethodUtil.METHOD_IS_DIRECT)); + this.virtualMethods = ImmutableMethod.immutableSetOf(Iterables.filter(methods, MethodUtil.METHOD_IS_VIRTUAL)); + } + public ImmutableClassDef(@Nonnull String type, int accessFlags, @Nullable String superclass, diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/FieldUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/FieldUtil.java index e00da0e8..c87e6c35 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/FieldUtil.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/FieldUtil.java @@ -31,12 +31,26 @@ package org.jf.dexlib2.util; +import com.google.common.base.Predicate; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.iface.Field; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public final class FieldUtil { + public static Predicate FIELD_IS_STATIC = new Predicate() { + @Override public boolean apply(@Nullable Field input) { + return input!=null && isStatic(input); + } + }; + + public static Predicate FIELD_IS_INSTANCE = new Predicate() { + @Override public boolean apply(@Nullable Field input) { + return input!= null && !isStatic(input); + } + }; + public static boolean isStatic(@Nonnull Field field) { return AccessFlags.STATIC.isSet(field.getAccessFlags()); } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java b/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java index 09c39d2b..869698ad 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/MethodUtil.java @@ -31,16 +31,30 @@ package org.jf.dexlib2.util; +import com.google.common.base.Predicate; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.iface.Method; import org.jf.dexlib2.iface.reference.MethodReference; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public final class MethodUtil { private static int directMask = AccessFlags.STATIC.getValue() | AccessFlags.PRIVATE.getValue() | AccessFlags.CONSTRUCTOR.getValue(); + public static Predicate METHOD_IS_DIRECT = new Predicate() { + @Override public boolean apply(@Nullable Method input) { + return input != null && isDirect(input); + } + }; + + public static Predicate METHOD_IS_VIRTUAL = new Predicate() { + @Override public boolean apply(@Nullable Method input) { + return input != null && !isDirect(input); + } + }; + public static boolean isDirect(@Nonnull Method method) { return (method.getAccessFlags() & directMask) != 0; }