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
parent 6667362c2f
commit 33b69f0ed0
29 changed files with 196 additions and 311 deletions

View File

@@ -1042,9 +1042,9 @@ proc newNode*(kind: TNodeKind): PNode =
new(result)
result.kind = kind
#result.info = UnknownLineInfo() inlined:
result.info.fileIndex = int32(-1)
result.info.fileIndex = InvalidFileIdx
result.info.col = int16(-1)
result.info.line = int16(-1)
result.info.line = uint16(0)
when defined(useNodeIds):
result.id = gNodeId
if result.id == nodeIdToDebug:
@@ -1116,13 +1116,13 @@ proc linkTo*(s: PSym, t: PType): PSym {.discardable.} =
s.typ = t
result = s
template fileIdx*(c: PSym): int32 =
template fileIdx*(c: PSym): FileIndex =
# XXX: this should be used only on module symbols
c.position.int32
c.position.FileIndex
template filename*(c: PSym): string =
# XXX: this should be used only on module symbols
c.position.int32.toFilename
c.position.FileIndex.toFilename
proc appendToModule*(m: PSym, n: PNode) =
## 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
add p.s(cpsStmts), initFrameNoDebug(p, frameName,
makeCString theMacro.name.s,
theMacro.info.quotedFilename, it.info.line)
theMacro.info.quotedFilename, it.info.line.int)
else:
genStmts(p, it)
if n.len > 0: exprOrStmt

View File

@@ -223,7 +223,7 @@ proc genLineDir(p: BProc, t: PNode) =
line.rope, makeCString(toFilename(tt.info)))
elif ({optLineTrace, optStackTrace} * p.options ==
{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):
linefmt(p, cpsStmts, "nimln_($1, $2);$n",
line.rope, tt.info.quotedFilename)
@@ -678,7 +678,7 @@ proc generateHeaders(m: BModule) =
proc openNamespaceNim(): Rope =
result.add("namespace Nim {" & tnl)
proc closeNamespaceNim(): Rope =
result.add("}" & tnl)
@@ -1090,7 +1090,7 @@ proc genMainProc(m: BModule) =
appcg(m, m.s[cfsProcs], nimMain,
[m.g.mainModInit, initStackBottomCall, rope(m.labels)])
if optNoMain notin gGlobalOptions:
if useNimNamespace:
if useNimNamespace:
m.s[cfsProcs].add closeNamespaceNim() & "using namespace Nim;" & tnl
appcg(m, m.s[cfsProcs], otherMain, [])
@@ -1202,7 +1202,7 @@ proc genModule(m: BModule, cfile: Cfile): Rope =
add(result, genSectionStart(i))
add(result, m.s[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])
if useNimNamespace: result.add closeNamespaceNim()
@@ -1301,7 +1301,7 @@ proc resetCgenModules*(g: BModuleList) =
for m in cgenModules(g): resetModule(m)
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 =
# 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 (sfDeadCodeElim in module.flags):
internalError("added pending module twice: " & module.filename)
internalError("added pending module twice: " & toFilename(FileIndex module.position))
template injectG(config) {.dirty.} =
if graph.backend == nil:

View File

@@ -319,7 +319,7 @@ proc trackDirty(arg: string, info: TLineInfo) =
localError(info, errInvalidNumber, a[2])
let dirtyOriginalIdx = a[1].fileInfoIdx
if dirtyOriginalIdx >= 0:
if dirtyOriginalIdx.int32 >= 0:
msgs.setDirtyFile(dirtyOriginalIdx, a[0])
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})
result = %{ "name": %name, "type": %($k), "line": %n.info.line,
result = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
"col": %n.info.col}
if comm != nil and comm != "":
result["description"] = %comm
@@ -618,7 +618,7 @@ proc generateJson*(d: PDoc, n: PNode) =
of nkCommentStmt:
if n.comment != nil and startsWith(n.comment, "##"):
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 }
of nkProcDef:
when useEffectSystem: documentRaises(n)
@@ -790,7 +790,7 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string,
discard "fixme: error report"
proc commandDoc*() =
var ast = parseFile(gProjectMainIdx, newIdentCache())
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true
@@ -840,7 +840,7 @@ proc commandRst2TeX*() =
commandRstAux(gProjectFull, TexExt)
proc commandJson*() =
var ast = parseFile(gProjectMainIdx, newIdentCache())
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true
@@ -855,7 +855,7 @@ proc commandJson*() =
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
proc commandTags*() =
var ast = parseFile(gProjectMainIdx, newIdentCache())
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true

