refactoring: make FileIndex a distinct type; make line information an uint16; fixes #7654

This commit is contained in:
Andreas Rumpf 2018-04-21 08:13:37 +02:00
commit 33b69f0ed0
29 changed files with 196 additions and 311 deletions

View file

@ -1042,9 +1042,9 @@ proc newNode*(kind: TNodeKind): PNode =
new(result) new(result)
result.kind = kind result.kind = kind
#result.info = UnknownLineInfo() inlined: #result.info = UnknownLineInfo() inlined:
result.info.fileIndex = int32(-1) result.info.fileIndex = InvalidFileIdx
result.info.col = int16(-1) result.info.col = int16(-1)
result.info.line = int16(-1) result.info.line = uint16(0)
when defined(useNodeIds): when defined(useNodeIds):
result.id = gNodeId result.id = gNodeId
if result.id == nodeIdToDebug: if result.id == nodeIdToDebug:
@ -1116,13 +1116,13 @@ proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
s.typ = t s.typ = t
result = s result = s
template fileIdx*(c: PSym): int32 = template fileIdx*(c: PSym): FileIndex =
# XXX: this should be used only on module symbols # XXX: this should be used only on module symbols
c.position.int32 c.position.FileIndex
template filename*(c: PSym): string = template filename*(c: PSym): string =
# XXX: this should be used only on module symbols # XXX: this should be used only on module symbols
c.position.int32.toFilename c.position.FileIndex.toFilename
proc appendToModule*(m: PSym, n: PNode) = proc appendToModule*(m: PSym, n: PNode) =
## The compiler will use this internally to add nodes that will be ## The compiler will use this internally to add nodes that will be

View file

@ -2023,7 +2023,7 @@ template genStmtListExprImpl(exprOrStmt) {.dirty.} =
let theMacro = it[0].sym let theMacro = it[0].sym
add p.s(cpsStmts), initFrameNoDebug(p, frameName, add p.s(cpsStmts), initFrameNoDebug(p, frameName,
makeCString theMacro.name.s, makeCString theMacro.name.s,
theMacro.info.quotedFilename, it.info.line) theMacro.info.quotedFilename, it.info.line.int)
else: else:
genStmts(p, it) genStmts(p, it)
if n.len > 0: exprOrStmt if n.len > 0: exprOrStmt

View file

@ -223,7 +223,7 @@ proc genLineDir(p: BProc, t: PNode) =
line.rope, makeCString(toFilename(tt.info))) line.rope, makeCString(toFilename(tt.info)))
elif ({optLineTrace, optStackTrace} * p.options == elif ({optLineTrace, optStackTrace} * p.options ==
{optLineTrace, optStackTrace}) and {optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex >= 0: (p.prc == nil or sfPure notin p.prc.flags) and tt.info.fileIndex != InvalidFileIDX:
if freshLineInfo(p, tt.info): if freshLineInfo(p, tt.info):
linefmt(p, cpsStmts, "nimln_($1, $2);$n", linefmt(p, cpsStmts, "nimln_($1, $2);$n",
line.rope, tt.info.quotedFilename) line.rope, tt.info.quotedFilename)
@ -678,7 +678,7 @@ proc generateHeaders(m: BModule) =
proc openNamespaceNim(): Rope = proc openNamespaceNim(): Rope =
result.add("namespace Nim {" & tnl) result.add("namespace Nim {" & tnl)
proc closeNamespaceNim(): Rope = proc closeNamespaceNim(): Rope =
result.add("}" & tnl) result.add("}" & tnl)
@ -1090,7 +1090,7 @@ proc genMainProc(m: BModule) =
appcg(m, m.s[cfsProcs], nimMain, appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, rope(m.labels)]) [m.g.mainModInit, initStackBottomCall, rope(m.labels)])
if optNoMain notin gGlobalOptions: if optNoMain notin gGlobalOptions:
if useNimNamespace: if useNimNamespace:
m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;" & tnl m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;" & tnl
appcg(m, m.s[cfsProcs], otherMain, []) appcg(m, m.s[cfsProcs], otherMain, [])
@ -1202,7 +1202,7 @@ proc genModule(m: BModule, cfile: Cfile): Rope =
add(result, genSectionStart(i)) add(result, genSectionStart(i))
add(result, m.s[i]) add(result, m.s[i])
add(result, genSectionEnd(i)) add(result, genSectionEnd(i))
if useNimNamespace and i == cfsHeaders: result.add openNamespaceNim() if useNimNamespace and i == cfsHeaders: result.add openNamespaceNim()
add(result, m.s[cfsInitProc]) add(result, m.s[cfsInitProc])
if useNimNamespace: result.add closeNamespaceNim() if useNimNamespace: result.add closeNamespaceNim()
@ -1301,7 +1301,7 @@ proc resetCgenModules*(g: BModuleList) =
for m in cgenModules(g): resetModule(m) for m in cgenModules(g): resetModule(m)
proc rawNewModule(g: BModuleList; module: PSym): BModule = proc rawNewModule(g: BModuleList; module: PSym): BModule =
result = rawNewModule(g, module, module.position.int32.toFullPath) result = rawNewModule(g, module, module.position.FileIndex.toFullPath)
proc newModule(g: BModuleList; module: PSym): BModule = proc newModule(g: BModuleList; module: PSym): BModule =
# we should create only one cgen module for each module sym # we should create only one cgen module for each module sym
@ -1311,7 +1311,7 @@ proc newModule(g: BModuleList; module: PSym): BModule =
if (optDeadCodeElim in gGlobalOptions): if (optDeadCodeElim in gGlobalOptions):
if (sfDeadCodeElim in module.flags): if (sfDeadCodeElim in module.flags):
internalError("added pending module twice: " & module.filename) internalError("added pending module twice: " & toFilename(FileIndex module.position))
template injectG(config) {.dirty.} = template injectG(config) {.dirty.} =
if graph.backend == nil: if graph.backend == nil:

View file

@ -319,7 +319,7 @@ proc trackDirty(arg: string, info: TLineInfo) =
localError(info, errInvalidNumber, a[2]) localError(info, errInvalidNumber, a[2])
let dirtyOriginalIdx = a[1].fileInfoIdx let dirtyOriginalIdx = a[1].fileInfoIdx
if dirtyOriginalIdx >= 0: if dirtyOriginalIdx.int32 >= 0:
msgs.setDirtyFile(dirtyOriginalIdx, a[0]) msgs.setDirtyFile(dirtyOriginalIdx, a[0])
gTrackPos = newLineInfo(dirtyOriginalIdx, line, column) gTrackPos = newLineInfo(dirtyOriginalIdx, line, column)

View file

@ -544,7 +544,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments}) initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments})
result = %{ "name": %name, "type": %($k), "line": %n.info.line, result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
"col": %n.info.col} "col": %n.info.col}
if comm != nil and comm != "": if comm != nil and comm != "":
result["description"] = %comm result["description"] = %comm
@ -618,7 +618,7 @@ proc generateJson*(d: PDoc, n: PNode) =
of nkCommentStmt: of nkCommentStmt:
if n.comment != nil and startsWith(n.comment, "##"): if n.comment != nil and startsWith(n.comment, "##"):
let stripped = n.comment.substr(2).strip let stripped = n.comment.substr(2).strip
d.add %{ "comment": %stripped, "line": %n.info.line, d.add %{ "comment": %stripped, "line": %n.info.line.int,
"col": %n.info.col } "col": %n.info.col }
of nkProcDef: of nkProcDef:
when useEffectSystem: documentRaises(n) when useEffectSystem: documentRaises(n)
@ -790,7 +790,7 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string,
discard "fixme: error report" discard "fixme: error report"
proc commandDoc*() = proc commandDoc*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true
@ -840,7 +840,7 @@ proc commandRst2TeX*() =
commandRstAux(gProjectFull, TexExt) commandRstAux(gProjectFull, TexExt)
proc commandJson*() = proc commandJson*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true
@ -855,7 +855,7 @@ proc commandJson*() =
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false) writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
proc commandTags*() = proc commandTags*() =
var ast = parseFile(gProjectMainIdx, newIdentCache()) var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true

View file

