@Override protected void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { CallLocation callLocation = getCallLocation(); if (instance == null) { dependencyAnalyzer.linkClass(method.getClassName()).initClass(callLocation); initClass(method.getClassName());
@Override protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { DependencyNode[] actualArgs = new DependencyNode[arguments.size() + 1]; for (int i = 0; i < arguments.size(); ++i) { actualArgs[i + 1] = nodes[arguments.get(i).getIndex()]; } actualArgs[0] = getNode(instance); DependencyConsumer listener = new VirtualCallConsumer(getNode(instance), method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs, receiver != null ? getNode(receiver) : null, getCallLocation(), currentExceptionConsumer); getNode(instance).addConsumer(listener); dependencyAnalyzer.getClassSource().overriddenMethods(method).forEach(methodImpl -> { dependencyAnalyzer.linkMethod(methodImpl.getReference()).addLocation(getCallLocation()); }); }
@Override public void createArray(VariableReader receiver, ValueType itemType, List<? extends VariableReader> dimensions) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < dimensions.size(); ++i) { sb.append('['); itemType = ((ValueType.Array) itemType).getItemType(); } String itemTypeStr; if (itemType instanceof ValueType.Object) { itemTypeStr = ((ValueType.Object) itemType).getClassName(); } else { itemTypeStr = itemType.toString(); } sb.append(itemTypeStr); DependencyNode node = nodes[receiver.getIndex()]; for (int i = 0; i < dimensions.size(); ++i) { if (node == null) { break; } node.propagate(dependencyChecker.getType(sb.substring(i, sb.length()))); node = node.getArrayItem(); } String className = extractClassName(itemType); if (className != null) { dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation)); } }
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments) { CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation); dependencyChecker.linkClass(method.getClassName(), callLocation).initClass(callLocation); MethodDependency methodDep = dependencyChecker.linkMethod(method, callLocation); if (methodDep.isMissing()) { return; } methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); for (int i = 0; i < arguments.size(); ++i) { DependencyNode value = nodes[arguments.get(i).getIndex()]; DependencyNode param = targetParams[i + 1]; if (value != null && param != null) { value.connect(param); } } if (instance != null) { nodes[instance.getIndex()].connect(targetParams[0]); } if (methodDep.getResult() != null && receiver != null) { DependencyNode receiverNode = nodes[receiver.getIndex()]; if (methodDep.getResult() != null && receiverNode != null) { methodDep.getResult().connect(receiverNode); } } methodDep.getThrown().addConsumer(currentExceptionConsumer); initClass(method.getClassName()); }
@Override public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, List<? extends VariableReader> arguments, InvocationType type) { if (instance == null) { invokeSpecial(receiver, null, method, arguments); } else { switch (type) { case SPECIAL: invokeSpecial(receiver, instance, method, arguments); break; case VIRTUAL: invokeVirtual(receiver, instance, method, arguments); break; } if (method.getName().equals("getClass") && method.parameterCount() == 0 && method.getReturnType().isObject(Class.class) && receiver != null) { nodes[instance.getIndex()].connect(nodes[receiver.getIndex()].getClassValueNode()); } } }
@Override public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { FieldDependency fieldDep = dependencyChecker.linkField(field, new CallLocation(caller.getMethod(), currentLocation)); if (!(fieldType instanceof ValueType.Primitive)) { DependencyNode valueNode = nodes[value.getIndex()]; if (valueNode != null) { valueNode.connect(fieldDep.getValue()); } } initClass(field.getClassName()); }
@Override public void isInstance(VariableReader receiver, VariableReader value, final ValueType type) { String className = extractClassName(type); if (className != null) { dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation)); } }
@Override public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { DependencyNode node = nodes[receiver.getIndex()]; if (node != null) { node.propagate(dependencyChecker.getType("[" + itemType)); } String className = extractClassName(itemType); if (className != null) { dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation)); } }
@Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { FieldDependency fieldDep = dependencyChecker.linkField(field, new CallLocation(caller.getMethod(), currentLocation)); if (!(fieldType instanceof ValueType.Primitive)) { DependencyNode receiverNode = nodes[receiver.getIndex()]; if (receiverNode != null) { fieldDep.getValue().connect(receiverNode); } } initClass(field.getClassName()); }
@Override public void getElement(VariableReader receiver, VariableReader array, VariableReader index, ArrayElementType type) { if (isPrimitive(type)) { return; } DependencyNode arrayNode = nodes[array.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; if (arrayNode != null && receiverNode != null && receiverNode != arrayNode.getArrayItem()) { arrayNode.getArrayItem().connect(receiverNode); } }
@Override public void putElement(VariableReader array, VariableReader index, VariableReader value, ArrayElementType type) { if (isPrimitive(type)) { return; } DependencyNode valueNode = nodes[value.getIndex()]; DependencyNode arrayNode = nodes[array.getIndex()]; if (valueNode != null && arrayNode != null && valueNode != arrayNode.getArrayItem()) { valueNode.connect(arrayNode.getArrayItem()); } }
@Override public void cloneArray(VariableReader receiver, VariableReader array) { DependencyNode arrayNode = getNode(array); DependencyNode receiverNode = getNode(receiver); if (arrayNode != null && receiverNode != null) { arrayNode.addConsumer(receiverNode::propagate); arrayNode.getArrayItem().connect(receiverNode.getArrayItem()); } MethodDependency cloneDep = getAnalyzer().linkMethod(CLONE_METHOD); cloneDep.addLocation(getCallLocation()); arrayNode.connect(cloneDep.getVariable(0)); cloneDep.use(); }