depends.nim 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # This module implements a dependency file generator.
  10. import
  11. options, ast, ropes, idents, passes, modulepaths, pathutils
  12. from modulegraphs import ModuleGraph, PPassContext
  13. type
  14. TGen = object of PPassContext
  15. module: PSym
  16. config: ConfigRef
  17. graph: ModuleGraph
  18. PGen = ref TGen
  19. Backend = ref object of RootRef
  20. dotGraph: Rope
  21. proc addDependencyAux(b: Backend; importing, imported: string) =
  22. b.dotGraph.addf("$1 -> \"$2\";$n", [rope(importing), rope(imported)])
  23. # s1 -> s2_4[label="[0-9]"];
  24. proc addDotDependency(c: PPassContext, n: PNode): PNode =
  25. result = n
  26. let g = PGen(c)
  27. let b = Backend(g.graph.backend)
  28. case n.kind
  29. of nkImportStmt:
  30. for i in 0..<n.len:
  31. var imported = getModuleName(g.config, n[i])
  32. addDependencyAux(b, g.module.name.s, imported)
  33. of nkFromStmt, nkImportExceptStmt:
  34. var imported = getModuleName(g.config, n[0])
  35. addDependencyAux(b, g.module.name.s, imported)
  36. of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
  37. for i in 0..<n.len: discard addDotDependency(c, n[i])
  38. else:
  39. discard
  40. proc generateDot*(graph: ModuleGraph; project: AbsoluteFile) =
  41. let b = Backend(graph.backend)
  42. discard writeRope("digraph $1 {$n$2}$n" % [
  43. rope(project.splitFile.name), b.dotGraph],
  44. changeFileExt(project, "dot"))
  45. when not defined(nimHasSinkInference):
  46. {.pragma: nosinks.}
  47. proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
  48. var g: PGen
  49. new(g)
  50. g.module = module
  51. g.config = graph.config
  52. g.graph = graph
  53. if graph.backend == nil:
  54. graph.backend = Backend(dotGraph: nil)
  55. result = g
  56. const gendependPass* = makePass(open = myOpen, process = addDotDependency)