public virtual void Visit(Dafny.Program program) { foreach (var module in program.Modules()) { Visit(module); } }
static Graph <Function> BuildFunctionCallGraph(Dafny.Program program) { Graph <Function> functionCallGraph = new Graph <Function>(); FunctionCallFinder callFinder = new FunctionCallFinder(); foreach (var module in program.Modules()) { foreach (var decl in module.TopLevelDecls) { if (decl is ClassDecl) { var c = (ClassDecl)decl; foreach (var member in c.Members) { if (member is Function) { var f = (Function)member; List <Function> calls = new List <Function>(); foreach (var e in f.Reads) { if (e != null && e.E != null) { callFinder.Visit(e.E, calls); } } foreach (var e in f.Req) { if (e != null) { callFinder.Visit(e, calls); } } foreach (var e in f.Ens) { if (e != null) { callFinder.Visit(e, calls); } } if (f.Body != null) { callFinder.Visit(f.Body, calls); } foreach (var callee in calls) { functionCallGraph.AddEdge(f, callee); } } } } } } return(functionCallGraph); }
public CompilationUnit ProcessProgram(Dafny.Program program) { _cancellationToken.ThrowIfCancellationRequested(); var compilationUnit = new CompilationUnit(program); // program.CompileModules would probably more suitable here, since we want the symbols of the System module as well. // However, it appears that the AST of program.CompileModules does not hold the correct location of the nodes - at least of the declarations. foreach (var module in program.Modules()) { compilationUnit.Modules.Add(ProcessModule(compilationUnit, module)); } compilationUnit.Modules.Add(ProcessModule(compilationUnit, program.BuiltIns.SystemModule)); return(compilationUnit); }
/// <summary> /// Compute various interesting statistics about the Dafny program /// </summary> public static void PrintStats(Dafny.Program program) { SortedDictionary <string, ulong> stats = new SortedDictionary <string, ulong>(); foreach (var module in program.Modules()) { IncrementStat(stats, "Modules"); UpdateMax(stats, "Module height (max)", (ulong)module.Height); ulong num_scc = (ulong)module.CallGraph.TopologicallySortedComponents().Count; UpdateMax(stats, "Call graph width (max)", num_scc); foreach (var decl in module.TopLevelDecls) { if (decl is DatatypeDecl) { IncrementStat(stats, "Datatypes"); } else if (decl is ClassDecl) { var c = (ClassDecl)decl; if (c.Name != "_default") { IncrementStat(stats, "Classes"); } foreach (var member in c.Members) { if (member is Function) { IncrementStat(stats, "Functions (total)"); var f = (Function)member; if (f.IsRecursive) { IncrementStat(stats, "Functions recursive"); } } else if (member is Method) { IncrementStat(stats, "Methods (total)"); var method = (Method)member; if (method.IsRecursive) { IncrementStat(stats, "Methods recursive"); } if (method.IsGhost) { IncrementStat(stats, "Methods ghost"); } } } } } } // Print out the results, with some nice formatting Console.WriteLine(""); Console.WriteLine("Statistics"); Console.WriteLine("----------"); int max_key_length = 0; foreach (var key in stats.Keys) { if (key.Length > max_key_length) { max_key_length = key.Length; } } foreach (var keypair in stats) { string keyString = keypair.Key.PadRight(max_key_length + 2); Console.WriteLine("{0} {1,4}", keyString, keypair.Value); } }