experiment: big refactoring

This commit is contained in:
Araq
2025-11-11 07:32:37 +01:00
parent 1ab4f1fe19
commit 16480c4d02
12 changed files with 405 additions and 178 deletions

View File

@@ -695,32 +695,33 @@ type
ItemState* = enum
Complete # completely in memory
Partial # partially in memory
Sealed # complete in memory, already written to NIF file, so further mutations are not allowed
PLib* = ref TLib
TSym* {.acyclic.} = object # Keep in sync with PackedSym
TSym* {.acyclic.} = object # Keep in sync with ast2nif.nim
itemId*: ItemId
# proc and type instantiations are cached in the generic symbol
state*: ItemState
case kind*: TSymKind
case kindImpl*: TSymKind # Note: kept as 'kind' for case statement, but accessor checks state
of routineKinds:
#procInstCache*: seq[PInstantiation]
gcUnsafetyReason*: PSym # for better error messages regarding gcsafe
transformedBody*: PNode # cached body after transf pass
gcUnsafetyReasonImpl*: PSym # for better error messages regarding gcsafe
transformedBodyImpl*: PNode # cached body after transf pass
of skLet, skVar, skField, skForVar:
guard*: PSym
bitsize*: int
alignment*: int # for alignment
guardImpl*: PSym
bitsizeImpl*: int
alignmentImpl*: int # for alignment
else: nil
magic*: TMagic
typ*: PType
magicImpl*: TMagic
typImpl*: PType
name*: PIdent
info*: TLineInfo
infoImpl*: TLineInfo
when defined(nimsuggest):
endInfo*: TLineInfo
hasUserSpecifiedType*: bool # used for determining whether to display inlay type hints
ownerField: PSym
flags*: TSymFlags
ast*: PNode # syntax tree of proc, iterator, etc.:
endInfoImpl*: TLineInfo
hasUserSpecifiedTypeImpl*: bool # used for determining whether to display inlay type hints
ownerFieldImpl: PSym
flagsImpl*: TSymFlags
astImpl*: PNode # syntax tree of proc, iterator, etc.:
# the whole proc including header; this is used
# for easy generation of proper error messages
# for variant record fields the discriminant
@@ -728,8 +729,8 @@ type
# for modules, it's a placeholder for compiler
# generated code that will be appended to the
# module after the sem pass (see appendToModule)
options*: TOptions
position*: int # used for many different things:
optionsImpl*: TOptions
positionImpl*: int # used for many different things:
# for enum fields its position;
# for fields its offset
# for parameters its position (starting with 0)
@@ -739,23 +740,23 @@ type
# for modules, an unique index corresponding
# to the module's fileIdx
# for variables a slot index for the evaluator
offset*: int32 # offset of record field
offsetImpl*: int32 # offset of record field
disamb*: int32 # disambiguation number; the basic idea is that
# `<procname>__<module>_<disamb>` is unique
loc*: TLoc
annex*: PLib # additional fields (seldom used, so we use a
locImpl*: TLoc
annexImpl*: PLib # additional fields (seldom used, so we use a
# reference to another object to save space)
when hasFFI:
cname*: string # resolved C declaration name in importc decl, e.g.:
cnameImpl*: string # resolved C declaration name in importc decl, e.g.:
# proc fun() {.importc: "$1aux".} => cname = funaux
constraint*: PNode # additional constraints like 'lit|result'; also
constraintImpl*: PNode # additional constraints like 'lit|result'; also
# misused for the codegenDecl and virtual pragmas in the hope
# it won't cause problems
# for skModule the string literal to output for
# deprecated modules.
instantiatedFrom*: PSym # for instances, the generic symbol where it came from.
instantiatedFromImpl*: PSym # for instances, the generic symbol where it came from.
when defined(nimsuggest):
allUsages*: seq[TLineInfo]
allUsagesImpl*: seq[TLineInfo]
TTypeSeq* = seq[PType]
@@ -840,11 +841,226 @@ template nodeId(n: PNode): int = cast[int](n)
template typ*(n: PNode): PType =
n.typField
proc loadSym*(s: PSym) {.inline.} =
## Loads a symbol from NIF file if it's in Partial state.
## This is a forward declaration - implementation should be provided elsewhere.
discard
proc owner*(s: PSym|PType): PSym {.inline.} =
result = s.ownerField
when s is PSym:
if s.state == Partial: loadSym(s)
result = s.ownerFieldImpl
else:
result = s.ownerField
proc setOwner*(s: PSym|PType, owner: PSym) {.inline.} =
s.ownerField = owner
when s is PSym:
if s.state == Partial: loadSym(s)
s.ownerFieldImpl = owner
else:
s.ownerField = owner
# Accessor procs for TSym fields
# Note: kind is kept as a direct field for case statement compatibility
# but we still provide an accessor that checks state
proc kind*(s: PSym): TSymKind {.inline.} =
if s.state == Partial: loadSym(s)
result = s.kind
proc `kind=`*(s: PSym, val: TSymKind) {.inline.} =
if s.state == Partial: loadSym(s)
s.kind = val
proc gcUnsafetyReason*(s: PSym): PSym {.inline.} =
if s.state == Partial: loadSym(s)
result = s.gcUnsafetyReasonImpl
proc `gcUnsafetyReason=`*(s: PSym, val: PSym) {.inline.} =
if s.state == Partial: loadSym(s)
s.gcUnsafetyReasonImpl = val
proc transformedBody*(s: PSym): PNode {.inline.} =
if s.state == Partial: loadSym(s)
result = s.transformedBodyImpl
proc `transformedBody=`*(s: PSym, val: PNode) {.inline.} =
if s.state == Partial: loadSym(s)
s.transformedBodyImpl = val
proc guard*(s: PSym): PSym {.inline.} =
if s.state == Partial: loadSym(s)
result = s.guardImpl
proc `guard=`*(s: PSym, val: PSym) {.inline.} =
if s.state == Partial: loadSym(s)
s.guardImpl = val
proc bitsize*(s: PSym): int {.inline.} =
if s.state == Partial: loadSym(s)
result = s.bitsizeImpl
proc `bitsize=`*(s: PSym, val: int) {.inline.} =
if s.state == Partial: loadSym(s)
s.bitsizeImpl = val
proc alignment*(s: PSym): int {.inline.} =
if s.state == Partial: loadSym(s)
result = s.alignmentImpl
proc `alignment=`*(s: PSym, val: int) {.inline.} =
if s.state == Partial: loadSym(s)
s.alignmentImpl = val
proc magic*(s: PSym): TMagic {.inline.} =
if s.state == Partial: loadSym(s)
result = s.magicImpl
proc `magic=`*(s: PSym, val: TMagic) {.inline.} =
if s.state == Partial: loadSym(s)
s.magicImpl = val
proc typ*(s: PSym): PType {.inline.} =
if s.state == Partial: loadSym(s)
result = s.typImpl
proc `typ=`*(s: PSym, val: PType) {.inline.} =
if s.state == Partial: loadSym(s)
s.typImpl = val
proc info*(s: PSym): TLineInfo {.inline.} =
if s.state == Partial: loadSym(s)
result = s.infoImpl
proc `info=`*(s: PSym, val: TLineInfo) {.inline.} =
if s.state == Partial: loadSym(s)
s.infoImpl = val
when defined(nimsuggest):
proc endInfo*(s: PSym): TLineInfo {.inline.} =
if s.state == Partial: loadSym(s)
result = s.endInfoImpl
proc `endInfo=`*(s: PSym, val: TLineInfo) {.inline.} =
if s.state == Partial: loadSym(s)
s.endInfoImpl = val
proc hasUserSpecifiedType*(s: PSym): bool {.inline.} =
if s.state == Partial: loadSym(s)
result = s.hasUserSpecifiedTypeImpl
proc `hasUserSpecifiedType=`*(s: PSym, val: bool) {.inline.} =
if s.state == Partial: loadSym(s)
s.hasUserSpecifiedTypeImpl = val
proc flags*(s: PSym): TSymFlags {.inline.} =
if s.state == Partial: loadSym(s)
result = s.flagsImpl
proc `flags=`*(s: PSym, val: TSymFlags) {.inline.} =
if s.state == Partial: loadSym(s)
s.flagsImpl = val
proc ast*(s: PSym): PNode {.inline.} =
if s.state == Partial: loadSym(s)
result = s.astImpl
proc `ast=`*(s: PSym, val: PNode) {.inline.} =
if s.state == Partial: loadSym(s)
s.astImpl = val
proc options*(s: PSym): TOptions {.inline.} =
if s.state == Partial: loadSym(s)
result = s.optionsImpl
proc `options=`*(s: PSym, val: TOptions) {.inline.} =
if s.state == Partial: loadSym(s)
s.optionsImpl = val
proc position*(s: PSym): int {.inline.} =
if s.state == Partial: loadSym(s)
result = s.positionImpl
proc `position=`*(s: PSym, val: int) {.inline.} =
if s.state == Partial: loadSym(s)
s.positionImpl = val
proc offset*(s: PSym): int32 {.inline.} =
if s.state == Partial: loadSym(s)
result = s.offsetImpl
proc `offset=`*(s: PSym, val: int32) {.inline.} =
if s.state == Partial: loadSym(s)
s.offsetImpl = val
proc loc*(s: PSym): TLoc {.inline.} =
if s.state == Partial: loadSym(s)
result = s.locImpl
proc `loc=`*(s: PSym, val: TLoc) {.inline.} =
if s.state == Partial: loadSym(s)
s.locImpl = val
proc annex*(s: PSym): PLib {.inline.} =
if s.state == Partial: loadSym(s)
result = s.annexImpl
proc `annex=`*(s: PSym, val: PLib) {.inline.} =
if s.state == Partial: loadSym(s)
s.annexImpl = val
when hasFFI:
proc cname*(s: PSym): string {.inline.} =
if s.state == Partial: loadSym(s)
result = s.cnameImpl
proc `cname=`*(s: PSym, val: string) {.inline.} =
if s.state == Partial: loadSym(s)
s.cnameImpl = val
proc constraint*(s: PSym): PNode {.inline.} =
if s.state == Partial: loadSym(s)
result = s.constraintImpl
proc `constraint=`*(s: PSym, val: PNode) {.inline.} =
if s.state == Partial: loadSym(s)
s.constraintImpl = val
proc instantiatedFrom*(s: PSym): PSym {.inline.} =
if s.state == Partial: loadSym(s)
result = s.instantiatedFromImpl
proc `instantiatedFrom=`*(s: PSym, val: PSym) {.inline.} =
if s.state == Partial: loadSym(s)
s.instantiatedFromImpl = val
proc setSnippet*(s: PSym; val: sink string) {.inline.} =
if s.state == Partial: loadSym(s)
s.locImpl.snippet = val
proc incl*(s: PSym; flag: TSymFlag) {.inline.} =
if s.state == Partial: loadSym(s)
s.flagsImpl.incl(flag)
proc incl*(s: PSym; flags: set[TSymFlag]) {.inline.} =
if s.state == Partial: loadSym(s)
s.flagsImpl.incl(flag)
proc incl*(s: PSym; flag: TLocFlag) {.inline.} =
if s.state == Partial: loadSym(s)
s.locImpl.flags.incl(flag)
proc excl*(s: PSym; flag: TSymFlag) {.inline.} =
if s.state == Partial: loadSym(s)
s.flagsImpl.excl(flag)
when defined(nimsuggest):
proc allUsages*(s: PSym): seq[TLineInfo] {.inline.} =
if s.state == Partial: loadSym(s)
result = s.allUsagesImpl
proc `allUsages=`*(s: PSym, val: seq[TLineInfo]) {.inline.} =
if s.state == Partial: loadSym(s)
s.allUsagesImpl = val
type Gconfig = object
# we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
@@ -1091,15 +1307,17 @@ proc getDeclPragma*(n: PNode): PNode =
proc extractPragma*(s: PSym): PNode =
## gets the pragma node of routine/type/var/let/const symbol `s`
if s.kind in routineKinds: # bug #24167
if s.ast[pragmasPos] != nil and s.ast[pragmasPos].kind != nkEmpty:
result = s.ast[pragmasPos]
let astVal = s.ast
if astVal != nil and astVal[pragmasPos] != nil and astVal[pragmasPos].kind != nkEmpty:
result = astVal[pragmasPos]
else:
result = nil
elif s.kind in {skType, skVar, skLet, skConst}:
if s.ast != nil and s.ast.len > 0:
if s.ast[0].kind == nkPragmaExpr and s.ast[0].len > 1:
let astVal = s.ast
if astVal != nil and astVal.len > 0:
if astVal[0].kind == nkPragmaExpr and astVal[0].len > 1:
# s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
result = s.ast[0][1]
result = astVal[0][1]
else:
result = nil
else:
@@ -1126,7 +1344,7 @@ when defined(useNodeIds):
const nodeIdToDebug* = -1 # 2322968
var gNodeId: int
template newNodeImpl(info2) =
template newNodeImpl(info2) {.dirty.} =
result = PNode(kind: kind, info: info2)
when false:
# this would add overhead, so we skip it; it results in a small amount of leaked entries
@@ -1229,8 +1447,8 @@ proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
# generates a symbol and initializes the hash field too
assert not name.isNil
let id = nextSymId idgen
result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
options: options, ownerField: owner, offset: defaultOffset,
result = PSym(name: name, kindImpl: symKind, flagsImpl: {}, infoImpl: info, itemId: id,
optionsImpl: options, ownerFieldImpl: owner, offsetImpl: defaultOffset,
disamb: getOrDefault(idgen.disambTable, name).int32)
idgen.disambTable.inc name
when false:
@@ -1241,10 +1459,11 @@ proc newSym*(symKind: TSymKind, name: PIdent, idgen: IdGenerator; owner: PSym,
proc astdef*(s: PSym): PNode =
# get only the definition (initializer) portion of the ast
if s.ast != nil and s.ast.kind in {nkIdentDefs, nkConstDef}:
s.ast[2]
let astVal = s.ast
if astVal != nil and astVal.kind in {nkIdentDefs, nkConstDef}:
astVal[2]
else:
s.ast
astVal
proc isMetaType*(t: PType): bool =
return t.kind in tyMetaTypes or
@@ -1256,31 +1475,33 @@ proc isUnresolvedStatic*(t: PType): bool =
proc linkTo*(t: PType, s: PSym): PType {.discardable.} =
t.sym = s
s.typ = t
s.typImpl = t
result = t
proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
t.sym = s
s.typ = t
s.typImpl = t
result = s
template fileIdx*(c: PSym): FileIndex =
# XXX: this should be used only on module symbols
c.position.FileIndex
c.position().FileIndex
template filename*(c: PSym): string =
# XXX: this should be used only on module symbols
c.position.FileIndex.toFilename
c.position().FileIndex.toFilename
proc appendToModule*(m: PSym, n: PNode) =
## The compiler will use this internally to add nodes that will be
## appended to the module after the sem pass
if m.ast == nil:
m.ast = newNode(nkStmtList)
m.ast.sons = @[n]
var astVal = m.ast
if astVal == nil:
astVal = newNode(nkStmtList)
astVal.sons = @[n]
m.astImpl = astVal
else:
assert m.ast.kind == nkStmtList
m.ast.sons.add(n)
assert astVal.kind == nkStmtList
astVal.sons.add(n)
const # for all kind of hash tables:
GrowthFactor* = 2 # must be power of 2, > 0
@@ -1582,9 +1803,11 @@ proc assignType*(dest, src: PType) =
# this fixes 'type TLock = TSysLock':
if src.sym != nil:
if dest.sym != nil:
dest.sym.flags.incl src.sym.flags-{sfUsed, sfExported}
if dest.sym.annex == nil: dest.sym.annex = src.sym.annex
mergeLoc(dest.sym.loc, src.sym.loc)
var destFlags = dest.sym.flags
var srcFlags = src.sym.flags
dest.sym.flagsImpl = destFlags + (srcFlags - {sfUsed, sfExported})
if dest.sym.annex == nil: dest.sym.annexImpl = src.sym.annex
mergeLoc(dest.sym.locImpl, src.sym.loc)
else:
dest.sym = src.sym
newSons(dest, src.sons.len)
@@ -1604,31 +1827,31 @@ proc exactReplica*(t: PType): PType =
proc copySym*(s: PSym; idgen: IdGenerator): PSym =
result = newSym(s.kind, s.name, idgen, s.owner, s.info, s.options)
#result.ast = nil # BUGFIX; was: s.ast which made problems
result.typ = s.typ
result.flags = s.flags
result.magic = s.magic
result.options = s.options
result.position = s.position
result.loc = s.loc
result.annex = s.annex # BUGFIX
result.constraint = s.constraint
#result.astImpl = nil # BUGFIX; was: s.ast which made problems
result.typImpl = s.typ
result.flagsImpl = s.flags
result.magicImpl = s.magic
result.optionsImpl = s.options
result.positionImpl = s.position
result.locImpl = s.loc
result.annexImpl = s.annex # BUGFIX
result.constraintImpl = s.constraint
if result.kind in {skVar, skLet, skField}:
result.guard = s.guard
result.bitsize = s.bitsize
result.alignment = s.alignment
result.guardImpl = s.guard
result.bitsizeImpl = s.bitsize
result.alignmentImpl = s.alignment
proc createModuleAlias*(s: PSym, idgen: IdGenerator, newIdent: PIdent, info: TLineInfo;
options: TOptions): PSym =
result = newSym(s.kind, newIdent, idgen, s.owner, info, options)
# keep ID!
result.ast = s.ast
result.astImpl = s.ast
#result.id = s.id # XXX figure out what to do with the ID.
result.flags = s.flags
result.options = s.options
result.position = s.position
result.loc = s.loc
result.annex = s.annex
result.flagsImpl = s.flags
result.optionsImpl = s.options
result.positionImpl = s.position
result.locImpl = s.loc
result.annexImpl = s.annex
proc initStrTable*(): TStrTable =
result = TStrTable(counter: 0)
@@ -1754,28 +1977,28 @@ proc transitionNoneToSym*(n: PNode) =
template transitionSymKindCommon*(k: TSymKind) =
let obj {.inject.} = s[]
s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
info: obj.info, ownerField: obj.ownerField, flags: obj.flags, ast: obj.ast,
options: obj.options, position: obj.position, offset: obj.offset,
loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
s[] = TSym(kindImpl: k, itemId: obj.itemId, magicImpl: obj.magicImpl, typImpl: obj.typImpl, name: obj.name,
infoImpl: obj.infoImpl, ownerFieldImpl: obj.ownerFieldImpl, flagsImpl: obj.flagsImpl, astImpl: obj.astImpl,
optionsImpl: obj.optionsImpl, positionImpl: obj.positionImpl, offsetImpl: obj.offsetImpl,
locImpl: obj.locImpl, annexImpl: obj.annexImpl, constraintImpl: obj.constraintImpl)
when hasFFI:
s.cname = obj.cname
s.cnameImpl = obj.cnameImpl
when defined(nimsuggest):
s.allUsages = obj.allUsages
s.allUsagesImpl = obj.allUsagesImpl
proc transitionGenericParamToType*(s: PSym) =
transitionSymKindCommon(skType)
proc transitionRoutineSymKind*(s: PSym, kind: range[skProc..skTemplate]) =
transitionSymKindCommon(kind)
s.gcUnsafetyReason = obj.gcUnsafetyReason
s.transformedBody = obj.transformedBody
s.gcUnsafetyReasonImpl = obj.gcUnsafetyReasonImpl
s.transformedBodyImpl = obj.transformedBodyImpl
proc transitionToLet*(s: PSym) =
transitionSymKindCommon(skLet)
s.guard = obj.guard
s.bitsize = obj.bitsize
s.alignment = obj.alignment
s.guardImpl = obj.guardImpl
s.bitsizeImpl = obj.bitsizeImpl
s.alignmentImpl = obj.alignmentImpl
template copyNodeImpl(dst, src, processSonsStmt) =
if src == nil: return

View File

@@ -118,8 +118,6 @@ type
deps: TokenBuf # include&import deps
infos: LineInfoWriter
currentModule: int32
writtenSyms: HashSet[ItemId]
writtenTypes: HashSet[ItemId]
decodedFileIndices: HashSet[FileIndex]
moduleToNifSuffix: Table[FileIndex, string]
locals: HashSet[ItemId] # track proc-local symbols
@@ -233,7 +231,8 @@ proc writeTypeDef(w: var Writer; dest: var TokenBuf; typ: PType) =
proc writeType(w: var Writer; dest: var TokenBuf; typ: PType) =
if typ == nil:
dest.addDotToken()
elif typ.itemId.module == w.currentModule and not w.writtenTypes.containsOrIncl(typ.uniqueId):
elif typ.itemId.module == w.currentModule and typ.state == Complete:
typ.state = Sealed
writeTypeDef(w, dest, typ)
else:
dest.buildTree tuseTag:
@@ -288,7 +287,8 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) =
proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
if sym == nil:
dest.addDotToken()
elif sym.itemId.module == w.currentModule and not w.writtenSyms.containsOrIncl(sym.itemId):
elif sym.itemId.module == w.currentModule and sym.state == Complete:
sym.state = Sealed
writeSymDef(w, dest, sym)
else:
# NIF has direct support for symbol references so we don't need to use a tag here,
@@ -298,7 +298,8 @@ proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
proc writeSymNode(w: var Writer; dest: var TokenBuf; n: PNode; sym: PSym) =
if sym == nil:
dest.addDotToken()
elif sym.itemId.module == w.currentModule and not w.writtenSyms.containsOrIncl(sym.itemId):
elif sym.itemId.module == w.currentModule and sym.state == Complete:
sym.state = Sealed
if n.typ != n.sym.typ:
dest.buildTree hiddenTypeTag, trLineInfo(w, n.info):
writeSymDef(w, dest, sym)
@@ -629,7 +630,7 @@ proc loadSymStub(c: var DecodeContext; t: SymId): PSym =
result = c.syms.getOrDefault(id)[0]
if result == nil:
let offs = c.getOffset(module, symAsStr)
result = PSym(itemId: id, kind: skStub, name: c.cache.getIdent(sn.name), disamb: sn.count.int32, state: Partial)
result = PSym(itemId: id, kindImpl: skStub, name: c.cache.getIdent(sn.name), disamb: sn.count.int32, state: Partial)
c.syms[id] = (result, offs)
proc loadSymStub(c: var DecodeContext; n: var Cursor): PSym =
@@ -689,6 +690,7 @@ proc loadLoc(c: var DecodeContext; n: var Cursor; loc: var TLoc) =
proc loadType*(c: var DecodeContext; t: PType) =
if t.state != Partial: return
t.state = Sealed
var buf = createTokenBuf(30)
var n = cursorFromIndexEntry(c, t.itemId.module, c.types[t.itemId][1], buf)
@@ -739,7 +741,8 @@ proc loadAnnex(c: var DecodeContext; n: var Cursor): PLib =
raiseAssert "`lib/annex` information expected"
proc loadSym*(c: var DecodeContext; s: PSym) =
if s.kind != skStub: return
if s.state != Partial: return
s.state = Sealed
var buf = createTokenBuf(30)
var n = cursorFromIndexEntry(c, s.itemId.module, c.syms[s.itemId][1], buf)
@@ -777,7 +780,7 @@ proc loadSym*(c: var DecodeContext; s: PSym) =
s.setOwner loadSymStub(c, n)
# We do not store `sym.ast` here but instead set it in the deserializer
#writeNode(w, sym.ast)
loadLoc c, n, s.loc
loadLoc c, n, s.locImpl
s.constraint = loadNode(c, n)
s.instantiatedFrom = loadSymStub(c, n)
skipParRi n

