# modulegraphs

Dark Mode

- Index

Search:
Group by:

This module implements the module graph data structure. The module graph represents a complete Nim project. Single modules can either be kept in RAM or stored in a Sqlite database.

The caching of modules is critical for 'nimsuggest' and is tricky to get right. If module E is being edited, we need autocompletion (and type checking) for E but we don't want to recompile depending modules right away for faster turnaround times. Instead we mark the module's dependencies as 'dirty'. Let D be a dependency of E. If D is dirty, we need to recompile it and all of its dependencies that are marked as 'dirty'. 'nimsuggest sug' actually is invoked for the file being edited so we know its content changed and there is no need to compute any checksums. Instead of a recursive algorithm, we use an iterative algorithm:

- If a module gets recompiled, its dependencies need to be updated.
- Its dependent module stays the same.

# Imports

ast, options, lineinfos, idents, incremental, btrees

# Types

    SigHash = distinct MD5Digest

  Source Edit

    ModuleGraph = ref object
      modules*: seq[PSym]        ## indexed by int32 fileIdx
      packageSyms*: TStrTable
      deps*: IntSet
      importDeps*: Table[FileIndex, seq[FileIndex]]
      suggestMode*: bool
      invalidTransitiveClosure: bool
      inclToMod*: Table[FileIndex, FileIndex]
      importStack*: seq[FileIndex]
      backend*: RootRef
      config*: ConfigRef
      cache*: IdentCache
      vm*: RootRef
      doStopCompile*: proc (): bool {...}{.closure.}
      usageSym*: PSym
      owners*: seq[PSym]
      methods*: seq[tuple[methods: seq[PSym], dispatcher: PSym]]
      systemModule*: PSym
      sysTypes*: array[TTypeKind, PType]
      compilerprocs*: TStrTable
      exposed*: TStrTable
      intTypeCache*: array[-5 .. 64, PType]
      opContains*, opNot*: PSym
      emptyNode*: PNode
      incr*: IncrementalCtx
      canonTypes*: Table[SigHash, PType]
      symBodyHashes*: Table[int, SigHash]
      importModuleCallback*: proc (graph: ModuleGraph; m: PSym; fileIdx: FileIndex): PSym {...}{.
          nimcall.}
      includeFileCallback*: proc (graph: ModuleGraph; m: PSym; fileIdx: FileIndex): PNode {...}{.
          nimcall.}
      recordStmt*: proc (graph: ModuleGraph; m: PSym; n: PNode) {...}{.nimcall.}
      cacheSeqs*: Table[string, PNode]
      cacheCounters*: Table[string, BiggestInt]
      cacheTables*: Table[string, BTree[string, PNode]]
      passes*: seq[TPass]
      onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {...}{.nimcall.}
      onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym;
                                         info: TLineInfo) {...}{.nimcall.}
      onUsage*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {...}{.nimcall.}
      globalDestructors*: seq[PNode]
      strongSemCheck*: proc (graph: ModuleGraph; owner: PSym; body: PNode) {...}{.nimcall.}
      compatibleProps*: proc (graph: ModuleGraph; formal, actual: PType): bool {...}{.
          nimcall.}

  Source Edit

    TPassContext = object of RootObj

  Source Edit

    PPassContext = ref TPassContext

  Source Edit

    TPassOpen = proc (graph: ModuleGraph; module: PSym): PPassContext {...}{.nimcall.}

  Source Edit

    TPassClose = proc (graph: ModuleGraph; p: PPassContext; n: PNode): PNode {...}{.
        nimcall.}

  Source Edit

    TPassProcess = proc (p: PPassContext; topLevelStmt: PNode): PNode {...}{.nimcall.}

  Source Edit

    TPass = tuple[open: TPassOpen, process: TPassProcess, close: TPassClose,
                  isFrontend: bool]

  Source Edit

# Procs

    proc `$`(u: SigHash): string {...}{.raises: [], tags: [].}

  Source Edit

    proc `==`(a, b: SigHash): bool {...}{.raises: [], tags: [].}

  Source Edit

    proc hash(u: SigHash): Hash {...}{.raises: [], tags: [].}

  Source Edit

    proc hash(x: FileIndex): Hash {...}{.borrow.}

  Source Edit

    proc stopCompile(g: ModuleGraph): bool {...}{.inline, raises: [Exception],
        tags: [RootEffect].}

  Source Edit

    proc createMagic(g: ModuleGraph; name: string; m: TMagic): PSym {...}{.raises: [],
        tags: [].}

  Source Edit

    proc newModuleGraph(cache: IdentCache; config: ConfigRef): ModuleGraph {...}{.
        raises: [], tags: [].}

  Source Edit

    proc resetAllModules(g: ModuleGraph) {...}{.raises: [], tags: [].}

  Source Edit

    proc getModule(g: ModuleGraph; fileIdx: FileIndex): PSym {...}{.raises: [], tags: [].}

  Source Edit

    proc addDep(g: ModuleGraph; m: PSym; dep: FileIndex) {...}{.raises: [], tags: [].}

  Source Edit

    proc addIncludeDep(g: ModuleGraph; module, includeFile: FileIndex) {...}{.raises: [],
        tags: [].}

  Source Edit

    proc parentModule(g: ModuleGraph; fileIdx: FileIndex): FileIndex {...}{.raises: [],
        tags: [].}

  returns 'fileIdx' if the file belonging to this index is directly used as a module or else the module that first references this include file. Source Edit

    proc markDirty(g: ModuleGraph; fileIdx: FileIndex) {...}{.raises: [], tags: [].}

  Source Edit

    proc markClientsDirty(g: ModuleGraph; fileIdx: FileIndex) {...}{.raises: [], tags: [].}

  Source Edit

    proc isDirty(g: ModuleGraph; m: PSym): bool {...}{.raises: [], tags: [].}

  Source Edit

# Templates

    template onUse(info: TLineInfo; s: PSym)

  Source Edit

    template onDef(info: TLineInfo; s: PSym)

  Source Edit

    template onDefResolveForward(info: TLineInfo; s: PSym)

  Source Edit