View File

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

View File

@@ -2261,7 +2261,7 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
var m = BModule(b)
if sfMainModule in m.module.flags:
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"
let code = wholeCode(graph, m)
let outfile =

View File

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

View File

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

View File

@@ -25,7 +25,7 @@
## - Its dependent module stays the same.
##
import ast, intsets, tables, options, rod
import ast, intsets, tables, options, rod, msgs, hashes
type
ModuleGraph* = ref object
@@ -34,10 +34,10 @@ type
deps*: IntSet # the dependency graph or potentially its transitive closure.
suggestMode*: bool # whether we are in nimsuggest mode or not.
invalidTransitiveClosure: bool
inclToMod*: Table[int32, int32] # mapping of include file to the
# first module that included it
importStack*: seq[int32] # The current import stack. Used for detecting recursive
# module dependencies.
inclToMod*: Table[FileIndex, FileIndex] # mapping of include file to the
# first module that included it
importStack*: seq[FileIndex] # The current import stack. Used for detecting recursive
# module dependencies.
backend*: RootRef # minor hack so that a backend can extend this easily
config*: ConfigRef
doStopCompile*: proc(): bool {.closure.}
@@ -45,6 +45,8 @@ type
owners*: seq[PSym]
methods*: seq[tuple[methods: TSymSeq, dispatcher: PSym]]
proc hash*(x: FileIndex): Hash {.borrow.}
{.this: g.}
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
@@ -56,7 +58,7 @@ proc newModuleGraph*(config: ConfigRef = nil): ModuleGraph =
result.deps = initIntSet()
result.modules = @[]
result.importStack = @[]
result.inclToMod = initTable[int32, int32]()
result.inclToMod = initTable[FileIndex, FileIndex]()
if config.isNil:
result.config = newConfigRef()
else:
@@ -69,35 +71,35 @@ proc resetAllModules*(g: ModuleGraph) =
deps = initIntSet()
modules = @[]
importStack = @[]
inclToMod = initTable[int32, int32]()
inclToMod = initTable[FileIndex, FileIndex]()
usageSym = nil
owners = @[]
methods = @[]
proc getModule*(g: ModuleGraph; fileIdx: int32): PSym =
if fileIdx >= 0 and fileIdx < modules.len:
result = modules[fileIdx]
proc getModule*(g: ModuleGraph; fileIdx: FileIndex): PSym =
if fileIdx.int32 >= 0 and fileIdx.int32 < modules.len:
result = modules[fileIdx.int32]
proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b
proc addDep*(g: ModuleGraph; m: PSym, dep: int32) =
assert m.position == m.info.fileIndex
proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) =
assert m.position == m.info.fileIndex.int32
addModuleDep(m.info.fileIndex, dep, isIncludeFile = false)
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.
# this improve efficiency quite a lot:
#invalidTransitiveClosure = true
proc addIncludeDep*(g: ModuleGraph; module, includeFile: int32) =
proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) =
addModuleDep(module, includeFile, isIncludeFile = true)
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
## directly used as a module or else the module that first
## 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
else:
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)):
g.incl i.dependsOn(j)
proc markDirty*(g: ModuleGraph; fileIdx: int32) =
proc markDirty*(g: ModuleGraph; fileIdx: FileIndex) =
let m = getModule fileIdx
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
# nimsuggest is done with this module, the module's dirty flag will be
# 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:
for i in 0i32..<modules.len.int32:
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
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)
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
let modulename = n.getModuleName
let fullPath = findModule(modulename, n.info.toFullPath)

View File

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

View File

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

View File

