private void includeDefaultDependencies(DependencyAgent agent) { agent.linkMethod(JavaScriptConvGenerator.fromJsMethod).use(); agent.linkMethod(JavaScriptConvGenerator.toJsMethod).use(); agent.linkMethod(JavaScriptConvGenerator.intValueMethod).propagate(0, Integer.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfIntMethod).use(); agent.linkMethod(JavaScriptConvGenerator.booleanValueMethod).propagate(0, Boolean.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfBooleanMethod).use(); agent.linkMethod(JavaScriptConvGenerator.doubleValueMethod).propagate(0, Double.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfDoubleMethod).use(); agent.linkMethod(JavaScriptConvGenerator.charValueMethod).propagate(0, Character.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfCharMethod).use(); agent.linkMethod(JavaScriptConvGenerator.byteValueMethod).propagate(0, Byte.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfByteMethod).use(); agent.linkMethod(JavaScriptConvGenerator.shortValueMethod).propagate(0, Short.class).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfShortMethod).use(); agent.linkMethod(JavaScriptConvGenerator.valueOfLongMethod).use(); allClassesNode.propagate(agent.getType("java.lang.Integer")); allClassesNode.propagate(agent.getType("java.lang.Float")); allClassesNode.propagate(agent.getType("java.lang.Double")); allClassesNode.propagate(agent.getType("java.lang.String")); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReference ref = method.getReference(); Set<MethodReference> callbackMethods = repository.callbackMethods.get(ref); if (callbackMethods != null) { for (MethodReference callbackMethod : callbackMethods) { agent.linkMethod(callbackMethod).addLocation(new CallLocation(ref)).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 methodReached(DependencyAgent agent, MethodDependency method) { MethodDependency addMethod = agent.linkMethod(new MethodReference(PlatformQueue.class, "wrap", Object.class, PlatformObject.class)); addMethod.getVariable(1).connect(method.getResult()); }
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(); } } } }); } }
@Override public void classReached(DependencyAgent agent, String className) { for (MethodReader reader : agent.getClassSource().get(className).getMethods()) { AnnotationReader annotation = reader.getAnnotations().get(Export.class.getName()); if (annotation != null) { agent.linkMethod(reader.getReference()).use(); } } }
private void reachFunctorMethods(DependencyAgent agent, String type) { ClassReader cls = agent.getClassSource().get(type); if (cls != null) { for (MethodReader method : cls.getMethods()) { if (!method.hasModifier(ElementModifier.STATIC)) { agent.linkMethod(method.getReference()).use(); } } } }
private void attachConstructor(DependencyAgent agent, String type, CallLocation location) { MethodReference ref = new MethodReference(type, "<init>", ValueType.VOID); MethodDependency methodDep = agent.linkMethod(ref); methodDep.addLocation(location); methodDep.getVariable(0).propagate(agent.getType(type)); methodDep.use(); } }
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) { MethodReference ref = method.getReference(); if (ref.getClassName().equals(Platform.class.getName()) && ref.getName().equals("lookupClass")) { allClasses.addConsumer(type -> { ClassReader cls = agent.getClassSource().get(type.getName()); if (cls == null) { return; } MethodReader initMethod = cls.getMethod(new MethodDescriptor("<clinit>", void.class)); if (initMethod != null) { MethodDependency initDep = agent.linkMethod(initMethod.getReference()); method.addLocationListener(initDep::addLocation); initDep.use(); } }); } } }
@Override public void classReached(DependencyAgent agent, String className) { ClassReader cls = agent.getClassSource().get(className); for (MethodReader method : cls.getMethods()) { AnnotationReader exposeAnnot = method.getAnnotations().get(JSMethodToExpose.class.getName()); if (exposeAnnot != null) { MethodDependency methodDep = agent.linkMethod(method.getReference()); methodDep.getVariable(0).propagate(agent.getType(className)); 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"); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { MethodReference ref = method.getReference(); if (ref.getClassName().equals("java.util.ServiceLoader") && ref.getName().equals("loadServices")) { List<ServiceLoaderFilter> filters = getFilters(agent); method.getResult().propagate(agent.getType("[Ljava/lang/Object;")); DependencyNode sourceNode = agent.linkMethod(LOAD_METHOD).getVariable(1).getClassValueNode(); sourceNode.connect(method.getResult().getArrayItem()); sourceNode.addConsumer(type -> { CallLocation location = new CallLocation(LOAD_METHOD); for (String implementationType : getImplementations(type.getName())) { if (filters.stream().anyMatch(filter -> !filter.apply(type.getName(), implementationType))) { continue; } serviceMap.computeIfAbsent(type.getName(), k -> new ArrayList<>()).add(implementationType); MethodReference ctor = new MethodReference(implementationType, new MethodDescriptor("<init>", ValueType.VOID)); agent.linkMethod(ctor).addLocation(location).use(); method.getResult().getArrayItem().propagate(agent.getType(implementationType)); } }); } }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { AnnotationReader delegateAnnot = method.getMethod().getAnnotations().get(DelegateTo.class.getName()); if (delegateAnnot != null) { String delegateMethodName = delegateAnnot.getValue("value").getString(); ClassReader cls = agent.getClassSource().get(method.getReference().getClassName()); for (MethodReader delegate : cls.getMethods()) { if (delegate.getName().equals(delegateMethodName)) { if (delegate != method.getMethod()) { MethodDependency dep = agent.linkMethod(delegate.getReference()); dep.use(); method.addLocationListener(dep::addLocation); } } } } }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { AnnotationReader delegateAnnot = method.getMethod().getAnnotations().get(DelegateTo.class.getName()); if (delegateAnnot != null) { String delegateMethodName = delegateAnnot.getValue("value").getString(); ClassReader cls = agent.getClassSource().get(method.getReference().getClassName()); for (MethodReader delegate : cls.getMethods()) { if (delegate.getName().equals(delegateMethodName)) { if (delegate != method.getMethod()) { MethodDependency delegateDep = agent.linkMethod(delegate.getReference()); method.addLocationListener(delegateDep::addLocation); delegateDep.use(); } } } } }
private void handleNewInstance(DependencyAgent agent, MethodDependency method) { CallLocation location = new CallLocation(method.getReference()); DependencyNode classValueNode = agent.linkMethod(getConstructors) .addLocation(location) .getVariable(0).getClassValueNode(); classValueNode.addConsumer(reflectedType -> { if (reflectedType.getName().startsWith("[")) { return; } Set<MethodDescriptor> accessibleMethods = getAccessibleMethods(agent, reflectedType.getName()); ClassReader cls = agent.getClassSource().get(reflectedType.getName()); for (MethodDescriptor methodDescriptor : accessibleMethods) { MethodReader calledMethod = cls.getMethod(methodDescriptor); MethodDependency calledMethodDep = agent.linkMethod(calledMethod.getReference()).addLocation(location); calledMethodDep.use(); for (int i = 0; i < calledMethod.parameterCount(); ++i) { propagateSet(agent, methodDescriptor.parameterType(i), method.getVariable(1).getArrayItem(), calledMethodDep.getVariable(i + 1), location); } calledMethodDep.getVariable(0).propagate(reflectedType); linkClassIfNecessary(agent, calledMethod, location); } }); classValueNode.connect(method.getResult()); }
@Override public void methodReached(DependencyAgent agent, MethodDependency method) { if (method.getReference().getClassName().equals(Platform.class.getName()) && method.getReference().getName().equals("getEnumConstants")) { allEnums.connect(method.getResult().getArrayItem()); final MethodReference ref = method.getReference(); allEnums.addConsumer(type -> { ClassReader cls = agent.getClassSource().get(type.getName()); MethodReader valuesMethod = cls.getMethod(new MethodDescriptor("values", ValueType.arrayOf(ValueType.object(cls.getName())))); if (valuesMethod != null) { MethodDependency valuesDep = agent.linkMethod(valuesMethod.getReference()); valuesDep.addLocation(new CallLocation(ref)); valuesDep.use(); } }); method.getResult().propagate(agent.getType("[Ljava/lang/Enum;")); for (String cls : agent.getReachableClasses()) { classReached(agent, cls); } } } }
@Override public void consume(DependencyType type) { if (!agent.getClassHierarchy().isSuperType(superMethod.getClassName(), type.getName(), false)) { return; } MethodReader method = agent.getClassSource().resolveImplementation(new MethodReference( type.getName(), superMethod.getDescriptor())); if (method == null) { return; } virtualMethods.add(method.getReference()); MethodDependency methodDep = agent.linkMethod(method.getReference()); methodDep.use(); for (int i = 0; i < methodDep.getParameterCount(); ++i) { allClassesNode.connect(methodDep.getVariable(i)); allClassesNode.connect(methodDep.getVariable(i).getArrayItem()); } } }
private void handleFieldSet(DependencyAgent agent, MethodDependency method) { CallLocation location = new CallLocation(method.getReference()); DependencyNode classValueNode = agent.linkMethod(getFields) .addLocation(location) .getVariable(0).getClassValueNode(); classValueNode.addConsumer(reflectedType -> { if (reflectedType.getName().startsWith("[")) { return; } Set<String> accessibleFields = getAccessibleFields(agent, reflectedType.getName()); ClassReader cls = agent.getClassSource().get(reflectedType.getName()); for (String fieldName : accessibleFields) { FieldReader field = cls.getField(fieldName); FieldDependency fieldDep = agent.linkField(field.getReference()).addLocation(location); propagateSet(agent, field.getType(), method.getVariable(2), fieldDep.getValue(), location); linkClassIfNecessary(agent, field, location); } }); }
private void handleFieldGet(DependencyAgent agent, MethodDependency method) { CallLocation location = new CallLocation(method.getReference()); DependencyNode classValueNode = agent.linkMethod(getFields) .addLocation(location) .getVariable(0).getClassValueNode(); classValueNode.addConsumer(reflectedType -> { if (reflectedType.getName().startsWith("[")) { return; } Set<String> accessibleFields = getAccessibleFields(agent, reflectedType.getName()); ClassReader cls = agent.getClassSource().get(reflectedType.getName()); for (String fieldName : accessibleFields) { FieldReader field = cls.getField(fieldName); FieldDependency fieldDep = agent.linkField(field.getReference()) .addLocation(location); propagateGet(agent, field.getType(), fieldDep.getValue(), method.getResult(), location); linkClassIfNecessary(agent, field, location); } }); }