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.
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