Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement setLineInfo #21153

Merged
merged 2 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/msgs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile): FileIndex =
var dummy: bool
result = fileInfoIdx(conf, filename, dummy)

proc fileInfoIdx*(conf: ConfigRef; filename: RelativeFile; isKnownFile: var bool): FileIndex =
fileInfoIdx(conf, AbsoluteFile expandFilename(filename.string), isKnownFile)

proc fileInfoIdx*(conf: ConfigRef; filename: RelativeFile): FileIndex =
var dummy: bool
fileInfoIdx(conf, AbsoluteFile expandFilename(filename.string), dummy)

proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
result.fileIndex = fileInfoIdx
if line < int high(uint16):
Expand Down
14 changes: 12 additions & 2 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1934,14 +1934,24 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
of 1: # getLine
regs[ra].node = newIntNode(nkIntLit, n.info.line.int)
of 2: # getColumn
regs[ra].node = newIntNode(nkIntLit, n.info.col)
regs[ra].node = newIntNode(nkIntLit, n.info.col.int)
else:
internalAssert c.config, false
regs[ra].node.info = n.info
regs[ra].node.typ = n.typ
of opcNSetLineInfo:
of opcNCopyLineInfo:
decodeB(rkNode)
regs[ra].node.info = regs[rb].node.info
of opcNSetLineInfoLine:
decodeB(rkNode)
regs[ra].node.info.line = regs[rb].intVal.uint16
of opcNSetLineInfoColumn:
decodeB(rkNode)
regs[ra].node.info.col = regs[rb].intVal.int16
of opcNSetLineInfoFile:
decodeB(rkNode)
regs[ra].node.info.fileIndex =
fileInfoIdx(c.config, RelativeFile regs[rb].node.strVal)
of opcEqIdent:
decodeBC(rkInt)
# aliases for shorter and easier to understand code below
Expand Down
3 changes: 2 additions & 1 deletion compiler/vmdef.nim
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ type
opcNError,
opcNWarning,
opcNHint,
opcNGetLineInfo, opcNSetLineInfo,
opcNGetLineInfo, opcNCopyLineInfo, opcNSetLineInfoLine,
opcNSetLineInfoColumn, opcNSetLineInfoFile
opcEqIdent,
opcStrToIdent,
opcGetImpl,
Expand Down
14 changes: 13 additions & 1 deletion compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,19 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
of "copyLineInfo":
internalAssert c.config, n.len == 3
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetLineInfo)
genBinaryStmt(c, n, opcNCopyLineInfo)
of "setLine":
internalAssert c.config, n.len == 3
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetLineInfoLine)
of "setColumn":
internalAssert c.config, n.len == 3
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetLineInfoColumn)
of "setFile":
internalAssert c.config, n.len == 3
unused(c, n, dest)
genBinaryStmt(c, n, opcNSetLineInfoFile)
else: internalAssert c.config, false
of mNHint:
unused(c, n, dest)
Expand Down
16 changes: 16 additions & 0 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,22 @@ proc getFile(arg: NimNode): string {.magic: "NLineInfo", noSideEffect.}
proc copyLineInfo*(arg: NimNode, info: NimNode) {.magic: "NLineInfo", noSideEffect.}
## Copy lineinfo from `info`.

proc setLine(arg: NimNode, line: uint16) {.magic: "NLineInfo", noSideEffect.}
proc setColumn(arg: NimNode, column: int16) {.magic: "NLineInfo", noSideEffect.}
proc setFile(arg: NimNode, file: string) {.magic: "NLineInfo", noSideEffect.}

proc setLineInfo*(arg: NimNode, file: string, line: int, column: int) =
## Sets the line info on the NimNode. The file needs to exists, but can be a
## relative path. If you want to attach line info to a block using `quote`
## you'll need to add the line information after the quote block.
arg.setFile(file)
arg.setLine(line.uint16)
arg.setColumn(column.int16)

proc setLineInfo*(arg: NimNode, lineInfo: LineInfo) =
## See `setLineInfo proc<#setLineInfo,NimNode,string,int,int>`_
setLineInfo(arg, lineInfo.filename, lineInfo.line, lineInfo.column)

proc lineInfoObj*(n: NimNode): LineInfo =
## Returns `LineInfo` of `n`, using absolute path for `filename`.
result = LineInfo(filename: n.getFile, line: n.getLine, column: n.getColumn)
Expand Down
23 changes: 22 additions & 1 deletion tests/macros/tmacros_various.nim
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ block tlexerex:



block tlineinfo:
block tcopylineinfo:
# issue #5617, feature request
type Test = object

Expand All @@ -103,6 +103,27 @@ block tlineinfo:
var z = mixer(Test)
doAssert z

block tsetgetlineinfo:
# issue #21098, feature request
type Test = object

macro mixer1(n: typed): untyped =
let x = newIdentNode("echo")
var lineInfo = n.lineInfoObj
x.setLineInfo lineInfo
result = newLit(x.lineInfo == n.lineInfo)

macro mixer2(n: typed): untyped =
let x = newIdentNode("echo")
var lineInfo = n.lineInfoObj
lineInfo.line += 1
x.setLineInfo lineInfo
result = newLit(x.lineInfo != n.lineInfo)

doAssert mixer1(Test)

doAssert mixer2(Test)



block tdebugstmt:
Expand Down