@ -35,7 +35,7 @@ const
proc newLine(p: var TTmplParser) = proc newLine(p: var TTmplParser) =
llStreamWrite(p.outp, repeat(')', p.emitPar)) llStreamWrite(p.outp, repeat(')', p.emitPar))
p.emitPar = 0 p.emitPar = 0
if p.info.line > int16(1): llStreamWrite(p.outp, "\n") if p.info.line > uint16(1): llStreamWrite(p.outp, "\n")
if p.pendingExprLine: if p.pendingExprLine:
llStreamWrite(p.outp, spaces(2)) llStreamWrite(p.outp, spaces(2))
p.pendingExprLine = false p.pendingExprLine = false
@ -212,9 +212,9 @@ proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream =
p.x = newStringOfCap(120) p.x = newStringOfCap(120)
# do not process the first line which contains the directive: # do not process the first line which contains the directive:
if llStreamReadLine(p.inp, p.x): if llStreamReadLine(p.inp, p.x):
p.info.line = p.info.line + int16(1) p.info.line = p.info.line + 1'u16
while llStreamReadLine(p.inp, p.x): while llStreamReadLine(p.inp, p.x):
p.info.line = p.info.line + int16(1) p.info.line = p.info.line + 1'u16
parseLine(p) parseLine(p)
newLine(p) newLine(p)
result = p.outp result = p.outp

View file

@ -2261,7 +2261,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
var m = BModule(b) var m = BModule(b)
if sfMainModule in m.module.flags: if sfMainModule in m.module.flags:
let ext = "js" let ext = "js"
let f = if globals.classes.len == 0: m.module.filename let f = if globals.classes.len == 0: toFilename(FileIndex m.module.position)
else: "nimsystem" else: "nimsystem"
let code = wholeCode(graph, m) let code = wholeCode(graph, m)
let outfile = let outfile =

View file

@ -133,7 +133,7 @@ type
TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string) TErrorHandler* = proc (info: TLineInfo; msg: TMsgKind; arg: string)
TLexer* = object of TBaseLexer TLexer* = object of TBaseLexer
fileIdx*: int32 fileIdx*: FileIndex
indentAhead*: int # if > 0 an indendation has already been read indentAhead*: int # if > 0 an indendation has already been read
# this is needed because scanning comments # this is needed because scanning comments
# needs so much look-ahead # needs so much look-ahead
@ -222,7 +222,7 @@ proc fillToken(L: var TToken) =
L.commentOffsetA = 0 L.commentOffsetA = 0
L.commentOffsetB = 0 L.commentOffsetB = 0
proc openLexer*(lex: var TLexer, fileIdx: int32, inputstream: PLLStream; proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
openBaseLexer(lex, inputstream) openBaseLexer(lex, inputstream)
lex.fileIdx = fileidx lex.fileIdx = fileidx
@ -274,7 +274,7 @@ template tokenEnd(tok, pos) {.dirty.} =
when defined(nimsuggest): when defined(nimsuggest):
let colB = getColNumber(L, pos)+1 let colB = getColNumber(L, pos)+1
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
L.cursor = CursorPosition.InToken L.cursor = CursorPosition.InToken
gTrackPos.col = colA.int16 gTrackPos.col = colA.int16
colA = 0 colA = 0
@ -285,9 +285,9 @@ template tokenEndIgnore(tok, pos) =
when defined(nimsuggest): when defined(nimsuggest):
let colB = getColNumber(L, pos) let colB = getColNumber(L, pos)
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
gTrackPos.fileIndex = trackPosInvalidFileIdx gTrackPos.fileIndex = trackPosInvalidFileIdx
gTrackPos.line = -1 gTrackPos.line = 0'u16
colA = 0 colA = 0
when defined(nimpretty): when defined(nimpretty):
tok.offsetB = L.offsetBase + pos tok.offsetB = L.offsetBase + pos
@ -299,7 +299,7 @@ template tokenEndPrevious(tok, pos) =
# the cursor in a string literal or comment: # the cursor in a string literal or comment:
let colB = getColNumber(L, pos) let colB = getColNumber(L, pos)
if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and if L.fileIdx == gTrackPos.fileIndex and gTrackPos.col in colA..colB and
L.lineNumber == gTrackPos.line and gIdeCmd in {ideSug, ideCon}: L.lineNumber == gTrackPos.line.int and gIdeCmd in {ideSug, ideCon}:
L.cursor = CursorPosition.BeforeToken L.cursor = CursorPosition.BeforeToken
gTrackPos = L.previousToken gTrackPos = L.previousToken
gTrackPosAttached = true gTrackPosAttached = true
@ -1066,7 +1066,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
when defined(nimsuggest): when defined(nimsuggest):
# we attach the cursor to the last *strong* token # we attach the cursor to the last *strong* token
if tok.tokType notin weakTokens: if tok.tokType notin weakTokens:
L.previousToken.line = tok.line.int16 L.previousToken.line = tok.line.uint16
L.previousToken.col = tok.col.int16 L.previousToken.col = tok.col.int16
when defined(nimsuggest): when defined(nimsuggest):
@ -1118,7 +1118,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
tok.tokType = tkParLe tok.tokType = tkParLe
when defined(nimsuggest): when defined(nimsuggest):
if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and if L.fileIdx == gTrackPos.fileIndex and tok.col < gTrackPos.col and
tok.line == gTrackPos.line and gIdeCmd == ideCon: tok.line == gTrackPos.line.int and gIdeCmd == ideCon:
gTrackPos.col = tok.col.int16 gTrackPos.col = tok.col.int16
of ')': of ')':
tok.tokType = tkParRi tok.tokType = tkParRi
@ -1139,7 +1139,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
of '.': of '.':
when defined(nimsuggest): when defined(nimsuggest):
if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and
tok.line == gTrackPos.line and gIdeCmd == ideSug: tok.line == gTrackPos.line.int and gIdeCmd == ideSug:
tok.tokType = tkDot tok.tokType = tkDot
L.cursor = CursorPosition.InToken L.cursor = CursorPosition.InToken
gTrackPos.col = tok.col.int16 gTrackPos.col = tok.col.int16

View file

@ -35,7 +35,7 @@ proc writeDepsFile(g: ModuleGraph; project: string) =
let f = open(changeFileExt(project, "deps"), fmWrite) let f = open(changeFileExt(project, "deps"), fmWrite)
for m in g.modules: for m in g.modules:
if m != nil: if m != nil:
f.writeLine(toFullPath(m.position.int32)) f.writeLine(toFullPath(m.position.FileIndex))
for k in g.inclToMod.keys: for k in g.inclToMod.keys:
if g.getModule(k).isNil: # don't repeat includes which are also modules if g.getModule(k).isNil: # don't repeat includes which are also modules
f.writeLine(k.toFullPath) f.writeLine(k.toFullPath)
@ -265,7 +265,7 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
of "parse": of "parse":
gCmd = cmdParse gCmd = cmdParse
wantMainModule() wantMainModule()
discard parseFile(gProjectMainIdx, cache) discard parseFile(FileIndex gProjectMainIdx, cache)
of "scan": of "scan":
gCmd = cmdScan gCmd = cmdScan
wantMainModule() wantMainModule()

View file

@ -25,7 +25,7 @@
## - Its dependent module stays the same. ## - Its dependent module stays the same.
## ##
import ast, intsets, tables, options, rod import ast, intsets, tables, options, rod, msgs, hashes
type type
ModuleGraph* = ref object ModuleGraph* = ref object
@ -34,10 +34,10 @@ type
deps*: IntSet # the dependency graph or potentially its transitive closure. deps*: IntSet # the dependency graph or potentially its transitive closure.
suggestMode*: bool # whether we are in nimsuggest mode or not. suggestMode*: bool # whether we are in nimsuggest mode or not.
invalidTransitiveClosure: bool invalidTransitiveClosure: bool
inclToMod*: Table[int32, int32] # mapping of include file to the inclToMod*: Table[FileIndex, FileIndex] # mapping of include file to the
# first module that included it # first module that included it
importStack*: seq[int32] # The current import stack. Used for detecting recursive importStack*: seq[FileIndex] # The current import stack. Used for detecting recursive
# module dependencies. # module dependencies.
backend*: RootRef # minor hack so that a backend can extend this easily backend*: RootRef # minor hack so that a backend can extend this easily
config*: ConfigRef config*: ConfigRef
doStopCompile*: proc(): bool {.closure.} doStopCompile*: proc(): bool {.closure.}
@ -45,6 +45,8 @@ type
owners*: seq[PSym] owners*: seq[PSym]
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]] methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]]
proc hash*(x: FileIndex): Hash {.borrow.}
{.this: g.} {.this: g.}
proc stopCompile*(g: ModuleGraph): bool {.inline.} = proc stopCompile*(g: ModuleGraph): bool {.inline.} =
@ -56,7 +58,7 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
result.deps = initIntSet() result.deps = initIntSet()
result.modules = @[] result.modules = @[]
result.importStack = @[] result.importStack = @[]
result.inclToMod = initTable[int32, int32]() result.inclToMod = initTable[FileIndex, FileIndex]()
if config.isNil: if config.isNil:
result.config = newConfigRef() result.config = newConfigRef()
else: else:
@ -69,35 +71,35 @@ proc resetAllModules*(g: ModuleGraph) =
deps = initIntSet() deps = initIntSet()
modules = @[] modules = @[]
importStack = @[] importStack = @[]
inclToMod = initTable[int32, int32]() inclToMod = initTable[FileIndex, FileIndex]()
usageSym = nil usageSym = nil
owners = @[] owners = @[]
methods = @[] methods = @[]
proc getModule*(g: ModuleGraph; fileIdx: int32): PSym = proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
if fileIdx >= 0 and fileIdx < modules.len: if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len:
result = modules[fileIdx] result = modules[fileIdx.int32]
proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b
proc addDep*(g: ModuleGraph; m: PSym, dep: int32) = proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
assert m.position == m.info.fileIndex assert m.position == m.info.fileIndex.int32
addModuleDep(m.info.fileIndex, dep, isIncludeFile = false) addModuleDep(m.info.fileIndex, dep, isIncludeFile = false)
if suggestMode: if suggestMode:
deps.incl m.position.dependsOn(dep) deps.incl m.position.dependsOn(dep.int)
# we compute the transitive closure later when quering the graph lazily. # we compute the transitive closure later when quering the graph lazily.
# this improve efficiency quite a lot: # this improve efficiency quite a lot:
#invalidTransitiveClosure = true #invalidTransitiveClosure = true
proc addIncludeDep*(g: ModuleGraph; module, includeFile: int32) = proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) =
addModuleDep(module, includeFile, isIncludeFile = true) addModuleDep(module, includeFile, isIncludeFile = true)
discard hasKeyOrPut(inclToMod, includeFile, module) discard hasKeyOrPut(inclToMod, includeFile, module)
proc parentModule*(g: ModuleGraph; fileIdx: int32): int32 = proc parentModule*(g: ModuleGraph; fileIdx: FileIndex): FileIndex =
## returns 'fileIdx' if the file belonging to this index is ## returns 'fileIdx' if the file belonging to this index is
## directly used as a module or else the module that first ## directly used as a module or else the module that first
## references this include file. ## references this include file.
if fileIdx >= 0 and fileIdx < modules.len and modules[fileIdx] != nil: if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len and modules[fileIdx.int32] != nil:
result = fileIdx result = fileIdx
else: else:
result = inclToMod.getOrDefault(fileIdx) result = inclToMod.getOrDefault(fileIdx)
@ -111,11 +113,11 @@ proc transitiveClosure(g: var IntSet; n: int) =
if g.contains(i.dependsOn(k)) and g.contains(k.dependsOn(j)): if g.contains(i.dependsOn(k)) and g.contains(k.dependsOn(j)):
g.incl i.dependsOn(j) g.incl i.dependsOn(j)
proc markDirty*(g: ModuleGraph; fileIdx: int32) = proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
let m = getModule fileIdx let m = getModule fileIdx
if m != nil: incl m.flags, sfDirty if m != nil: incl m.flags, sfDirty
proc markClientsDirty*(g: ModuleGraph; fileIdx: int32) = proc markClientsDirty*(g: ModuleGraph; fileIdx: FileIndex) =
# we need to mark its dependent modules D as dirty right away because after # we need to mark its dependent modules D as dirty right away because after
# nimsuggest is done with this module, the module's dirty flag will be # nimsuggest is done with this module, the module's dirty flag will be
# cleared but D still needs to be remembered as 'dirty'. # cleared but D still needs to be remembered as 'dirty'.
@ -126,7 +128,7 @@ proc markClientsDirty*(g: ModuleGraph; fileIdx: int32) =
# every module that *depends* on this file is also dirty: # every module that *depends* on this file is also dirty:
for i in 0i32..<modules.len.int32: for i in 0i32..<modules.len.int32:
let m = modules[i] let m = modules[i]
if m != nil and deps.contains(i.dependsOn(fileIdx)): if m != nil and deps.contains(i.dependsOn(fileIdx.int)):
incl m.flags, sfDirty incl m.flags, sfDirty
proc isDirty*(g: ModuleGraph; m: PSym): bool = proc isDirty*(g: ModuleGraph; m: PSym): bool =

