vancode/interpreter/resolver

This module defines a file resolver for managing file imports and includes. It tracks which files have been resolve (imported/included) by which other files, and provides utilities for checking dependencies and resolving files.

This is used by the interpreter to manage file imports and includes, and to detect circular dependencies.

Types

FileResolver = object
  resolvedFiles*: ResolvedFiles
  fs*: VirtualFileSystem ## The virtual file system used to check for file existence and
                         ## read file contents. This allows us to swap out the actual disk FS for
                         ## an in-memory or embedded FS
Manages file resolution for imports/includes
ResolverError = object of CatchableError
VirtualFileSystem = ref object
  existsProc*: proc (path: string): bool
  readProc*: proc (path: string): string

Procs

proc clearFile(resolver: var FileResolver; filePath: string) {.
    ...raises: [KeyError], tags: [], forbids: [].}
Clear the resolution status of a file
proc dependants(resolver: FileResolver; target: string; recursive = true): seq[
    string] {....raises: [], tags: [], forbids: [].}
Returns a list of files that depend on the target file. If recursive is true, it will return all files that directly or indirectly depend on the target. Otherwise it will only return files that directly depend to the target.
proc dependencies(resolver: FileResolver; filePath: string): seq[string] {.
    ...raises: [], tags: [], forbids: [].}
proc fileExists(resolver: FileResolver; filePath: string): bool {.
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
proc initResolver(): FileResolver {....raises: [], tags: [], forbids: [].}
Initialize a new FileResolver
proc isResolved(resolver: FileResolver; filePath: string): bool {....raises: [],
    tags: [], forbids: [].}
proc newDiskFS(): VirtualFileSystem {....raises: [], tags: [], forbids: [].}

Create a virtual file system that interacts with the actual disk.

This is the default file system used by the resolver, but it can be replaced with an in-memory or embedded file system for testing or special use cases.

proc newInMemoryFS(map: TableRef[string, string]): VirtualFileSystem {.
    ...raises: [], tags: [], forbids: [].}

Create a virtual file system from an in-memory map of file paths to contents.

This is useful for testing or when you want to embed files directly into your application

proc readFile(resolver: FileResolver; filePath: string): string {.
    ...raises: [Exception, ResolverError], tags: [RootEffect], forbids: [].}
proc resolveFile(resolver: var FileResolver; aFile, bFile: string) {.
    ...raises: [Exception, ResolverError, KeyError], tags: [RootEffect],
    forbids: [].}

Resolve a file import/include. This proc checks if the file exists, if it has already been resolved, and if there are any circular or self-imports.

If all checks pass, it marks the file as resolved. TODO handle symlinks

proc setDependencies(resolver: var FileResolver; aFile: string;
                     deps: openArray[string]) {....raises: [], tags: [],
    forbids: [].}
Set the dependencies for a file. This is used to mark which files have been resolved (imported/included) by a given file