View File

@@ -899,11 +899,11 @@ proc moduleIndex*(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: in
proc symHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
s: PackedSym; si, item: int32): PSym =
result = PSym(itemId: ItemId(module: si, item: item),
kind: s.kind, magic: s.magic, flags: s.flags,
info: translateLineInfo(c, g, si, s.info),
options: s.options,
position: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
offset: if s.kind in routineKinds: defaultOffset else: s.offset,
kindImpl: s.kind, magicImpl: s.magic, flagsImpl: s.flags,
infoImpl: translateLineInfo(c, g, si, s.info),
optionsImpl: s.options,
positionImpl: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
offsetImpl: if s.kind in routineKinds: defaultOffset else: s.offset,
disamb: s.disamb,
name: getIdent(c.cache, g[si].fromDisk.strings[s.name])
)
@@ -945,8 +945,8 @@ proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
setOwner(result, loadSym(c, g, si, s.owner))
let externalName = g[si].fromDisk.strings[s.externalName]
if externalName != "":
result.loc.snippet = externalName
result.loc.flags = s.locFlags
result.locImpl.snippet = externalName
result.locImpl.flags = s.locFlags
result.instantiatedFrom = loadSym(c, g, si, s.instantiatedFrom)
proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
@@ -1058,12 +1058,12 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
let filename = AbsoluteFile toFullPath(conf, fileIdx)
# We cannot call ``newSym`` here, because we have to circumvent the ID
# mechanism, which we do in order to assign each module a persistent ID.
m.module = PSym(kind: skModule, itemId: ItemId(module: int32(fileIdx), item: 0'i32),
m.module = PSym(kindImpl: skModule, itemId: ItemId(module: int32(fileIdx), item: 0'i32),
name: getIdent(cache, splitFile(filename).name),
info: newLineInfo(fileIdx, 1, 1),
position: int(fileIdx))
infoImpl: newLineInfo(fileIdx, 1, 1),
positionImpl: int(fileIdx))
setOwner(m.module, getPackage(conf, cache, fileIdx))
m.module.flags = m.fromDisk.moduleFlags
m.module.flagsImpl = m.fromDisk.moduleFlags
proc loadToReplayNodes(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
fileIdx: FileIndex; m: var LoadedModule) =

View File

@@ -311,7 +311,7 @@ proc errorSym*(c: PContext, ident: PIdent, info: TLineInfo): PSym =
## creates an error symbol to avoid cascading errors (for IDE support)
result = newSym(skError, ident, c.idgen, getCurrOwner(c), info, {})
result.typ = errorType(c)
incl(result.flags, sfDiscardable)
incl(result.flagsImpl, sfDiscardable)
# pretend it's from the top level scope to prevent cascading errors:
if c.config.cmd != cmdInteractive and c.compilesContextId == 0:
c.moduleScope.addSym(result)

View File

@@ -82,7 +82,7 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: P
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
incl(temp.flagsImpl, sfFromGeneric)
tempAsNode = newSymNode(temp)
var v = newNodeI(nkVarSection, value.info)
@@ -103,7 +103,7 @@ proc evalOnce*(g: ModuleGraph; value: PNode; idgen: IdGenerator; owner: PSym): P
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), idgen,
owner, value.info, g.config.options)
temp.typ = skipTypes(value.typ, abstractInst)
incl(temp.flags, sfFromGeneric)
incl(temp.flagsImpl, sfFromGeneric)
var v = newNodeI(nkLetSection, value.info)
let tempAsNode = newSymNode(temp)
@@ -127,8 +127,8 @@ proc lowerSwap*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNod
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
var temp = newSym(skVar, getIdent(g.cache, genPrefix), idgen, owner, n.info, owner.options)
temp.typ = n[1].typ
incl(temp.flags, sfFromGeneric)
incl(temp.flags, sfGenSym)
incl(temp.flagsImpl, sfFromGeneric)
incl(temp.flagsImpl, sfGenSym)
var v = newNodeI(nkVarSection, n.info)
let tempAsNode = newSymNode(temp)
@@ -153,7 +153,7 @@ proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo
result.n = newNodeI(nkRecList, info)
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
idgen, owner, info, owner.options)
incl s.flags, sfAnon
incl s.flagsImpl, sfAnon
s.typ = result
result.sym = s