View file

@ -174,7 +174,7 @@ proc getModuleName*(n: PNode): string =
localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree) localError(n.info, errGenerated, "invalid module name: '$1'" % n.renderTree)
result = "" result = ""
proc checkModuleName*(n: PNode; doLocalError=true): int32 = proc checkModuleName*(n: PNode; doLocalError=true): FileIndex =
# This returns the full canonical path for a given module import # This returns the full canonical path for a given module import
let modulename = n.getModuleName let modulename = n.getModuleName
let fullPath = findModule(modulename, n.info.toFullPath) let fullPath = findModule(modulename, n.info.toFullPath)

View file

@ -121,7 +121,7 @@ when false:
proc resetSystemArtifacts*() = proc resetSystemArtifacts*() =
magicsys.resetSysTypes() magicsys.resetSysTypes()
proc newModule(graph: ModuleGraph; fileIdx: int32): PSym = proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
# We cannot call ``newSym`` here, because we have to circumvent the ID # 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. # mechanism, which we do in order to assign each module a persistent ID.
new(result) new(result)
@ -144,9 +144,9 @@ proc newModule(graph: ModuleGraph; fileIdx: int32): PSym =
graph.packageSyms.strTableAdd(packSym) graph.packageSyms.strTableAdd(packSym)
result.owner = packSym result.owner = packSym
result.position = fileIdx result.position = int fileIdx
growCache graph.modules, fileIdx growCache graph.modules, int fileIdx
graph.modules[result.position] = result graph.modules[result.position] = result
incl(result.flags, sfUsed) incl(result.flags, sfUsed)
@ -158,7 +158,7 @@ proc newModule(graph: ModuleGraph; fileIdx: int32): PSym =
# strTableIncl() for error corrections: # strTableIncl() for error corrections:
discard strTableIncl(packSym.tab, result) discard strTableIncl(packSym.tab, result)
proc compileModule*(graph: ModuleGraph; fileIdx: int32; cache: IdentCache, flags: TSymFlags): PSym = proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; cache: IdentCache, flags: TSymFlags): PSym =
result = graph.getModule(fileIdx) result = graph.getModule(fileIdx)
if result == nil: if result == nil:
#growCache gMemCacheData, fileIdx #growCache gMemCacheData, fileIdx
@ -199,7 +199,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: int32; cache: IdentCache, flags
else: else:
result = gCompiledModules[fileIdx] result = gCompiledModules[fileIdx]
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PSym {.procvar.} = cache: IdentCache): PSym {.procvar.} =
# this is called by the semantic checking phase # this is called by the semantic checking phase
result = compileModule(graph, fileIdx, cache, {}) result = compileModule(graph, fileIdx, cache, {})
@ -210,11 +210,11 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: int32;
gNotes = if s.owner.id == gMainPackageId: gMainPackageNotes gNotes = if s.owner.id == gMainPackageId: gMainPackageNotes
else: ForeignPackageNotes else: ForeignPackageNotes
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PNode {.procvar.} = cache: IdentCache): PNode {.procvar.} =
result = syntaxes.parseFile(fileIdx, cache) result = syntaxes.parseFile(fileIdx, cache)
graph.addDep(s, fileIdx) graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.int32, fileIdx) graph.addIncludeDep(s.position.FileIndex, fileIdx)
proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) = proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
if magicsys.systemModule == nil: if magicsys.systemModule == nil:
@ -224,16 +224,16 @@ proc compileSystemModule*(graph: ModuleGraph; cache: IdentCache) =
proc wantMainModule* = proc wantMainModule* =
if gProjectFull.len == 0: if gProjectFull.len == 0:
fatal(gCmdLineInfo, errCommandExpectsFilename) fatal(gCmdLineInfo, errCommandExpectsFilename)
gProjectMainIdx = addFileExt(gProjectFull, NimExt).fileInfoIdx gProjectMainIdx = int32 addFileExt(gProjectFull, NimExt).fileInfoIdx
passes.gIncludeFile = includeModule passes.gIncludeFile = includeModule
passes.gImportModule = importModule passes.gImportModule = importModule
proc compileProject*(graph: ModuleGraph; cache: IdentCache; proc compileProject*(graph: ModuleGraph; cache: IdentCache;
projectFileIdx = -1'i32) = projectFileIdx = InvalidFileIDX) =
wantMainModule() wantMainModule()
let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") let systemFileIdx = fileInfoIdx(options.libpath / "system.nim")
let projectFile = if projectFileIdx < 0: gProjectMainIdx else: projectFileIdx let projectFile = if projectFileIdx == InvalidFileIDX: FileIndex(gProjectMainIdx) else: projectFileIdx
graph.importStack.add projectFile graph.importStack.add projectFile
if projectFile == systemFileIdx: if projectFile == systemFileIdx:
discard graph.compileModule(projectFile, cache, {sfMainModule, sfSystemModule}) discard graph.compileModule(projectFile, cache, {sfMainModule, sfSystemModule})

View file

@ -499,14 +499,15 @@ type
hash*: string # the checksum of the file hash*: string # the checksum of the file
when defined(nimpretty): when defined(nimpretty):
fullContent*: string fullContent*: string
FileIndex* = int32 # XXX will make this 'distinct' later FileIndex* = distinct int32
TLineInfo* = object # This is designed to be as small as possible, TLineInfo* = object # This is designed to be as small as possible,
# because it is used # because it is used
# in syntax nodes. We save space here by using # in syntax nodes. We save space here by using
# two int16 and an int32. # two int16 and an int32.
# On 64 bit and on 32 bit systems this is # On 64 bit and on 32 bit systems this is
# only 8 bytes. # only 8 bytes.
line*, col*: int16 line*: uint16
col*: int16
fileIndex*: FileIndex fileIndex*: FileIndex
when defined(nimpretty): when defined(nimpretty):
offsetA*, offsetB*: int offsetA*, offsetB*: int
@ -521,6 +522,8 @@ type
ERecoverableError* = object of ValueError ERecoverableError* = object of ValueError
ESuggestDone* = object of Exception ESuggestDone* = object of Exception
proc `==`*(a, b: FileIndex): bool {.borrow.}
const const
NotesVerbosity*: array[0..3, TNoteKinds] = [ NotesVerbosity*: array[0..3, TNoteKinds] = [
{low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit, {low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit,
@ -545,14 +548,14 @@ const
{low(TNoteKind)..high(TNoteKind)}] {low(TNoteKind)..high(TNoteKind)}]
const const
InvalidFileIDX* = int32(-1) InvalidFileIDX* = FileIndex(-1)
var var
ForeignPackageNotes*: TNoteKinds = {hintProcessing, warnUnknownMagic, ForeignPackageNotes*: TNoteKinds = {hintProcessing, warnUnknownMagic,
hintQuitCalled, hintExecuting} hintQuitCalled, hintExecuting}
filenameToIndexTbl = initTable[string, int32]() filenameToIndexTbl = initTable[string, FileIndex]()
fileInfos*: seq[TFileInfo] = @[] fileInfos*: seq[TFileInfo] = @[]
systemFileIdx*: int32 systemFileIdx*: FileIndex
proc toCChar*(c: char): string = proc toCChar*(c: char): string =
case c case c
@ -598,7 +601,7 @@ proc newFileInfo(fullPath, projPath: string): TFileInfo =
when defined(nimpretty): when defined(nimpretty):
proc fileSection*(fid: FileIndex; a, b: int): string = proc fileSection*(fid: FileIndex; a, b: int): string =
substr(fileInfos[fid].fullContent, a, b) substr(fileInfos[fid.int].fullContent, a, b)
proc fileInfoKnown*(filename: string): bool = proc fileInfoKnown*(filename: string): bool =
var var
@ -609,7 +612,7 @@ proc fileInfoKnown*(filename: string): bool =
canon = filename canon = filename
result = filenameToIndexTbl.hasKey(canon) result = filenameToIndexTbl.hasKey(canon)
proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 = proc fileInfoIdx*(filename: string; isKnownFile: var bool): FileIndex =
var var
canon: string canon: string
pseudoPath = false pseudoPath = false
@ -627,28 +630,28 @@ proc fileInfoIdx*(filename: string; isKnownFile: var bool): int32 =
result = filenameToIndexTbl[canon] result = filenameToIndexTbl[canon]
else: else:
isKnownFile = false isKnownFile = false
result = fileInfos.len.int32 result = fileInfos.len.FileIndex
fileInfos.add(newFileInfo(canon, if pseudoPath: filename fileInfos.add(newFileInfo(canon, if pseudoPath: filename
else: canon.shortenDir)) else: canon.shortenDir))
filenameToIndexTbl[canon] = result filenameToIndexTbl[canon] = result
proc fileInfoIdx*(filename: string): int32 = proc fileInfoIdx*(filename: string): FileIndex =
var dummy: bool var dummy: bool
result = fileInfoIdx(filename, dummy) result = fileInfoIdx(filename, dummy)
proc newLineInfo*(fileInfoIdx: int32, line, col: int): TLineInfo = proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
result.fileIndex = fileInfoIdx result.fileIndex = fileInfoIdx
result.line = int16(line) result.line = uint16(line)
result.col = int16(col) result.col = int16(col)
proc newLineInfo*(filename: string, line, col: int): TLineInfo {.inline.} = proc newLineInfo*(filename: string, line, col: int): TLineInfo {.inline.} =
result = newLineInfo(filename.fileInfoIdx, line, col) result = newLineInfo(filename.fileInfoIdx, line, col)
fileInfos.add(newFileInfo("", "command line")) fileInfos.add(newFileInfo("", "command line"))
var gCmdLineInfo* = newLineInfo(int32(0), 1, 1) var gCmdLineInfo* = newLineInfo(FileIndex(0), 1, 1)
fileInfos.add(newFileInfo("", "compilation artifact")) fileInfos.add(newFileInfo("", "compilation artifact"))
var gCodegenLineInfo* = newLineInfo(int32(1), 1, 1) var gCodegenLineInfo* = newLineInfo(FileIndex(1), 1, 1)
proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} = proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
raise newException(ERecoverableError, msg) raise newException(ERecoverableError, msg)
@ -664,9 +667,9 @@ var
gMainPackageNotes*: TNoteKinds = NotesVerbosity[1] gMainPackageNotes*: TNoteKinds = NotesVerbosity[1]
proc unknownLineInfo*(): TLineInfo = proc unknownLineInfo*(): TLineInfo =
result.line = int16(-1) result.line = uint16(0)
result.col = int16(-1) result.col = int16(-1)
result.fileIndex = -1 result.fileIndex = InvalidFileIDX
type type
Severity* {.pure.} = enum ## VS Code only supports these three Severity* {.pure.} = enum ## VS Code only supports these three
@ -728,32 +731,32 @@ proc getInfoContext*(index: int): TLineInfo =
if i >=% L: result = unknownLineInfo() if i >=% L: result = unknownLineInfo()
else: result = msgContext[i] else: result = msgContext[i]
template toFilename*(fileIdx: int32): string = template toFilename*(fileIdx: FileIndex): string =
(if fileIdx < 0: "???" else: fileInfos[fileIdx].projPath) (if fileIdx.int32 < 0: "???" else: fileInfos[fileIdx.int32].projPath)
proc toFullPath*(fileIdx: int32): string = proc toFullPath*(fileIdx: FileIndex): string =
if fileIdx < 0: result = "???" if fileIdx.int32 < 0: result = "???"
else: result = fileInfos[fileIdx].fullPath else: result = fileInfos[fileIdx.int32].fullPath
proc setDirtyFile*(fileIdx: int32; filename: string) = proc setDirtyFile*(fileIdx: FileIndex; filename: string) =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
fileInfos[fileIdx].dirtyFile = filename fileInfos[fileIdx.int32].dirtyFile = filename
proc setHash*(fileIdx: int32; hash: string) = proc setHash*(fileIdx: FileIndex; hash: string) =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
shallowCopy(fileInfos[fileIdx].hash, hash) shallowCopy(fileInfos[fileIdx.int32].hash, hash)
proc getHash*(fileIdx: int32): string = proc getHash*(fileIdx: FileIndex): string =
assert fileIdx >= 0 assert fileIdx.int32 >= 0
shallowCopy(result, fileInfos[fileIdx].hash) shallowCopy(result, fileInfos[fileIdx.int32].hash)
proc toFullPathConsiderDirty*(fileIdx: int32): string = proc toFullPathConsiderDirty*(fileIdx: FileIndex): string =
if fileIdx < 0: if fileIdx.int32 < 0:
result = "???" result = "???"
elif not fileInfos[fileIdx].dirtyFile.isNil: elif not fileInfos[fileIdx.int32].dirtyFile.isNil:
result = fileInfos[fileIdx].dirtyFile result = fileInfos[fileIdx.int32].dirtyFile
else: else:
result = fileInfos[fileIdx].fullPath result = fileInfos[fileIdx.int32].fullPath
template toFilename*(info: TLineInfo): string = template toFilename*(info: TLineInfo): string =
info.fileIndex.toFilename info.fileIndex.toFilename
@ -762,15 +765,15 @@ template toFullPath*(info: TLineInfo): string =
info.fileIndex.toFullPath info.fileIndex.toFullPath
proc toMsgFilename*(info: TLineInfo): string = proc toMsgFilename*(info: TLineInfo): string =
if info.fileIndex < 0: if info.fileIndex.int32 < 0:
result = "???" result = "???"
elif gListFullPaths: elif gListFullPaths:
result = fileInfos[info.fileIndex].fullPath result = fileInfos[info.fileIndex.int32].fullPath
else: else:
result = fileInfos[info.fileIndex].projPath result = fileInfos[info.fileIndex.int32].projPath
proc toLinenumber*(info: TLineInfo): int {.inline.} = proc toLinenumber*(info: TLineInfo): int {.inline.} =
result = info.line result = int info.line
proc toColumn*(info: TLineInfo): int {.inline.} = proc toColumn*(info: TLineInfo): int {.inline.} =
result = info.col result = info.col
@ -787,7 +790,7 @@ proc `??`* (info: TLineInfo, filename: string): bool =
# only for debugging purposes # only for debugging purposes
result = filename in info.toFilename result = filename in info.toFilename
const trackPosInvalidFileIdx* = -2 # special marker so that no suggestions const trackPosInvalidFileIdx* = FileIndex(-2) # special marker so that no suggestions
# are produced within comments and string literals # are produced within comments and string literals
var gTrackPos*: TLineInfo var gTrackPos*: TLineInfo
var gTrackPosAttached*: bool ## whether the tracking position was attached to some var gTrackPosAttached*: bool ## whether the tracking position was attached to some
@ -926,7 +929,7 @@ proc writeContext(lastinfo: TLineInfo) =
else: else:
styledMsgWriteln(styleBright, styledMsgWriteln(styleBright,
PosFormat % [toMsgFilename(msgContext[i]), PosFormat % [toMsgFilename(msgContext[i]),
coordToStr(msgContext[i].line), coordToStr(msgContext[i].line.int),
coordToStr(msgContext[i].col+1)], coordToStr(msgContext[i].col+1)],
resetStyle, resetStyle,
getMessageStr(errInstantiationFrom, "")) getMessageStr(errInstantiationFrom, ""))
@ -994,7 +997,7 @@ proc formatMsg*(info: TLineInfo, msg: TMsgKind, arg: string): string =
of warnMin..warnMax: WarningTitle of warnMin..warnMax: WarningTitle
of hintMin..hintMax: HintTitle of hintMin..hintMax: HintTitle
else: ErrorTitle else: ErrorTitle
result = PosFormat % [toMsgFilename(info), coordToStr(info.line), result = PosFormat % [toMsgFilename(info), coordToStr(info.line.int),
coordToStr(info.col+1)] & coordToStr(info.col+1)] &
title & title &
getMessageStr(msg, arg) getMessageStr(msg, arg)
@ -1035,7 +1038,7 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
# NOTE: currently line info line numbers start with 1, # NOTE: currently line info line numbers start with 1,
# but column numbers start with 0, however most editors expect # but column numbers start with 0, however most editors expect
# first column to be 1, so we need to +1 here # first column to be 1, so we need to +1 here
let x = PosFormat % [toMsgFilename(info), coordToStr(info.line), let x = PosFormat % [toMsgFilename(info), coordToStr(info.line.int),
coordToStr(info.col+1)] coordToStr(info.col+1)]
let s = getMessageStr(msg, arg) let s = getMessageStr(msg, arg)
@ -1093,30 +1096,30 @@ template assertNotNil*(e): untyped =
template internalAssert*(e: bool) = template internalAssert*(e: bool) =
if not e: internalError($instantiationInfo()) if not e: internalError($instantiationInfo())
proc addSourceLine*(fileIdx: int32, line: string) = proc addSourceLine*(fileIdx: FileIndex, line: string) =
fileInfos[fileIdx].lines.add line.rope fileInfos[fileIdx.int32].lines.add line.rope
proc sourceLine*(i: TLineInfo): Rope = proc sourceLine*(i: TLineInfo): Rope =
if i.fileIndex < 0: return nil if i.fileIndex.int32 < 0: return nil
if not optPreserveOrigSource and fileInfos[i.fileIndex].lines.len == 0: if not optPreserveOrigSource and fileInfos[i.fileIndex.int32].lines.len == 0:
try: try:
for line in lines(i.toFullPath): for line in lines(i.toFullPath):
addSourceLine i.fileIndex, line.string addSourceLine i.fileIndex, line.string
except IOError: except IOError:
discard discard
internalAssert i.fileIndex < fileInfos.len internalAssert i.fileIndex.int32 < fileInfos.len
# can happen if the error points to EOF: # can happen if the error points to EOF:
if i.line > fileInfos[i.fileIndex].lines.len: return nil if i.line.int > fileInfos[i.fileIndex.int32].lines.len: return nil
result = fileInfos[i.fileIndex].lines[i.line-1] result = fileInfos[i.fileIndex.int32].lines[i.line.int-1]
proc quotedFilename*(i: TLineInfo): Rope = proc quotedFilename*(i: TLineInfo): Rope =
internalAssert i.fileIndex >= 0 internalAssert i.fileIndex.int32 >= 0
if optExcessiveStackTrace in gGlobalOptions: if optExcessiveStackTrace in gGlobalOptions:
result = fileInfos[i.fileIndex].quotedFullName result = fileInfos[i.fileIndex.int32].quotedFullName
else: else:
result = fileInfos[i.fileIndex].quotedName result = fileInfos[i.fileIndex.int32].quotedName
ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) = ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) =
case err case err

View file

@ -28,7 +28,7 @@ proc overwriteFiles*() =
let doStrip = options.getConfigVar("pretty.strip").normalize == "on" let doStrip = options.getConfigVar("pretty.strip").normalize == "on"
for i in 0 .. high(gSourceFiles): for i in 0 .. high(gSourceFiles):
if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile and if gSourceFiles[i].dirty and not gSourceFiles[i].isNimfixFile and
(not gOnlyMainfile or gSourceFiles[i].fileIdx == gProjectMainIdx): (not gOnlyMainfile or gSourceFiles[i].fileIdx == gProjectMainIdx.FileIndex):
let newFile = if gOverWrite: gSourceFiles[i].fullpath let newFile = if gOverWrite: gSourceFiles[i].fullpath
else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim") else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim")
try: try:
@ -95,7 +95,7 @@ proc beautifyName(s: string, k: TSymKind): string =
proc replaceInFile(info: TLineInfo; newName: string) = proc replaceInFile(info: TLineInfo; newName: string) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int].lines[info.line.int-1]
var first = min(info.col.int, line.len) var first = min(info.col.int, line.len)
if first < 0: return if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first) #inc first, skipIgnoreCase(line, "proc ", first)
@ -107,8 +107,8 @@ proc replaceInFile(info: TLineInfo; newName: string) =
if differ(line, first, last, newName): if differ(line, first, last, newName):
# last-first+1 != newName.len or # last-first+1 != newName.len or
var x = line.substr(0, first-1) & newName & line.substr(last+1) var x = line.substr(0, first-1) & newName & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int].dirty = true
proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) = proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) =
let beau = beautifyName(s, k) let beau = beautifyName(s, k)
@ -136,7 +136,7 @@ template styleCheckDef*(s: PSym) =
styleCheckDef(s.info, s, s.kind) styleCheckDef(s.info, s, s.kind)
proc styleCheckUseImpl(info: TLineInfo; s: PSym) = proc styleCheckUseImpl(info: TLineInfo; s: PSym) =
if info.fileIndex < 0: return if info.fileIndex.int < 0: return
# we simply convert it to what it looks like in the definition # we simply convert it to what it looks like in the definition
# for consistency # for consistency