@@ -28,7 +28,7 @@ proc overwriteFiles*() =
let doStrip = options.getConfigVar("pretty.strip").normalize == "on"
for i in 0 .. high(gSourceFiles):
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
else: gSourceFiles[i].fullpath.changeFileExt(".pretty.nim")
try:
@@ -95,7 +95,7 @@ proc beautifyName(s: string, k: TSymKind): string =
proc replaceInFile(info: TLineInfo; newName: string) =
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)
if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first)
@@ -107,8 +107,8 @@ proc replaceInFile(info: TLineInfo; newName: string) =
if differ(line, first, last, newName):
# last-first+1 != newName.len or
var x = line.substr(0, first-1) & newName & line.substr(last+1)
system.shallowCopy(gSourceFiles[info.fileIndex].lines[info.line-1], x)
gSourceFiles[info.fileIndex].dirty = true
system.shallowCopy(gSourceFiles[info.fileIndex.int].lines[info.line.int-1], x)
gSourceFiles[info.fileIndex.int].dirty = true
proc checkStyle(info: TLineInfo, s: string, k: TSymKind; sym: PSym) =
let beau = beautifyName(s, k)
@@ -136,7 +136,7 @@ template styleCheckDef*(s: PSym) =
styleCheckDef(s.info, s, s.kind)
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
# for consistency

View File

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

View File

@@ -235,7 +235,8 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
result = arLValue
else:
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
of nkBracketExpr:
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)
p.hasProgress = true
proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream,
proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
cache: IdentCache;
strongSpaces=false) =
## 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:
var
gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PSym {.nimcall.}
gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: int32; cache: IdentCache): PNode {.nimcall.}
gImportModule*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PSym {.nimcall.}
gIncludeFile*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex; cache: IdentCache): PNode {.nimcall.}
# implementation
@@ -63,20 +63,6 @@ proc skipCodegen*(n: PNode): bool {.inline.} =
# error count instead.
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
maxPasses = 10
@@ -153,7 +139,7 @@ proc closePassesCached(graph: ModuleGraph; a: var TPassContextArray) =
m = gPasses[i].close(graph, a[i], m)
a[i] = nil # free the memory here
proc resolveMod(module, relativeTo: string): int32 =
proc resolveMod(module, relativeTo: string): FileIndex =
let fullPath = findModule(module, relativeTo)
if fullPath.len == 0:
result = InvalidFileIDX
@@ -166,7 +152,7 @@ proc processImplicits(implicits: seq[string], nodeKind: TNodeKind,
let relativeTo = m.info.toFullPath
for module in items(implicits):
# 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 str = newStrNode(nkStrLit, module)
str.info = gCmdLineInfo
@@ -180,7 +166,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
p: TParsers
a: TPassContextArray
s: PLLStream
fileIdx = module.fileIdx
fileIdx = FileIndex module.fileIdx
if module.id < 0:
# new module caching mechanism:
for i in 0..<gPassesLen:

View File

@@ -19,7 +19,7 @@ proc getTok(p: var TParser) =
## `tok` member.
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) =
## 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:
# XXX this produces weird paths which are not properly resolved:
n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
n.info.line = int16(y.intVal)
n.info.line = uint16(y.intVal)
else:
localError(n.info, errXExpected, "tuple")
else:

View File

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

View File