View File

@@ -681,13 +681,13 @@ proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
if m != nil:
g.suggestSymbols.del(fileIdx)
g.suggestErrors.del(fileIdx)
incl m.flags, sfDirty
incl m.flagsImpl, sfDirty
proc unmarkAllDirty*(g: ModuleGraph) =
for i in 0i32..<g.ifaces.len.int32:
let m = g.ifaces[i].module
if m != nil:
m.flags.excl sfDirty
m.flagsImpl.excl sfDirty
proc isDirty*(g: ModuleGraph; m: PSym): bool =
result = g.suggestMode and sfDirty in m.flags

View File

@@ -148,7 +148,7 @@ proc pragmaEnsures(c: PContext, n: PNode) =
if o.kind in routineKinds and o.typ != nil and o.typ.returnType != nil:
var s = newSym(skResult, getIdent(c.cache, "result"), c.idgen, o, n.info)
s.typ = o.typ.returnType
incl(s.flags, sfUsed)
incl(s.flagsImpl, sfUsed)
addDecl(c, s)
n[1] = c.semExpr(c, n[1])
closeScope(c)
@@ -156,12 +156,12 @@ proc pragmaEnsures(c: PContext, n: PNode) =
proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
# special cases to improve performance:
if extname == "$1":
s.loc.snippet = rope(s.name.s)
s.setSnippet(rope(s.name.s))
elif '$' notin extname:
s.loc.snippet = rope(extname)
s.setSnippet(rope(extname))
else:
try:
s.loc.snippet = rope(extname % s.name.s)
s.setSnippet(rope(extname % s.name.s))
except ValueError:
localError(c.config, info, "invalid extern name: '" & extname & "'. (Forgot to escape '$'?)")
when hasFFI:
@@ -170,36 +170,36 @@ proc setExternName(c: PContext; s: PSym, extname: string, info: TLineInfo) =
proc makeExternImport(c: PContext; s: PSym, extname: string, info: TLineInfo) =
setExternName(c, s, extname, info)
incl(s.flags, sfImportc)
excl(s.flags, sfForward)
s.incl(sfImportc)
s.excl(sfForward)
proc makeExternExport(c: PContext; s: PSym, extname: string, info: TLineInfo) =
setExternName(c, s, extname, info)
incl(s.flags, sfExportc)
s.incl(sfExportc)
proc processImportCompilerProc(c: PContext; s: PSym, extname: string, info: TLineInfo) =
setExternName(c, s, extname, info)
incl(s.flags, sfImportc)
excl(s.flags, sfForward)
incl(s.loc.flags, lfImportCompilerProc)
s.incl(sfImportc)
s.excl(sfForward)
incl(s.locImpl.flags, lfImportCompilerProc)
proc processImportCpp(c: PContext; s: PSym, extname: string, info: TLineInfo) =
setExternName(c, s, extname, info)
incl(s.flags, sfImportc)
incl(s.flags, sfInfixCall)
excl(s.flags, sfForward)
s.incl(sfImportc)
incl(s.flagsImpl, sfInfixCall)
excl(s.flagsImpl, sfForward)
if c.config.backend == backendC:
let m = s.getModule()
incl(m.flags, sfCompileToCpp)
incl(m.flagsImpl, sfCompileToCpp)
incl c.config.globalOptions, optMixedMode
proc processImportObjC(c: PContext; s: PSym, extname: string, info: TLineInfo) =
setExternName(c, s, extname, info)
incl(s.flags, sfImportc)
incl(s.flags, sfNamedParamCall)
excl(s.flags, sfForward)
s.incl(sfImportc)
incl(s.flagsImpl, sfNamedParamCall)
excl(s.flagsImpl, sfForward)
let m = s.getModule()
incl(m.flags, sfCompileToObjc)
m.incl(sfCompileToObjc)
proc newEmptyStrNode(c: PContext; n: PNode, strVal: string = ""): PNode {.noinline.} =
result = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
@@ -239,14 +239,14 @@ proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string =
proc processVirtual(c: PContext, n: PNode, s: PSym, flag: TSymFlag) =
s.constraint = newEmptyStrNode(c, n, getOptionalStr(c, n, "$1"))
s.constraint.strVal = s.constraint.strVal % s.name.s
s.flags.incl {flag, sfInfixCall, sfExportc, sfMangleCpp}
s.flagsImpl.incl {flag, sfInfixCall, sfExportc, sfMangleCpp}
s.typ.callConv = ccMember
incl c.config.globalOptions, optMixedMode
proc processCodegenDecl(c: PContext, n: PNode, sym: PSym) =
sym.constraint = getStrLitNode(c, n)
sym.flags.incl sfCodegenDecl
sym.flagsImpl.incl sfCodegenDecl
proc processMagic(c: PContext, n: PNode, s: PSym) =
#if sfSystemModule notin c.module.flags:
@@ -282,10 +282,10 @@ proc onOff(c: PContext, n: PNode, op: TOptions, resOptions: var TOptions) =
proc pragmaNoForward*(c: PContext, n: PNode; flag=sfNoForward) =
if isTurnedOn(c, n):
incl(c.module.flags, flag)
incl(c.module.flagsImpl, flag)
c.features.incl codeReordering
else:
excl(c.module.flags, flag)
excl(c.module.flagsImpl, flag)
# c.features.excl codeReordering
# deprecated as of 0.18.1
@@ -357,9 +357,9 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
var lib = getLib(c, libDynamic, expectDynlibNode(c, n))
if not lib.isOverridden:
addToLib(lib, sym)
incl(sym.loc.flags, lfDynamicLib)
sym.incl(lfDynamicLib)
else:
incl(sym.loc.flags, lfExportLib)
sym.incl(lfExportLib)
# since we'll be loading the dynlib symbols dynamically, we must use
# a calling convention that doesn't introduce custom name mangling
# cdecl is the default - the user can override this explicitly
@@ -435,7 +435,7 @@ proc processExperimental(c: PContext; n: PNode) =
if not isTopLevel(c):
localError(c.config, n.info,
"Code reordering experimental pragma only valid at toplevel")
c.module.flags.incl sfReorder
c.module.flagsImpl.incl sfReorder
except ValueError:
localError(c.config, n[1].info, "unknown experimental feature")
else:
@@ -636,7 +636,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
var e = searchInScopes(con, getIdent(con.cache, sub), amb)
# XXX what to do here if 'amb' is true?
if e != nil:
incl(e.flags, sfUsed)
incl(e.flagsImpl, sfUsed)
if isDefined(con.config, "nimPreviewAsmSemSymbol"):
result.add con.semExprWithType(con, newSymNode(e), {efTypeAllowed})
else:
@@ -764,8 +764,8 @@ proc markCompilerProc(c: PContext; s: PSym) =
# should not have an external name set:
if s.kind != skType or s.name.s != "FlowVar":
makeExternExport(c, s, "$1", s.info)
incl(s.flags, sfCompilerProc)
incl(s.flags, sfUsed)
incl(s, sfCompilerProc)
incl(s.flagsImpl, sfUsed)
registerCompilerProc(c.graph, s)
if c.config.symbolFiles != disabledSf:
addCompilerProc(c.encoder, c.packedRepr, s)
@@ -773,7 +773,7 @@ proc markCompilerProc(c: PContext; s: PSym) =
proc deprecatedStmt(c: PContext; outerPragma: PNode) =
let pragma = outerPragma[1]
if pragma.kind in {nkStrLit..nkTripleStrLit}:
incl(c.module.flags, sfDeprecated)
incl(c.module, sfDeprecated)
c.module.constraint = getStrLitNode(c, outerPragma)
return
if pragma.kind != nkBracket:
@@ -842,7 +842,7 @@ proc processEffectsOf(c: PContext, n: PNode; owner: PSym) =
let r = c.semExpr(c, n)
if r.kind == nkSym and r.sym.kind == skParam:
if r.sym.owner == owner:
incl r.sym.flags, sfEffectsDelayed
incl r.sym, sfEffectsDelayed
else:
localError(c.config, n.info, errGenerated, "parameter cannot be declared as .effectsOf")
else:
@@ -907,8 +907,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
if c.config.backend != backendCpp:
localError(c.config, it.info, "exportcpp requires `cpp` backend, got: " & $c.config.backend)
else:
incl(sym.flags, sfMangleCpp)
incl(sym.flags, sfUsed) # avoid wrong hints
incl(sym, sfMangleCpp)
incl(sym.flagsImpl, sfUsed) # avoid wrong hints
of wImportc:
let name = getOptionalStr(c, it, "$1")
cppDefine(c.config, name)
@@ -921,24 +921,24 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
processImportCompilerProc(c, sym, name, it.info)
of wExtern: setExternName(c, sym, expectStrLit(c, it), it.info)
of wDirty:
if sym.kind == skTemplate: incl(sym.flags, sfDirty)
if sym.kind == skTemplate: incl(sym, sfDirty)
else: invalidPragma(c, it)
of wRedefine:
if sym.kind == skTemplate: incl(sym.flags, sfTemplateRedefinition)
if sym.kind == skTemplate: incl(sym, sfTemplateRedefinition)
else: invalidPragma(c, it)
of wCallsite:
if sym.kind == skTemplate: incl(sym.flags, sfCallsite)
if sym.kind == skTemplate: incl(sym, sfCallsite)
else: invalidPragma(c, it)
of wImportCpp:
processImportCpp(c, sym, getOptionalStr(c, it, "$1"), it.info)
of wCppNonPod:
incl(sym.flags, sfCppNonPod)
incl(sym, sfCppNonPod)
of wImportJs:
if c.config.backend != backendJs:
localError(c.config, it.info, "`importjs` pragma requires the JavaScript target")
let name = getOptionalStr(c, it, "$1")
incl(sym.flags, sfImportc)
incl(sym.flags, sfInfixCall)
incl(sym, sfImportc)
incl(sym.flagsImpl, sfInfixCall)
if sym.kind in skProcKinds and {'(', '#', '@'} notin name:
localError(c.config, n.info, "`importjs` for routines requires a pattern")
setExternName(c, sym, name, it.info)
@@ -968,29 +968,29 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
localError(c.config, it.info, "power of two expected")
of wNodecl:
noVal(c, it)
incl(sym.loc.flags, lfNoDecl)
sym.incl(lfNoDecl)
of wPure, wAsmNoStackFrame:
noVal(c, it)
if sym != nil:
if k == wPure and sym.kind in routineKinds: invalidPragma(c, it)
else: incl(sym.flags, sfPure)
else: incl(sym, sfPure)
of wVolatile:
noVal(c, it)
incl(sym.flags, sfVolatile)
incl(sym, sfVolatile)
of wCursor:
noVal(c, it)
incl(sym.flags, sfCursor)
incl(sym, sfCursor)
of wRegister:
noVal(c, it)
incl(sym.flags, sfRegister)
incl(sym, sfRegister)
of wNoalias:
noVal(c, it)
incl(sym.flags, sfNoalias)
incl(sym, sfNoalias)
of wEffectsOf:
processEffectsOf(c, it, sym)
of wThreadVar:
noVal(c, it)
incl(sym.flags, {sfThread, sfGlobal})
incl(sym, {sfThread, sfGlobal})
of wDeadCodeElimUnused:
warningDeprecated(c.config, n.info, "'{.deadcodeelim: on.}' is deprecated, now a noop") # deprecated, dead code elim always on
of wNoForward: pragmaNoForward(c, it)
@@ -1000,20 +1000,19 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
noVal(c, it)
if comesFromPush:
if sym.kind in {skProc, skFunc}:
incl(sym.flags, sfCompileTime)
incl(sym, sfCompileTime)
else:
incl(sym.flags, sfCompileTime)
incl(sym, sfCompileTime)
#incl(sym.loc.flags, lfNoDecl)
of wGlobal:
noVal(c, it)
incl(sym.flags, sfGlobal)
incl(sym.flags, sfPure)
incl(sym, {sfGlobal, sfPure})
of wConstructor:
incl(sym.flags, sfConstructor)
incl(sym, sfConstructor)
if sfImportc notin sym.flags:
sym.constraint = newEmptyStrNode(c, it, getOptionalStr(c, it, ""))
sym.constraint.strVal = sym.constraint.strVal
sym.flags.incl {sfExportc, sfMangleCpp}
sym.flagsImpl.incl {sfExportc, sfMangleCpp}
sym.typ.callConv = ccNoConvention
of wHeader:
var lib = getLib(c, libHeader, getStrLitNode(c, it))