View file

@ -16,13 +16,13 @@ type
lines*: seq[string] lines*: seq[string]
dirty*, isNimfixFile*: bool dirty*, isNimfixFile*: bool
fullpath*, newline*: string fullpath*, newline*: string
fileIdx*: int32 fileIdx*: FileIndex
var var
gSourceFiles*: seq[TSourceFile] = @[] gSourceFiles*: seq[TSourceFile] = @[]
proc loadFile*(info: TLineInfo) = proc loadFile*(info: TLineInfo) =
let i = info.fileIndex let i = info.fileIndex.int
if i >= gSourceFiles.len: if i >= gSourceFiles.len:
gSourceFiles.setLen(i+1) gSourceFiles.setLen(i+1)
if gSourceFiles[i].lines.isNil: if gSourceFiles[i].lines.isNil:
@ -64,7 +64,7 @@ proc differ*(line: string, a, b: int, x: string): bool =
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) = proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1]
var first = min(info.col.int, line.len) var first = min(info.col.int, line.len)
if first < 0: return if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first) #inc first, skipIgnoreCase(line, "proc ", first)
@ -75,8 +75,8 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PIdent) =
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
if cmpIgnoreStyle(line[first..last], oldSym.s) == 0: if cmpIgnoreStyle(line[first..last], oldSym.s) == 0:
var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) var x = line.substr(0, first-1) & newSym.s & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int32].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int32].dirty = true
#if newSym.s == "File": writeStackTrace() #if newSym.s == "File": writeStackTrace()
proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) = proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
@ -85,10 +85,10 @@ proc replaceDeprecated*(info: TLineInfo; oldSym, newSym: PSym) =
proc replaceComment*(info: TLineInfo) = proc replaceComment*(info: TLineInfo) =
loadFile(info) loadFile(info)
let line = gSourceFiles[info.fileIndex].lines[info.line-1] let line = gSourceFiles[info.fileIndex.int32].lines[info.line.int-1]
var first = info.col.int var first = info.col.int
if line[first] != '#': inc first if line[first] != '#': inc first
var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x) system.shallowCopy(gSourceFiles[info.fileIndex.int32].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex].dirty = true gSourceFiles[info.fileIndex.int32].dirty = true

