@Override public boolean match(DependencyType type) { if (cache >= 0) { return type.index == cache; } boolean result = typeName.equals(type.getName()); if (result) { cache = type.index; } return result; } }
public DependencyType getType(String name) { DependencyType type = typeMap.get(name); if (type == null) { type = new DependencyType(this, name, types.size()); types.add(type); typeMap.put(name, type); if (!name.startsWith("[") && !name.startsWith("~")) { markSupertypesAsHavingSubtypes(name); } } return type; }
public void propagate(DependencyType type) { if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); } if (degree > 2) { return; } if (addType(type)) { if (DependencyChecker.shouldLog) { System.out.println(tag + " -> " + type.getName()); } if (followers != null) { for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { dependencyChecker.schedulePropagation(consumer, type); } } if (transitions != null) { for (DependencyConsumer consumer : transitions.toArray(new DependencyConsumer[transitions.size()])) { dependencyChecker.schedulePropagation(consumer, type); } } } }
public boolean hasType(DependencyType type) { if (smallTypes != null) { for (int i = 0; i < smallTypes.length; ++i) { if (smallTypes[i] == type.index) { return true; } } return false; } return types != null && type.getDependencyChecker() == dependencyChecker && types.get(type.index); }
for (int i = 0; i < newTypes.length; ++i) { DependencyType type = newTypes[i]; if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); System.out.println(tag + " -> " + types[i].getName());
@Override public boolean match(DependencyType type) { if (!superType.subtypeExists) { return superType.index == type.index; } if (knownTypes.get(type.index)) { return cache.get(type.index); } boolean result = predicate.test(type.getName(), false); knownTypes.set(type.index); cache.set(type.index, result); return result; }
public DependencyType getType(String name) { DependencyType type = typeMap.get(name); if (type == null) { type = new DependencyType(this, name, types.size()); types.add(type); typeMap.put(name, type); } return type; }
private boolean matchCacheMiss(DependencyType type) { if (!type.getName().startsWith("[")) { return false; } String typeName = type.getName().substring(1); ValueType valueType = ValueType.parseIfPossible(typeName); if (valueType == null || valueType instanceof ValueType.Primitive) { return false; } if (valueType instanceof ValueType.Object) { typeName = ((ValueType.Object) valueType).getClassName(); } return itemTypeFilter.match(analyzer.getType(typeName)); }
@Override public String[] getTypes() { if (typeSet == null) { return new String[0]; } DependencyType[] types = typeSet.getTypes(); String[] result = new String[types.length]; int i = 0; for (DependencyType type : types) { if (filter(type)) { result[i++] = type.getName(); } } return i == result.length ? result : Arrays.copyOf(result, i); }
SuperClassFilter(DependencyAnalyzer dependencyAnalyzer, DependencyType superType) { this.superType = superType; predicate = dependencyAnalyzer.getClassHierarchy().getSuperclassPredicate(superType.getName()); }
@Override public int[] tryExtract(BitSet types) { int[] result = itemTypeFilter.tryExtract(types); if (result == null) { return null; } for (int i = 0; i < result.length; ++i) { String name = analyzer.types.get(i).getName(); int mapped; if (name.startsWith("[")) { mapped = analyzer.getType("[" + name).index; } else if (name.startsWith("~")) { mapped = analyzer.getType("[" + name.substring(1)).index; } else { mapped = analyzer.getType(ValueType.arrayOf(ValueType.object(name)).toString()).index; } result[i] = mapped; } return result; } }
private void reachGetComponentType(DependencyAgent agent, MethodDependency method) { method.getVariable(0).getClassValueNode().addConsumer(t -> { if (!t.getName().startsWith("[")) { return; } String typeName = t.getName().substring(1); if (typeName.charAt(0) == 'L') { typeName = ((ValueType.Object) ValueType.parse(typeName)).getClassName(); } method.getResult().getClassValueNode().propagate(agent.getType(typeName)); }); }
private void reachSet(DependencyAgent agent, MethodDependency method) { method.getVariable(3).connect(method.getVariable(1).getArrayItem()); method.getVariable(1).addConsumer(type -> { if (type.getName().startsWith("[")) { String typeName = type.getName().substring(1); for (int i = 0; i < primitiveTypes.length; ++i) { if (primitiveTypes[i].toString().equals(typeName)) { String wrapper = "java.lang." + primitiveWrappers[i]; MethodReference methodRef = new MethodReference(wrapper, primitives[i].toLowerCase() + "Value", primitiveTypes[i]); agent.linkMethod(methodRef).use(); } } } }); } }
private void reachGetLength(DependencyAgent agent, MethodDependency method) { method.getVariable(1).addConsumer(type -> { if (!type.getName().startsWith("[")) { MethodReference cons = new MethodReference(IllegalArgumentException.class, "<init>", void.class); agent.linkMethod(cons).use(); } }); }
@Override public void consume(DependencyType type) { String className = type.getName(); if (DependencyAnalyzer.shouldLog) { System.out.println("Virtual call of " + methodDesc + " detected on " + node.getTag() + ". " + "Target class is " + className); } if (className.startsWith("[")) { className = "java.lang.Object"; type = analyzer.getType(className); } MethodDependency methodDep = analyzer.linkMethod(className, methodDesc); if (!methods.add(methodDep)) { return; } for (CallLocation location : callLocations.values()) { methodDep.addLocation(location); } if (!methodDep.isMissing()) { methodDep.use(); } }
@Override public void started(DependencyAgent agent) { allClasses = agent.createNode(); allClasses.addConsumer(c -> { if (agent.getClassSource().isSuperType("java.lang.Throwable", c.getName()).orElse(false)) { MethodDependency methodDep = agent.linkMethod(new MethodReference(c.getName(), GET_MESSAGE)); methodDep.getVariable(0).propagate(c); methodDep.use(); } }); agent.linkClass("java.lang.Throwable"); }
private void reachGet(DependencyAgent agent, MethodDependency method) { method.getVariable(1).getArrayItem().connect(method.getResult()); method.getVariable(1).addConsumer(type -> { if (type.getName().startsWith("[")) { String typeName = type.getName().substring(1); for (int i = 0; i < primitiveTypes.length; ++i) { if (primitiveTypes[i].toString().equals(typeName)) { String wrapper = "java.lang." + primitiveWrappers[i]; MethodReference methodRef = new MethodReference(wrapper, "valueOf", primitiveTypes[i], ValueType.object(wrapper)); agent.linkMethod(methodRef).use(); method.getResult().propagate(agent.getType("java.lang." + primitiveWrappers[i])); } } } }); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReader reader = method.getMethod(); if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstanceImpl")) { allClassesNode.connect(method.getResult()); MethodReference methodRef = reader.getReference(); method.getResult().addConsumer(type -> attachConstructor(agent, type.getName(), new CallLocation(methodRef))); } }
public FastDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics) { super(classSource, classLoader, services, diagnostics); instancesNode = new DependencyNode(this, null); classesNode = new DependencyNode(this, null); instancesNode.addConsumer(type -> { getSubtypeNode(type.getName()).propagate(type); }); }