View File

@@ -568,7 +568,7 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
proc symFromType*(c: PContext; t: PType, info: TLineInfo): PSym =
if t.sym != nil: return t.sym
result = newSym(skType, getIdent(c.cache, "AnonType"), c.idgen, t.owner, info)
result.flags.incl sfAnon
result.flagsImpl.incl sfAnon
result.typ = t
proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
@@ -577,7 +577,7 @@ proc symNodeFromType*(c: PContext, t: PType, info: TLineInfo): PNode =
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
incl(s.flags, sfAddrTaken)
incl(s.flagsImpl, sfAddrTaken)
# XXX add to 'c' for global analysis
proc illFormedAst*(n: PNode; conf: ConfigRef) =
@@ -685,7 +685,7 @@ proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
# n.sym.typ can be nil in 'check' mode ...
if n.sym.typ != nil and
skipTypes(n.sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
incl(n.sym.flags, sfAddrTaken)
incl(n.sym.flagsImpl, sfAddrTaken)
result = newHiddenAddrTaken(c, n, isOutParam)
of nkDotExpr:
checkSonsLen(n, 2, c.config)
@@ -693,12 +693,12 @@ proc analyseIfAddressTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
internalError(c.config, n.info, "analyseIfAddressTaken")
return
if skipTypes(n[1].sym.typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
incl(n[1].sym.flags, sfAddrTaken)
incl(n[1].sym.flagsImpl, sfAddrTaken)
result = newHiddenAddrTaken(c, n, isOutParam)
of nkBracketExpr:
checkMinSonsLen(n, 1, c.config)
if skipTypes(n[0].typ, abstractInst-{tyTypeDesc}).kind notin {tyVar, tyLent}:
if n[0].kind == nkSym: incl(n[0].sym.flags, sfAddrTaken)
if n[0].kind == nkSym: incl(n[0].sym.flagsImpl, sfAddrTaken)
result = newHiddenAddrTaken(c, n, isOutParam)
else:
result = newHiddenAddrTaken(c, n, isOutParam)

View File

@@ -279,8 +279,10 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT
if result.sym.kind == skField and result.sym.ast != nil and
(cl.owner == nil or result.sym.owner == cl.owner):
# instantiate default value of object/tuple field
cl.c.fitDefaultNode(cl.c, result.sym.ast, result.sym.typ)
result.sym.typ = result.sym.ast.typ.skipIntLit(cl.c.idgen)
var n = result.sym.ast
cl.c.fitDefaultNode(cl.c, n, result.sym.typ)
result.sym.ast = n
result.sym.typ = n.typ.skipIntLit(cl.c.idgen)
# sym type can be nil if was gensym created by macro, see #24048
if result.sym.typ != nil and result.sym.typ.kind == tyVoid:
# don't add the 'void' field
@@ -361,7 +363,7 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym, t: PType): PSym =
]#
result = copySym(s, cl.c.idgen)
incl(result.flags, sfFromGeneric)
incl(result.flagsImpl, sfFromGeneric)
#idTablePut(cl.symMap, s, result)
setOwner(result, s.owner)
result.typ = t
@@ -682,7 +684,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
of tyUserTypeClass:
result = t
of tyStatic:
if cl.c.matchedConcept != nil:
# allow concepts to not instantiate statics for now