View file

@ -235,7 +235,8 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
result = arLValue result = arLValue
else: else:
result = isAssignable(owner, n.sons[0], isUnsafeAddr) result = isAssignable(owner, n.sons[0], isUnsafeAddr)
if result != arNone and sfDiscriminant in n.sons[1].sym.flags: if result != arNone and n[1].kind == nkSym and
sfDiscriminant in n[1].sym.flags:
result = arDiscriminant result = arDiscriminant
of nkBracketExpr: of nkBracketExpr:
if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in if skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}).kind in

View file

@ -83,7 +83,7 @@ proc getTok(p: var TParser) =
rawGetTok(p.lex, p.tok) rawGetTok(p.lex, p.tok)
p.hasProgress = true p.hasProgress = true
proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream, proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
cache: IdentCache; cache: IdentCache;
strongSpaces=false) = strongSpaces=false) =
## Open a parser, using the given arguments to set up its internal state. ## Open a parser, using the given arguments to set up its internal state.

View file

@ -52,8 +52,8 @@ proc makePass*(open: TPassOpen = nil,
# the semantic checker needs these: # the semantic checker needs these:
var var
gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PSym {.nimcall.} gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PSym {.nimcall.}
gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PNode {.nimcall.} gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PNode {.nimcall.}
# implementation # implementation
@ -63,20 +63,6 @@ proc skipCodegen*(n: PNode): bool {.inline.} =
# error count instead. # error count instead.
result = msgs.gErrorCounter > 0 result = msgs.gErrorCounter > 0
proc astNeeded*(s: PSym): bool =
# The ``rodwrite`` module uses this to determine if the body of a proc
# needs to be stored. The passes manager frees s.sons[codePos] when
# appropriate to free the procedure body's memory. This is important
# to keep memory usage down.
if (s.kind in {skMethod, skProc, skFunc}) and
({sfCompilerProc, sfCompileTime} * s.flags == {}) and
(s.typ.callConv != ccInline) and
(s.ast.sons[genericParamsPos].kind == nkEmpty):
result = false
# XXX this doesn't really make sense with excessive CTFE
else:
result = true
const const
maxPasses = 10 maxPasses = 10
@ -153,7 +139,7 @@ proc closePassesCached(graph: ModuleGraph; a: var TPassContextArray) =
m = gPasses[i].close(graph, a[i], m) m = gPasses[i].close(graph, a[i], m)
a[i] = nil # free the memory here a[i] = nil # free the memory here
proc resolveMod(module, relativeTo: string): int32 = proc resolveMod(module, relativeTo: string): FileIndex =
let fullPath = findModule(module, relativeTo) let fullPath = findModule(module, relativeTo)
if fullPath.len == 0: if fullPath.len == 0:
result = InvalidFileIDX result = InvalidFileIDX
@ -166,7 +152,7 @@ proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
let relativeTo = m.info.toFullPath let relativeTo = m.info.toFullPath
for module in items(implicits): for module in items(implicits):
# implicit imports should not lead to a module importing itself # implicit imports should not lead to a module importing itself
if m.position != resolveMod(module, relativeTo): if m.position != resolveMod(module, relativeTo).int32:
var importStmt = newNodeI(nodeKind, gCmdLineInfo) var importStmt = newNodeI(nodeKind, gCmdLineInfo)
var str = newStrNode(nkStrLit, module) var str = newStrNode(nkStrLit, module)
str.info = gCmdLineInfo str.info = gCmdLineInfo
@ -180,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
p: TParsers p: TParsers
a: TPassContextArray a: TPassContextArray
s: PLLStream s: PLLStream
fileIdx = module.fileIdx fileIdx = FileIndex module.fileIdx
if module.id < 0: if module.id < 0:
# new module caching mechanism: # new module caching mechanism:
for i in 0..<gPassesLen: for i in 0..<gPassesLen:

View file

@ -19,7 +19,7 @@ proc getTok(p: var TParser) =
## `tok` member. ## `tok` member.
rawGetTok(p.lex, p.tok) rawGetTok(p.lex, p.tok)
proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream; proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
## Open a parser, using the given arguments to set up its internal state. ## Open a parser, using the given arguments to set up its internal state.
## ##

View file

@ -543,7 +543,7 @@ proc pragmaLine(c: PContext, n: PNode) =
else: else:
# XXX this produces weird paths which are not properly resolved: # XXX this produces weird paths which are not properly resolved:
n.info.fileIndex = msgs.fileInfoIdx(x.strVal) n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
n.info.line = int16(y.intVal) n.info.line = uint16(y.intVal)
else: else:
localError(n.info, errXExpected, "tuple") localError(n.info, errXExpected, "tuple")
else: else:

View file

@ -1,6 +1,6 @@
import import
intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils, intsets, ast, idents, algorithm, renderer, parser, ospaths, strutils,
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables
type type
@ -135,13 +135,13 @@ proc hasIncludes(n:PNode): bool =
if a.kind == nkIncludeStmt: if a.kind == nkIncludeStmt:
return true return true
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: int32; proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
cache: IdentCache): PNode {.procvar.} = cache: IdentCache): PNode {.procvar.} =
result = syntaxes.parseFile(fileIdx, cache) result = syntaxes.parseFile(fileIdx, cache)
graph.addDep(s, fileIdx) graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.int32, fileIdx) graph.addIncludeDep(FileIndex s.position, fileIdx)
proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode, proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
modulePath: string, includedFiles: var IntSet, modulePath: string, includedFiles: var IntSet,
cache: IdentCache): PNode = cache: IdentCache): PNode =
# Parses includes and injects them in the current tree # Parses includes and injects them in the current tree
@ -153,13 +153,13 @@ proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
for i in 0..<a.len: for i in 0..<a.len:
var f = checkModuleName(a.sons[i]) var f = checkModuleName(a.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(includedFiles, f): if containsOrIncl(includedFiles, f.int):
localError(a.info, errRecursiveDependencyX, f.toFilename) localError(a.info, errRecursiveDependencyX, f.toFilename)
else: else:
let nn = includeModule(graph, module, f, cache) let nn = includeModule(graph, module, f, cache)
let nnn = expandIncludes(graph, module, nn, modulePath, let nnn = expandIncludes(graph, module, nn, modulePath,
includedFiles, cache) includedFiles, cache)
excl(includedFiles, f) excl(includedFiles, f.int)
for b in nnn: for b in nnn:
result.add b result.add b
else: else:
@ -429,8 +429,8 @@ proc reorder*(graph: ModuleGraph, n: PNode, module: PSym, cache: IdentCache): PN
if n.hasForbiddenPragma: if n.hasForbiddenPragma:
return n return n
var includedFiles = initIntSet() var includedFiles = initIntSet()
let mpath = module.fileIdx.toFullPath let mpath = module.fileIdx.FileIndex.toFullPath
let n = expandIncludes(graph, module, n, mpath, let n = expandIncludes(graph, module, n, mpath,
includedFiles, cache).splitSections includedFiles, cache).splitSections
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)
var deps = newSeq[(IntSet, IntSet)](n.len) var deps = newSeq[(IntSet, IntSet)](n.len)

