refactoring: make FileIndex a distinct type; make line information an uint16; fixes #7654
This commit is contained in:
parent
6667362c2f
commit
33b69f0ed0
29 changed files with 196 additions and 311 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue