/** * Given a context sensitive caller, i.e., another MethodFlowsGraph, identify the InvokeTypeFlow * belonging to the caller that linked to this callee. * * @param callerFlowGraph the context sensitive caller. * @return the InvokeTypeFlow object belonging to the caller that linked to this callee. */ public InvokeTypeFlow invokeFlow(MethodFlowsGraph callerFlowGraph, BigBang bb) { for (InvokeTypeFlow callerInvoke : callerFlowGraph.getInvokeFlows()) { for (MethodFlowsGraph calleeFlowGraph : callerInvoke.getCalleesFlows(bb)) { // 'this' method graph was found among the callees of an invoke flow in the caller // method clone, hence we register return it if (calleeFlowGraph.equals(this)) { return callerInvoke; } } } return null; }
/** * Get the list of all context sensitive callers. * * @return a list containing all the callers for the given context sensitive method */ public List<MethodFlowsGraph> callers(BigBang bb) { /* * This list is seldom needed thus it is created lazily instead of storing a mapping from a * caller context to a caller graph for each method graph. * * TODO cache the result */ List<MethodFlowsGraph> callers = new ArrayList<>(); for (AnalysisMethod caller : method.getJavaInvocations()) { for (MethodFlowsGraph callerFlowGraph : caller.getTypeFlow().getFlows()) { for (InvokeTypeFlow callerInvoke : callerFlowGraph.getInvokeFlows()) { for (MethodFlowsGraph calleeFlowGraph : callerInvoke.getCalleesFlows(bb)) { // 'this' method graph was found among the callees of an invoke flow in one // of the clones of the caller methods, hence we regiter that clone as a // caller for 'this' method clone if (calleeFlowGraph.equals(this)) { callers.add(callerFlowGraph); } } } } } return callers; }