View file

@ -9,124 +9,18 @@
## This module implements the canonalization for the various caching mechanisms. ## This module implements the canonalization for the various caching mechanisms.
import ast, idgen import ast, idgen, msgs
when not defined(nimSymbolfiles): when not defined(nimSymbolfiles):
template setupModuleCache* = discard template setupModuleCache* = discard
template storeNode*(module: PSym; n: PNode) = discard template storeNode*(module: PSym; n: PNode) = discard
template loadNode*(module: PSym; index: var int): PNode = PNode(nil) template loadNode*(module: PSym; index: var int): PNode = PNode(nil)
template getModuleId*(fileIdx: int32; fullpath: string): int = getID() template getModuleId*(fileIdx: FileIndex; fullpath: string): int = getID()
template addModuleDep*(module, fileIdx: int32; isIncludeFile: bool) = discard template addModuleDep*(module, fileIdx: FileIndex; isIncludeFile: bool) = discard
template storeRemaining*(module: PSym) = discard template storeRemaining*(module: PSym) = discard
else: else:
include rodimpl include rodimpl
when false:
type
BlobWriter* = object
buf: string
pos: int
SerializationAction = enum acRead, acWrite
# Varint implementation inspired by SQLite.
proc rdVaruint64(z: ptr UncheckedArray[byte]; n: int; pResult: var uint64): int =
if z[0] <= 240:
pResult = z[0]
return 1
if z[0] <= 248:
if n < 2: return 0
pResult = (z[0] - 241) * 256 + z[1] + 240
return 2
if n < z[0]-246: return 0
if z[0] == 249:
pResult = 2288 + 256*z[1] + z[2]
return 3
if z[0] == 250:
pResult = (z[1] shl 16u64) + (z[2] shl 8u64) + z[3]
return 4
let x = (z[1] shl 24) + (z[2] shl 16) + (z[3] shl 8) + z[4]
if z[0] == 251:
pResult = x
return 5
if z[0] == 252:
pResult = (((uint64)x) shl 8) + z[5]
return 6
if z[0] == 253:
pResult = (((uint64)x) shl 16) + (z[5] shl 8) + z[6]
return 7
if z[0] == 254:
pResult = (((uint64)x) shl 24) + (z[5] shl 16) + (z[6] shl 8) + z[7]
return 8
pResult = (((uint64)x) shl 32) +
(0xffffffff & ((z[5] shl 24) + (z[6] shl 16) + (z[7] shl 8) + z[8]))
return 9
proc varintWrite32(z: ptr UncheckedArray[byte]; y: uint32) =
z[0] = uint8(y shr 24)
z[1] = uint8(y shr 16)
z[2] = uint8(y shr 8)
z[3] = uint8(y)
proc sqlite4PutVarint64(z: ptr UncheckedArray[byte], x: uint64): int =
## Write a varint into z. The buffer z must be at least 9 characters
## long to accommodate the largest possible varint. Returns the number of
## bytes used.
if x <= 240:
z[0] = uint8 x
return 1
if x <= 2287:
y = uint32(x - 240)
z[0] = uint8(y shr 8 + 241)
z[1] = uint8(y and 255)
return 2
if x <= 67823:
y = uint32(x - 2288)
z[0] = 249
z[1] = uint8(y shr 8)
z[2] = uint8(y and 255)
return 3
let y = uint32 x
let w = uint32(x shr 32)
if w == 0:
if y <= 16777215:
z[0] = 250
z[1] = uint8(y shr 16)
z[2] = uint8(y shr 8)
z[3] = uint8(y)
return 4
z[0] = 251
varintWrite32(z+1, y)
return 5
if w <= 255:
z[0] = 252
z[1] = uint8 w
varintWrite32(z+2, y)
return 6
if w <= 65535:
z[0] = 253
z[1] = uint8(w shr 8)
z[2] = uint8 w
varintWrite32(z+3, y)
return 7
if w <= 16777215:
z[0] = 254
z[1] = uint8(w shr 16)
z[2] = uint8(w shr 8)
z[3] = uint8 w
varintWrite32(z+4, y)
return 8
z[0] = 255
varintWrite32(z+1, w)
varintWrite32(z+5, y)
return 9
template field(x: BiggestInt; action: SerializationAction) =
when action == acRead:
readBiggestInt(x)
else:
writeBiggestInt()

