/// <summary> /// try to get /// (1) local calling graph, where only local function calls are considered /// (2) process function order ( reverse order of topological order of the calling graph) /// (3) external function call list for every function /// </summary> /// <param name="callGraph"></param> /// <param name="topologicRes"></param> private void TrySetLocalCallingGraph(out CallGraph callGraph, out IEnumerable <string> topologicRes) { callGraph = new CallGraph(); foreach (var kvPair in MethodMetadataTemplates) { callGraph.AddVertex(kvPair.Key); foreach (var calledFunc in kvPair.Value.CallingSet) { if (calledFunc.StartsWith(Replacement.This)) { callGraph.AddVerticesAndEdge(new Edge <string>(kvPair.Key, calledFunc)); } else { if (!ExternalFuncCall.TryGetValue(kvPair.Key, out var callingList)) { callingList = new List <string>(); ExternalFuncCall.Add(kvPair.Key, callingList); } callingList.Add(calledFunc); } } } try { topologicRes = callGraph.TopologicalSort(); } catch (NonAcyclicGraphException) { callGraph.Clear(); callGraph = null; topologicRes = null; throw new FunctionMetadataException($"Calling graph of contract {FullName} is Non-DAG thus nothing take effect"); } }