@@ -9,124 +9,18 @@
## This module implements the canonalization for the various caching mechanisms.
import ast, idgen
import ast, idgen, msgs
when not defined(nimSymbolfiles):
template setupModuleCache* = discard
template storeNode*(module: PSym; n: PNode) = discard
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
else:
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
options: TOptions
reason: TReasonForRecompile
modDeps: seq[int32]
files: seq[int32]
modDeps: seq[FileIndex]
files: seq[FileIndex]
dataIdx: int # offset of start of data section
convertersIdx: int # offset of start of converters section
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))
if r.s[r.pos] == ',':
inc(r.pos)
if r.s[r.pos] == ',': info.line = -1'i16
else: info.line = int16(decodeVInt(r.s, r.pos))
if r.s[r.pos] == ',': info.line = 0'u16
else: info.line = uint16(decodeVInt(r.s, r.pos))
if r.s[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) =
assert r.s[r.pos] == '('
@@ -861,29 +861,29 @@ proc loadMethods(r: PRodReader) =
r.methods.add(rrGetSym(r, d, unknownLineInfo()))
if r.s[r.pos] == ' ': inc(r.pos)
proc getHash*(fileIdx: int32): SecureHash =
if fileIdx <% gMods.len and gMods[fileIdx].hashDone:
return gMods[fileIdx].hash
proc getHash*(fileIdx: FileIndex): SecureHash =
if fileIdx.int32 <% gMods.len and gMods[fileIdx.int32].hashDone:
return gMods[fileIdx.int32].hash
result = secureHashFile(fileIdx.toFullPath)
if fileIdx >= gMods.len: setLen(gMods, fileIdx+1)
gMods[fileIdx].hash = result
if fileIdx.int32 >= gMods.len: setLen(gMods, fileIdx.int32+1)
gMods[fileIdx.int32].hash = result
template growCache*(cache, pos) =
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
growCache gMods, fileIdx
if gMods[fileIdx].reason != rrEmpty:
growCache gMods, fileIdx.int32
if gMods[fileIdx.int32].reason != rrEmpty:
# reason has already been computed for this module:
return gMods[fileIdx].reason
return gMods[fileIdx.int32].reason
let filename = fileIdx.toFilename
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
var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
var r = newRodReader(rodfile, hash, fileIdx, cache)
var r = newRodReader(rodfile, hash, fileIdx.int32, cache)
if r == nil:
result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
else:
@@ -907,19 +907,18 @@ proc checkDep(fileIdx: int32; cache: IdentCache): TReasonForRecompile =
# recompilation is necessary:
if r != nil: memfiles.close(r.memfile)
r = nil
gMods[fileIdx].rd = r
gMods[fileIdx].reason = result # now we know better
gMods[fileIdx.int32].rd = r
gMods[fileIdx.int32].reason = result # now we know better
proc handleSymbolFile*(module: PSym; cache: IdentCache): PRodReader =
let fileIdx = module.fileIdx
if gSymbolFiles in {disabledSf, writeOnlySf, v2Sf}:
module.id = getID()
return nil
idgen.loadMaxIds(options.gProjectPath / options.gProjectName)
let fileIdx = FileIndex module.fileIdx
discard checkDep(fileIdx, cache)
if gMods[fileIdx].reason == rrEmpty: internalError("handleSymbolFile")
result = gMods[fileIdx].rd
if gMods[fileIdx.int32].reason == rrEmpty: internalError("handleSymbolFile")
result = gMods[fileIdx.int32].rd
if result != nil:
module.id = result.moduleID
result.syms[module.id] = module
@@ -1153,7 +1152,7 @@ proc viewFile(rodfile: string) =
if r.s[r.pos] == '\x0A':
inc(r.pos)
inc(r.line)
outf.write(w, " ", inclHash, "\n")
outf.write(w.int32, " ", inclHash, "\n")
if r.s[r.pos] == ')': inc(r.pos)
outf.write(")\n")
of "DEPS":
@@ -1163,7 +1162,7 @@ proc viewFile(rodfile: string) =
let v = int32(decodeVInt(r.s, r.pos))
r.modDeps.add(r.files[v])
if r.s[r.pos] == ' ': inc(r.pos)
outf.write(" ", r.files[v])
outf.write(" ", r.files[v].int32)
outf.write("\n")
of "INTERF", "COMPILERPROCS":
inc r.pos, 2

View File

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

View File

@@ -144,7 +144,7 @@ proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
proc filename*(c: PContext): string =
# the module's filename
return c.module.filename
return toFilename(FileIndex c.module.position)
proc scopeDepth*(c: PContext): int {.inline.} =
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:
var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f):
if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename)
else:
let code = gIncludeFile(c.graph, c.module, f, c.cache)
gatherStmts c, code, result
excl(c.includedFiles, f)
excl(c.includedFiles, f.int)
of nkStmtList:
for i in 0 ..< n.len:
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):
var f = checkModuleName(n.sons[i])
if f != InvalidFileIDX:
if containsOrIncl(c.includedFiles, f):
if containsOrIncl(c.includedFiles, f.int):
localError(n.info, errRecursiveDependencyX, f.toFilename)
else:
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) =
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,
# we map TLineInfo to a unique int here for this lookup table:
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) =
# ensure nothing gets too slow:
@@ -574,7 +574,7 @@ proc suggestEnum*(c: PContext; n: PNode; t: PType) =
if outputs.len > 0: suggestQuit()
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
inc(c.compilesContextId)
var outputs: Suggestions = @[]

View File

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

View File

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