View file

@ -126,8 +126,8 @@ type
s: cstring # mmap'ed file contents s: cstring # mmap'ed file contents
options: TOptions options: TOptions
reason: TReasonForRecompile reason: TReasonForRecompile
modDeps: seq[int32] modDeps: seq[FileIndex]
files: seq[int32] files: seq[FileIndex]
dataIdx: int # offset of start of data section dataIdx: int # offset of start of data section
convertersIdx: int # offset of start of converters section convertersIdx: int # offset of start of converters section
initIdx, interfIdx, compilerProcsIdx, methodsIdx: int initIdx, interfIdx, compilerProcsIdx, methodsIdx: int
@ -163,11 +163,11 @@ proc decodeLineInfo(r: PRodReader, info: var TLineInfo) =
else: info.col = int16(decodeVInt(r.s, r.pos)) else: info.col = int16(decodeVInt(r.s, r.pos))
if r.s[r.pos] == ',': if r.s[r.pos] == ',':
inc(r.pos) inc(r.pos)
if r.s[r.pos] == ',': info.line = -1'i16 if r.s[r.pos] == ',': info.line = 0'u16
else: info.line = int16(decodeVInt(r.s, r.pos)) else: info.line = uint16(decodeVInt(r.s, r.pos))
if r.s[r.pos] == ',': if r.s[r.pos] == ',':
inc(r.pos) inc(r.pos)
info = newLineInfo(r.files[decodeVInt(r.s, r.pos)], info.line, info.col) info = newLineInfo(r.files[decodeVInt(r.s, r.pos)], int info.line, info.col)
proc skipNode(r: PRodReader) = proc skipNode(r: PRodReader) =
assert r.s[r.pos] == '(' assert r.s[r.pos] == '('
@ -861,29 +861,29 @@ proc loadMethods(r: PRodReader) =
r.methods.add(rrGetSym(r, d, unknownLineInfo())) r.methods.add(rrGetSym(r, d, unknownLineInfo()))
if r.s[r.pos] == ' ': inc(r.pos) if r.s[r.pos] == ' ': inc(r.pos)
proc getHash*(fileIdx: int32): SecureHash = proc getHash*(fileIdx: FileIndex): SecureHash =
if fileIdx <% gMods.len and gMods[fileIdx].hashDone: if fileIdx.int32 <% gMods.len and gMods[fileIdx.int32].hashDone:
return gMods[fileIdx].hash return gMods[fileIdx.int32].hash
result = secureHashFile(fileIdx.toFullPath) result = secureHashFile(fileIdx.toFullPath)
if fileIdx >= gMods.len: setLen(gMods, fileIdx+1) if fileIdx.int32 >= gMods.len: setLen(gMods, fileIdx.int32+1)
gMods[fileIdx].hash = result gMods[fileIdx.int32].hash = result
template growCache*(cache, pos) = template growCache*(cache, pos) =
if cache.len <= pos: cache.setLen(pos+1) if cache.len <= pos: cache.setLen(pos+1)
proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile = proc checkDep(fileIdx: FileIndex; cache: IdentCache): TReasonForRecompile =
assert fileIdx != InvalidFileIDX assert fileIdx != InvalidFileIDX
growCache gMods, fileIdx growCache gMods, fileIdx.int32
if gMods[fileIdx].reason != rrEmpty: if gMods[fileIdx.int32].reason != rrEmpty:
# reason has already been computed for this module: # reason has already been computed for this module:
return gMods[fileIdx].reason return gMods[fileIdx.int32].reason
let filename = fileIdx.toFilename let filename = fileIdx.toFilename
var hash = getHash(fileIdx) var hash = getHash(fileIdx)
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles gMods[fileIdx.int32].reason = rrNone # we need to set it here to avoid cycles
result = rrNone result = rrNone
var rodfile = toGeneratedFile(filename.withPackageName, RodExt) var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
var r = newRodReader(rodfile, hash, fileIdx, cache) var r = newRodReader(rodfile, hash, fileIdx.int32, cache)
if r == nil: if r == nil:
result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
else: else:
@ -907,19 +907,18 @@ proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile =
# recompilation is necessary: # recompilation is necessary:
if r != nil: memfiles.close(r.memfile) if r != nil: memfiles.close(r.memfile)
r = nil r = nil
gMods[fileIdx].rd = r gMods[fileIdx.int32].rd = r
gMods[fileIdx].reason = result # now we know better gMods[fileIdx.int32].reason = result # now we know better
proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader = proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
let fileIdx = module.fileIdx
if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}: if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}:
module.id = getID() module.id = getID()
return nil return nil
idgen.loadMaxIds(options.gProjectPath / options.gProjectName) idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
let fileIdx = FileIndex module.fileIdx
discard checkDep(fileIdx, cache) discard checkDep(fileIdx, cache)
if gMods[fileIdx].reason == rrEmpty: internalError("handleSymbolFile") if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
result = gMods[fileIdx].rd result = gMods[fileIdx.int32].rd
if result != nil: if result != nil:
module.id = result.moduleID module.id = result.moduleID
result.syms[module.id] = module result.syms[module.id] = module
@ -1153,7 +1152,7 @@ proc viewFile(rodfile: string) =
if r.s[r.pos] == '\x0A': if r.s[r.pos] == '\x0A':
inc(r.pos) inc(r.pos)
inc(r.line) inc(r.line)
outf.write(w, " ", inclHash, "\n") outf.write(w.int32, " ", inclHash, "\n")
if r.s[r.pos] == ')': inc(r.pos) if r.s[r.pos] == ')': inc(r.pos)
outf.write(")\n") outf.write(")\n")
of "DEPS": of "DEPS":
@ -1163,7 +1162,7 @@ proc viewFile(rodfile: string) =
let v = int32(decodeVInt(r.s, r.pos)) let v = int32(decodeVInt(r.s, r.pos))
r.modDeps.add(r.files[v]) r.modDeps.add(r.files[v])
if r.s[r.pos] == ' ': inc(r.pos) if r.s[r.pos] == ' ': inc(r.pos)
outf.write(" ", r.files[v]) outf.write(" ", r.files[v].int32)
outf.write("\n") outf.write("\n")
of "INTERF", "COMPILERPROCS": of "INTERF", "COMPILERPROCS":
inc r.pos, 2 inc r.pos, 2

