/** Returns a list of direct subclasses of c, including c. */ public List<SootClass> getDirectSubclassesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) { throw new RuntimeException("class needed!"); } checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(classToDirSubclasses.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct subinterfaces of c, including itself. */ public List<SootClass> getDirectSubinterfacesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) { throw new RuntimeException("interface needed!"); } checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(interfaceToDirSubinterfaces.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct implementers of c, excluding itself. */ public List<SootClass> getDirectImplementersOf(SootClass i) { i.checkLevel(SootClass.HIERARCHY); if (!i.isInterface()) { throw new RuntimeException("interface needed; got " + i); } checkState(); return Collections.unmodifiableList(interfaceToDirImplementers.get(i)); }
/** Returns a list of direct subclasses of c, excluding c. */ public List<SootClass> getDirectSubclassesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) { throw new RuntimeException("class needed!"); } checkState(); return Collections.unmodifiableList(classToDirSubclasses.get(c)); }
/** Returns a list of direct subinterfaces of c. */ public List<SootClass> getDirectSubinterfacesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) { throw new RuntimeException("interface needed!"); } checkState(); return interfaceToDirSubinterfaces.get(c); }
/** Returns a list of superinterfaces of c, excluding itself. */ public List<SootClass> getSuperinterfacesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) { throw new RuntimeException("interface needed!"); } checkState(); // If already cached, return the value. List<SootClass> cached = interfaceToSuperinterfaces.get(c); if (cached != null) { return cached; } // Otherwise, build up the hashmap. List<SootClass> l = new ArrayList<SootClass>(); for (SootClass si : interfaceToDirSuperinterfaces.get(c)) { l.addAll(getSuperinterfacesOfIncluding(si)); } interfaceToSuperinterfaces.put(c, Collections.unmodifiableList(l)); return Collections.unmodifiableList(l); }
/** Returns a list of subclasses of c, excluding itself. */ public List<SootClass> getSubclassesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) { throw new RuntimeException("class needed!"); } checkState(); // If already cached, return the value. if (classToSubclasses.get(c) != null) { return classToSubclasses.get(c); } // Otherwise, build up the hashmap. List<SootClass> l = new ArrayList<SootClass>(); for (SootClass cls : classToDirSubclasses.get(c)) { if (cls.resolvingLevel() < SootClass.HIERARCHY) { continue; } l.addAll(getSubclassesOfIncluding(cls)); } l = Collections.unmodifiableList(l); classToSubclasses.put(c, l); return l; }
/** Returns a list of implementers of c, excluding itself. */ public List<SootClass> getImplementersOf(SootClass i) { i.checkLevel(SootClass.HIERARCHY); if (!i.isInterface()) { throw new RuntimeException("interface needed; got " + i); } checkState(); ArraySet<SootClass> set = new ArraySet<SootClass>(); for (SootClass c : getSubinterfacesOfIncluding(i)) { set.addAll(getDirectImplementersOf(c)); } ArrayList<SootClass> l = new ArrayList<SootClass>(); l.addAll(set); return Collections.unmodifiableList(l); }
/** * Returns a list of <strong>direct</strong> superclasses of passed class in reverse order, starting with its parent. * * @param sootClass * the <strong>class</strong> of which superclasses will be taken. Must not be {@code null} or interface * @return list of superclasses * @throws IllegalArgumentException * when passed class is an interface * @throws NullPointerException * when passed argument is {@code null} */ public List<SootClass> getSuperclassesOf(SootClass sootClass) { sootClass.checkLevel(SootClass.HIERARCHY); if (sootClass.isInterface()) { throw new IllegalArgumentException(sootClass.getName() + " is an interface, but class is expected"); } checkState(); final List<SootClass> superclasses = new ArrayList<>(); SootClass current = sootClass; while (current.hasSuperclass()) { superclasses.add(current.getSuperclass()); current = current.getSuperclass(); } return Collections.unmodifiableList(superclasses); }
/** * Given a set of definite receiver types, returns a list of possible targets. */ public List<SootMethod> resolveConcreteDispatch(List<Type> classes, SootMethod m) { m.getDeclaringClass().checkLevel(SootClass.HIERARCHY); checkState(); Set<SootMethod> s = new ArraySet<SootMethod>(); for (Type cls : classes) { if (cls instanceof RefType) { s.add(resolveConcreteDispatch(((RefType) cls).getSootClass(), m)); } else if (cls instanceof ArrayType) { s.add(resolveConcreteDispatch((RefType.v("java.lang.Object")).getSootClass(), m)); } else { throw new RuntimeException("Unable to resolve concrete dispatch of type " + cls); } } return Collections.unmodifiableList(new ArrayList<SootMethod>(s)); }
/** * Given an object of actual type C (o = new C()), returns the method which will be called on an o.f() invocation. */ public SootMethod resolveConcreteDispatch(SootClass concreteType, SootMethod m) { concreteType.checkLevel(SootClass.HIERARCHY); m.getDeclaringClass().checkLevel(SootClass.HIERARCHY); checkState(); if (concreteType.isInterface()) { throw new RuntimeException("class needed!"); } String methodSig = m.getSubSignature(); for (SootClass c : getSuperclassesOfIncluding(concreteType)) { SootMethod sm = c.getMethodUnsafe(methodSig); if (sm != null && isVisible(c, m)) { return sm; } } throw new RuntimeException("could not resolve concrete dispatch!\nType: " + concreteType + "\nMethod: " + m); }
/** * Given an abstract dispatch to an object of type c and a method m, gives a list of possible receiver methods. */ public List<SootMethod> resolveAbstractDispatch(SootClass c, SootMethod m) { c.checkLevel(SootClass.HIERARCHY); m.getDeclaringClass().checkLevel(SootClass.HIERARCHY); checkState(); Set<SootMethod> s = new ArraySet<SootMethod>(); Collection<SootClass> classesIt; if (c.isInterface()) { Set<SootClass> classes = new HashSet<SootClass>(); for (SootClass sootClass : getImplementersOf(c)) { classes.addAll(getSubclassesOfIncluding(sootClass)); } classesIt = classes; } else { classesIt = getSubclassesOfIncluding(c); } for (SootClass cl : classesIt) { if (!Modifier.isAbstract(cl.getModifiers())) { s.add(resolveConcreteDispatch(cl, m)); } } return Collections.unmodifiableList(new ArrayList<SootMethod>(s)); }
/** Returns a list of direct subinterfaces of c, including itself. */ public List<SootClass> getDirectSubinterfacesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) throw new RuntimeException("interface needed!"); checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(interfaceToDirSubinterfaces.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct subclasses of c, including c. */ public List<SootClass> getDirectSubclassesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) throw new RuntimeException("class needed!"); checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(classToDirSubclasses.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct subclasses of c, including c. */ public List<SootClass> getDirectSubclassesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) throw new RuntimeException("class needed!"); checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(classToDirSubclasses.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct subinterfaces of c, including itself. */ public List<SootClass> getDirectSubinterfacesOfIncluding(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) throw new RuntimeException("interface needed!"); checkState(); List<SootClass> l = new ArrayList<SootClass>(); l.addAll(interfaceToDirSubinterfaces.get(c)); l.add(c); return Collections.unmodifiableList(l); }
/** Returns a list of direct subclasses of c, excluding c. */ public List getDirectSubclassesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (c.isInterface()) throw new RuntimeException("class needed!"); checkState(); return Collections.unmodifiableList(classToDirSubclasses.get(c)); }
/** Returns a list of direct implementers of c, excluding itself. */ public List getDirectImplementersOf(SootClass i) { i.checkLevel(SootClass.HIERARCHY); if (!i.isInterface()) throw new RuntimeException("interface needed; got "+i); checkState(); return Collections.unmodifiableList(interfaceToDirImplementers.get(i)); }
/** Returns a list of direct subinterfaces of c. */ public List getDirectSubinterfacesOf(SootClass c) { c.checkLevel(SootClass.HIERARCHY); if (!c.isInterface()) throw new RuntimeException("interface needed!"); checkState(); return interfaceToDirSubinterfaces.get(c); }