View File

@@ -1671,7 +1671,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
let roota = if skipBoth or deptha > depthf: a.skipGenericAlias else: a
let rootf = if skipBoth or depthf > deptha: f.skipGenericAlias else: f
if f.isConcept:
result = enterConceptMatch(c, rootf, roota, flags)
elif a.kind == tyGenericInst:
@@ -2316,7 +2316,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
let fdest = typeRel(m, f, dest)
if fdest in {isEqual, isGeneric} and not (dest.kind == tyLent and f.kind in {tyVar}):
# can't fully mark used yet, may not be used in final call
incl(c.converters[i].flags, sfUsed)
incl(c.converters[i].flagsImpl, sfUsed)
markOwnerModuleAsUsed(c, c.converters[i])
var s = newSymNode(c.converters[i])
s.typ() = c.converters[i].typ

View File

@@ -43,7 +43,7 @@ when defined(nimsuggest):
const
sep = '\t'
type
type
ImportContext = object
isMultiImport: bool # True if we're in a [...] context
baseDir: string # e.g., "folder/" in "import folder/[..."
@@ -707,9 +707,9 @@ proc markOwnerModuleAsUsed(c: PContext; s: PSym) =
proc markUsed(c: PContext; info: TLineInfo; s: PSym; checkStyle = true; isGenericInstance = false) =
if not isGenericInstance:
let conf = c.config
incl(s.flags, sfUsed)
incl(s.flagsImpl, sfUsed)
if s.kind == skEnumField and s.owner != nil:
incl(s.owner.flags, sfUsed)
incl(s.owner.flagsImpl, sfUsed)
if sfDeprecated in s.owner.flags:
warnAboutDeprecated(conf, info, s)
if {sfDeprecated, sfError} * s.flags != {}:
@@ -788,7 +788,7 @@ proc extractImportContextFromAst(n: PNode, cursorCol: int): ImportContext =
proc findModuleFile(c: PContext, partialPath: string): seq[string] =
result = @[]
let currentModuleDir = parentDir(toFullPath(c.config, FileIndex(c.module.position)))
proc tryAddModule(path, baseName: string) =
if fileExists(path & ".nim"):
result.add(baseName)
@@ -800,7 +800,7 @@ proc findModuleFile(c: PContext, partialPath: string): seq[string] =
let (_, name, ext) = splitFile(path)
if kind == pcFile:
if ext == ".nim" and name.startsWith(file):
result.add(name)
result.add(name)
proc collectImportModulesFromDir(dir: string, result: var seq[string]) =
for kind, path in walkDir(dir):
@@ -809,10 +809,10 @@ proc findModuleFile(c: PContext, partialPath: string): seq[string] =
if kind == pcFile:
if ext == ".nim" and name.startsWith(partialPath):
result.add(name)
else:
else:
if name.startsWith(partialPath):
result.add(name)
if '/' in partialPath:
let parts = partialPath.split('/')
let dir = parts[0]
@@ -839,13 +839,13 @@ proc suggestModuleNames(c: PContext, n: PNode) =
column: n.info.col.int,
doc: "",
quality: 100,
contextFits: true,
contextFits: true,
prefix: if partialPath.len > 0: prefixMatch(path, partialPath)
else: PrefixMatch.None,
symkind: byte skModule
)
suggestions.add(suggest)
let importCtx = extractImportContextFromAst(n, c.config.m.trackPos.col)
var searchPath = ""
if importCtx.baseDir.len > 0:
@@ -901,7 +901,7 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
if outputs.len > 0 and c.config.ideCmd in {ideSug, ideCon, ideDef}:
produceOutput(outputs, c.config)
suggestQuit()
proc suggestExpr*(c: PContext, n: PNode) =
if exactEquals(c.config.m.trackPos, n.info): suggestExprNoCheck(c, n)

View File

@@ -1014,6 +1014,6 @@ proc computeCursors*(s: PSym; n: PNode; g: ModuleGraph) =
if par.s[rid].con.kind == isRootOf and dangerousMutation(par.graphs[par.s[rid].con.graphIndex], par.s[i]):
discard "cannot cursor into a graph that is mutated"
else:
v.sym.flags.incl sfCursor
v.sym.flagsImpl.incl sfCursor
when false:
echo "this is now a cursor ", v.sym, " ", par.s[rid].flags, " ", g.config $ v.sym.info