View file

@ -55,7 +55,7 @@ proc fileIdx(w: PRodWriter, filename: string): int =
w.files[result] = filename w.files[result] = filename
template filename*(w: PRodWriter): string = template filename*(w: PRodWriter): string =
w.module.filename toFilename(FileIndex w.module.position)
proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter = proc newRodWriter(hash: SecureHash, module: PSym; cache: IdentCache): PRodWriter =
new(result) new(result)
@ -125,14 +125,14 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
result.add(',') result.add(',')
encodeVInt(n.info.line, result) encodeVInt(int n.info.line, result)
result.add(',') result.add(',')
encodeVInt(fileIdx(w, toFullPath(n.info)), result) encodeVInt(fileIdx(w, toFullPath(n.info)), result)
elif fInfo.line != n.info.line: elif fInfo.line != n.info.line:
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
result.add(',') result.add(',')
encodeVInt(n.info.line, result) encodeVInt(int n.info.line, result)
elif fInfo.col != n.info.col: elif fInfo.col != n.info.col:
result.add('?') result.add('?')
encodeVInt(n.info.col, result) encodeVInt(n.info.col, result)
@ -303,7 +303,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
result.add('?') result.add('?')
if s.info.col != -1'i16: encodeVInt(s.info.col, result) if s.info.col != -1'i16: encodeVInt(s.info.col, result)
result.add(',') result.add(',')
if s.info.line != -1'i16: encodeVInt(s.info.line, result) if s.info.line != 0'u16: encodeVInt(int s.info.line, result)
result.add(',') result.add(',')
encodeVInt(fileIdx(w, toFullPath(s.info)), result) encodeVInt(fileIdx(w, toFullPath(s.info)), result)
if s.owner != nil: if s.owner != nil:
@ -642,7 +642,7 @@ proc process(c: PPassContext, n: PNode): PNode =
proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext = proc myOpen(g: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
if module.id < 0: internalError("rodwrite: module ID not set") if module.id < 0: internalError("rodwrite: module ID not set")
var w = newRodWriter(rodread.getHash module.fileIdx, module, cache) var w = newRodWriter(rodread.getHash FileIndex module.position, module, cache)
rawAddInterfaceSym(w, module) rawAddInterfaceSym(w, module)
result = w result = w

View file

@ -144,7 +144,7 @@ proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
proc filename*(c: PContext): string = proc filename*(c: PContext): string =
# the module's filename # the module's filename
return c.module.filename return toFilename(FileIndex c.module.position)
proc scopeDepth*(c: PContext): int {.inline.} = proc scopeDepth*(c: PContext): int {.inline.} =
result = if c.currentScope != nil: c.currentScope.depthLevel result = if c.currentScope != nil: c.currentScope.depthLevel

View file

@ -1095,12 +1095,12 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode =
for i in 0..<n.len: for i in 0..<n.len:
var f = checkModuleName(n.sons[i]) var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f): if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename) localError(n.info, errRecursiveDependencyX, f.toFilename)
else: else:
let code = gIncludeFile(c.graph, c.module, f, c.cache) let code = gIncludeFile(c.graph, c.module, f, c.cache)
gatherStmts c, code, result gatherStmts c, code, result
excl(c.includedFiles, f) excl(c.includedFiles, f.int)
of nkStmtList: of nkStmtList:
for i in 0 ..< n.len: for i in 0 ..< n.len:
gatherStmts(c, n.sons[i], result) gatherStmts(c, n.sons[i], result)
@ -1784,11 +1784,11 @@ proc evalInclude(c: PContext, n: PNode): PNode =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var f = checkModuleName(n.sons[i]) var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX: if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f): if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename) localError(n.info, errRecursiveDependencyX, f.toFilename)
else: else:
addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache))) addSon(result, semStmt(c, gIncludeFile(c.graph, c.module, f, c.cache)))
excl(c.includedFiles, f) excl(c.includedFiles, f.int)
proc setLine(n: PNode, info: TLineInfo) = proc setLine(n: PNode, info: TLineInfo) =
for i in 0 ..< safeLen(n): setLine(n.sons[i], info) for i in 0 ..< safeLen(n): setLine(n.sons[i], info)

View file

@ -415,7 +415,7 @@ when defined(nimsuggest):
# Since TLineInfo defined a == operator that doesn't include the column, # Since TLineInfo defined a == operator that doesn't include the column,
# we map TLineInfo to a unique int here for this lookup table: # we map TLineInfo to a unique int here for this lookup table:
proc infoToInt(info: TLineInfo): int64 = proc infoToInt(info: TLineInfo): int64 =
info.fileIndex + info.line.int64 shl 32 + info.col.int64 shl 48 info.fileIndex.int64 + info.line.int64 shl 32 + info.col.int64 shl 48
proc addNoDup(s: PSym; info: TLineInfo) = proc addNoDup(s: PSym; info: TLineInfo) =
# ensure nothing gets too slow: # ensure nothing gets too slow:
@ -574,7 +574,7 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
if outputs.len > 0: suggestQuit() if outputs.len > 0: suggestQuit()
proc suggestSentinel*(c: PContext) = proc suggestSentinel*(c: PContext) =
if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex: return if gIdeCmd != ideSug or c.module.position != gTrackPos.fileIndex.int32: return
if c.compilesContextId > 0: return if c.compilesContextId > 0: return
inc(c.compilesContextId) inc(c.compilesContextId)
var outputs: Suggestions = @[] var outputs: Suggestions = @[]

View file

@ -138,7 +138,7 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
else: else:
result = applyFilter(p, n, filename, result) result = applyFilter(p, n, filename, result)
proc openParsers*(p: var TParsers, fileIdx: int32, inputstream: PLLStream; proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream;
cache: IdentCache) = cache: IdentCache) =
var s: PLLStream var s: PLLStream
p.skin = skinStandard p.skin = skinStandard
@ -155,7 +155,7 @@ proc openParsers*(p: var TParsers, fileIdx: int32, inputstream: PLLStream;
proc closeParsers*(p: var TParsers) = proc closeParsers*(p: var TParsers) =
parser.closeParser(p.parser) parser.closeParser(p.parser)
proc parseFile*(fileIdx: int32; cache: IdentCache): PNode {.procvar.} = proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
var var
p: TParsers p: TParsers
f: File f: File

View file

@ -1381,7 +1381,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of opcNGetLine: of opcNGetLine:
decodeB(rkNode) decodeB(rkNode)
let n = regs[rb].node let n = regs[rb].node
regs[ra].node = newIntNode(nkIntLit, n.info.line) regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
regs[ra].node.info = n.info regs[ra].node.info = n.info
regs[ra].node.typ = n.typ regs[ra].node.typ = n.typ
of opcNGetColumn: of opcNGetColumn:
@ -1521,7 +1521,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
let x = newNodeI(TNodeKind(int(k)), let x = newNodeI(TNodeKind(int(k)),
if cc.kind != nkNilLit: if cc.kind != nkNilLit:
cc.info cc.info
elif c.comesFromHeuristic.line > -1: elif c.comesFromHeuristic.line != 0'u16:
c.comesFromHeuristic c.comesFromHeuristic
elif c.callsite != nil and c.callsite.safeLen > 1: elif c.callsite != nil and c.callsite.safeLen > 1:
c.callsite[1].info c.callsite[1].info
@ -1748,7 +1748,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
setupGlobalCtx(module, cache) setupGlobalCtx(module, cache)
var c = globalCtx var c = globalCtx
c.comesFromHeuristic.line = -1 c.comesFromHeuristic.line = 0'u16
c.callsite = nOrig c.callsite = nOrig
let start = genProc(c, sym) let start = genProc(c, sym)