compiler/sem/lookups

    Dark Mode
Search:
  Source   Edit

This module implements lookup helpers.

Types

PIdentResult = tuple[ident: PIdent, ## found ident, otherwise `IdentCache.notFoundIdent`
                     errNode: PNode]
  Source   Edit
TLookupFlag = enum
  checkAmbiguity, checkUndeclared, checkModule, checkPureEnumFields
  Source   Edit
TOverloadIter = object
  it*: TIdentIter
  mit*: ModuleIter
  m*: PSym
  mode*: TOverloadIterMode
  symChoiceIndex*: int
  currentScope: PScope
  importIdx: int
  marked: IntSet
  Source   Edit
TOverloadIterMode = enum
  oimDone, oimNoQualifier, oimSelfModule, oimOtherModule, oimSymChoice,
  oimSymChoiceLocalLookup
  Source   Edit

Procs

proc addDecl(c: PContext; sym: PSym; info = sym.info; scope = c.currentScope) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
  Source   Edit
proc addInterfaceDecl(c: PContext; sym: PSym) {.inline,
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
adds a decl and the interface if appropriate   Source   Edit
proc addInterfaceDeclAt(c: PContext; scope: PScope; sym: PSym) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
adds a symbol on the scope and the interface if appropriate   Source   Edit
proc addInterfaceOverloadableSymAt(c: PContext; scope: PScope; sym: PSym) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
adds an overloadable symbol on the scope and the interface if appropriate   Source   Edit
proc addOverloadableSymAt(c: PContext; scope: PScope; fn: PSym) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
adds an symbol to the given scope, will check for and raise errors if it's a redefinition as opposed to an overload.   Source   Edit
proc addPrelimDecl(c: PContext; sym: PSym) {....raises: [], tags: [].}
  Source   Edit
proc addUniqueSym(scope: PScope; s: PSym): PSym {....raises: [], tags: [].}
  Source   Edit
proc closeScope(c: PContext) {....raises: [Exception], tags: [RootEffect].}
  Source   Edit
proc closeShadowScope(c: PContext) {....raises: [], tags: [].}
closes the shadow scope, but doesn't merge any of the symbols Does not check for unused symbols or missing forward decls since a macro or template consumes this AST   Source   Edit
proc considerQuotedIdent(c: PContext; n: PNode): PIdentResult {....raises: [],
    tags: [].}

Retrieve a PIdent from a PNode, taking into account accent nodes for keyword escaping (stropping) and identifier construction. If none found, returns a idents.IdentCache.identNotFound and an error node (nkError).

Idents are derived as follows:

  • nkIdent -> ident
  • nkSym -> ident
  • nkSymChoices -> ident of first child; assert if malformed
  • nkAccQuoted:
    • if empty -> an error
    • if singleton with nkIdent|Sym|SymChoices -> handled as above
    • else -> construct identifier, see next
  • anything else -> not found (see note )

Ident Construction, creates an ident by concatenating child string values:

  • nkIdent|Sym|SymChoices -> ident.s for string value
  • nkAccQuoted:
    • if empty -> empty string
    • else -> recursively evaluate
  • string literals -> string
  • chararacter literal -> character as string
  • integer literal -> int to string
  • anything else -> error

To ensure we don't have a run away evaluation, identifier construction has a hard limit on number of items.

  Source   Edit
proc createUndeclaredIdentifierError(c: PContext; n: PNode; name: string;
                                     candidates: seq[SemSpellCandidate] = @[]): PNode {.
    ...raises: [], tags: [].}
  Source   Edit
proc debugScopes(c: PContext; limit = 0; max = int.high) {....deprecated,
    raises: [], tags: [].}
Deprecated
  Source   Edit
proc errorSym(c: PContext; n, err: PNode): PSym {....raises: [Exception, KeyError],
    tags: [RootEffect].}
creates an error symbol to avoid cascading errors (for IDE support), with n as the node with the error and err with the desired nkError   Source   Edit
proc errorUndeclaredIdentifier(c: PContext; info: TLineInfo; name: string;
                               candidates: seq[SemSpellCandidate] = @[]) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
  Source   Edit
proc errorUndeclaredIdentifierHint(c: PContext; n: PNode; ident: PIdent): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc errorUndeclaredIdentifierWithHint(c: PContext; n: PNode; name: string;
    candidates: seq[SemSpellCandidate] = @[]): PSym {.
    ...raises: [Exception, KeyError], tags: [RootEffect].}
creates an error symbol with hints as to what it might be eg: recursive imports   Source   Edit
proc errorUseQualifier(c: PContext; n: PNode; s: PSym): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc fieldVisible(c: PContext; f: PSym): bool {.inline, ...raises: [], tags: [].}
  Source   Edit
proc fixSpelling(c: PContext; ident: PIdent): seq[SemSpellCandidate] {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
when we cannot find the identifier, suggest nearby spellings   Source   Edit
proc initOverloadIter(o: var TOverloadIter; c: PContext; n: PNode): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc initOverloadIter(o: var TOverloadIter; c: PContext; scope: PScope; n: PNode): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
Similiar to the normal initOverloadIter procedure, but allows for specifying the scope to start in.   Source   Edit
proc isShadowScope(s: PScope): bool {.inline, ...raises: [], tags: [].}
  Source   Edit
proc lastOverloadScope(o: TOverloadIter): int {....raises: [], tags: [].}
  Source   Edit
proc legacyConsiderQuotedIdent(c: PContext; n, origin: PNode): PIdent {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}

Legacy/Transition Code: avoid using this

considerQuotedIdent used to allow providing an origin for "better" error reporting, but it was an awkward API. This template creates a block to replicate the previous behaviour of fetching and doing inline error with an origin parameter for the purposes of transition.

  Source   Edit
proc localSearchInScope(c: PContext; s: PIdent): PSym {....raises: [], tags: [].}
  Source   Edit
proc lookUp(c: PContext; n: PNode): PSym {.
    ...raises: [KeyError, Exception, ERecoverableError],
    tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc mergeShadowScope(c: PContext) {....raises: [Exception, ERecoverableError],
                                     tags: [RootEffect].}

close the existing scope and merge in all defined symbols, this will also trigger any export related code if this is into a non-shadow scope.

Merges: shadow -> shadow: add symbols to the parent but check for redefinitions etc shadow -> non-shadow: the above, but also handle exports and all that

  Source   Edit
proc nextOverloadIter(o: var TOverloadIter; c: PContext; n: PNode): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc openScope(c: PContext): PScope {.discardable, ...raises: [], tags: [].}
  Source   Edit
proc openShadowScope(c: PContext) {....raises: [], tags: [].}
opens a shadow scope, just like any other scope except the depth is the same as the parent -- see isShadowScope.   Source   Edit
proc pickSym(c: PContext; n: PNode; kinds: set[TSymKind]; flags: TSymFlags = {}): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc qualifiedLookUp(c: PContext; n: PNode; flags: set[TLookupFlag]): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}

takes an identifier (ident, accent quoted, dot expression qualified, etc), finds the associated symbol or reports errors based on the flags configuration (allow ambiguity, etc).

this new version returns an error symbol rather than issuing errors directly. The symbol's ast field will contain an nkError, and the typ field on the symbol will be the errorType

XXX: currently skError is just a const for skUnknown which has many uses,
once things are cleaner, create a proper skError and use that instead of a tuple return.
XXX: maybe remove the flags for ambiguity and undeclared and let the call
sites figure it out instead?
  Source   Edit
proc rawCloseScope(c: PContext) {....raises: [], tags: [].}
  Source   Edit
proc searchInScopes(c: PContext; s: PIdent; ambiguous: var bool): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc searchInScopesFilterBy(c: PContext; s: PIdent; filter: TSymKinds): seq[PSym] {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc someSymFromImportTable(c: PContext; name: PIdent; ambiguous: var bool): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
proc wrongRedefinition(c: PContext; info: TLineInfo; s: PSym;
                       conflictsWith: PSym) {.
    ...raises: [Exception, ERecoverableError], tags: [RootEffect].}
Emit a redefinition error if in non-interactive mode   Source   Edit

Iterators

iterator allScopes(scope: PScope): PScope {....raises: [], tags: [].}
  Source   Edit
iterator allSyms(c: PContext): (PSym, int, bool) {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
iterator importedItems(c: PContext; name: PIdent): PSym {.
    ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
  Source   Edit
iterator localScopesFrom(c: PContext; scope: PScope): PScope {....raises: [],
    tags: [].}
  Source   Edit

Templates

template addSym(scope: PScope; s: PSym)
  Source   Edit