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 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: [].}
- 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 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 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?
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