private ClassDependency createClassDependency(String className) { ClassReader cls = classSource.get(className); ClassDependency dependency = new ClassDependency(this, className, cls); if (!dependency.isMissing()) { if (cls.getParent() != null && !cls.getParent().equals(className)) { linkClass(cls.getParent(), null); } for (String ifaceName : cls.getInterfaces()) { linkClass(ifaceName, null); } } return dependency; }
void initClass(ClassDependency cls, CallLocation callLocation) { ClassReader reader = cls.getClassReader(); MethodReader method = reader.getMethod(new MethodDescriptor("<clinit>", void.class)); if (method != null) { tasks.add(() -> linkMethod(method.getReference(), callLocation).use()); } }
public static Set<Class> crawl(Set<Class> todo, Set<Class> seen) { while (!todo.isEmpty()) { Class clazz = todo.iterator().next(); todo.remove(clazz); if (!seen.contains(clazz)) { seen.add(clazz); ClassDependency cd = new ClassDependency(clazz); todo.addAll(cd.getDependencies()); } } return seen; }
public ClassDependency linkClass(String className, CallLocation callLocation) { if (completing && getClass(className) == null) { throw new IllegalStateException("Can't link class during completion phase"); } ClassDependency dep = classCache.map(className); boolean added = true; if (callLocation != null && callLocation.getMethod() != null) { DefaultCallGraphNode callGraphNode = callGraph.getNode(callLocation.getMethod()); if (!addClassAccess(callGraphNode, className, callLocation.getSourceLocation())) { added = false; } } else { added = classesAddedByRoot.add(className); } if (!dep.isMissing() && added) { tasks.add( () -> { for (DependencyListener listener : listeners) { listener.classReached(agent, className, callLocation); } }); } return dep; }