mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-13 08:15:33 +00:00
saves/loads PNode and PSym line info
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import std / [assertions, tables]
|
||||
import "../../dist/nimony/src/lib" / [bitabs, nifreader, nifstreams, nifcursors]
|
||||
import "../../dist/nimony/src/lib" / [bitabs, nifreader, nifstreams, nifcursors, lineinfos]
|
||||
import ".." / [ast, idents, lineinfos, options, modules, modulegraphs, msgs, pathutils]
|
||||
import enum2nif, icniftags
|
||||
|
||||
@@ -59,6 +59,13 @@ when false:
|
||||
else:
|
||||
expectTag(n, id)
|
||||
|
||||
proc fromNifLineInfo(c: var DecodeContext; n: Cursor): TLineInfo =
|
||||
if n.info == NoLineInfo:
|
||||
unknownLineInfo
|
||||
else:
|
||||
let info = pool.man.unpack(n.info)
|
||||
c.graph.config.newLineInfo(pool.files[info.file].AbsoluteFile, info.line, info.col)
|
||||
|
||||
proc fromNifModuleId(c: var DecodeContext; n: var Cursor): (FileIndex, int32) =
|
||||
expect n, {ParLe, IntLit}
|
||||
if n.kind == ParLe:
|
||||
@@ -83,6 +90,7 @@ proc fromNif(c: var DecodeContext; n: var Cursor): PNode
|
||||
|
||||
proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
|
||||
expectTag n, symIdTag
|
||||
let info = c.fromNifLineInfo n
|
||||
inc n
|
||||
let (itemIdModule, nifModId) = c.fromNifModuleId(n)
|
||||
expect n, IntLit
|
||||
@@ -100,6 +108,7 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
|
||||
result = PSym(itemId: ItemId(module: itemIdModule.int32, item: itemId),
|
||||
kind: kind,
|
||||
name: ident,
|
||||
info: info,
|
||||
flags: flags,
|
||||
disamb: disamb)
|
||||
|
||||
@@ -223,9 +232,10 @@ proc fromNifType(c: var DecodeContext; n: var Cursor): PType =
|
||||
assert false, "expected type tag but got " & pool.tags[n.tagId]
|
||||
|
||||
template withNode(c: var DecodeContext; n: var Cursor; result: PNode; kind: TNodeKind; body: untyped) =
|
||||
let info = c.fromNifLineInfo(n)
|
||||
incExpect n, {DotToken, Ident}
|
||||
let flags = fromNifNodeFlags n
|
||||
result = newNode(kind)
|
||||
result = newNodeI(kind, info)
|
||||
result.flags = flags
|
||||
result.typ = c.fromNifType n
|
||||
body
|
||||
@@ -241,12 +251,12 @@ proc fromNif(c: var DecodeContext; n: var Cursor): PNode =
|
||||
let kind = n.nodeKind
|
||||
case kind:
|
||||
of nkEmpty:
|
||||
result = newNode(nkEmpty)
|
||||
result = newNodeI(nkEmpty, c.fromNifLineInfo(n))
|
||||
inc n
|
||||
skipParRi n
|
||||
of nkIdent:
|
||||
incExpect n, Ident
|
||||
result = newIdentNode(c.graph.cache.getIdent(pool.strings[n.litId]), unknownLineInfo)
|
||||
result = newIdentNode(c.graph.cache.getIdent(pool.strings[n.litId]), c.fromNifLineInfo(n))
|
||||
inc n
|
||||
skipParRi n
|
||||
of nkSym:
|
||||
|
||||
@@ -31,6 +31,13 @@ proc writeFlags[E](dest: var TokenBuf; flags: set[E]) =
|
||||
else:
|
||||
dest.addDotToken
|
||||
|
||||
proc toNif(c: var EncodeContext; info: TLineInfo): PackedLineInfo =
|
||||
if info == unknownLineInfo:
|
||||
NoLineInfo
|
||||
else:
|
||||
let fileId = pool.files.getOrIncl(c.conf.toFullPath(info.fileIndex))
|
||||
pack(pool.man, fileId, info.line.int32, info.col)
|
||||
|
||||
proc toNifModuleId(c: var EncodeContext; moduleId: int) =
|
||||
# `ItemId.module` in PType and PSym (and `PSym.position` when it is skModule) are module's FileIndex
|
||||
# but it cannot be directly encoded as the uniqueness of it can broke
|
||||
@@ -48,28 +55,29 @@ proc toNif(c: var EncodeContext; typ: PType)
|
||||
proc toNif(c: var EncodeContext; n: PNode)
|
||||
|
||||
proc toNifDef(c: var EncodeContext; sym: PSym) =
|
||||
c.dest.buildTree symIdTag:
|
||||
c.toNifModuleId sym.itemId.module
|
||||
c.dest.addIntLit sym.itemId.item
|
||||
c.dest.addIdent sym.name.s
|
||||
c.dest.writeFlags sym.flags
|
||||
c.dest.addIntLit sym.disamb
|
||||
c.dest.buildTree sym.kind.toNifTag:
|
||||
case sym.kind
|
||||
of skLet, skVar, skField, skForVar:
|
||||
c.toNif sym.guard
|
||||
c.dest.addIntLit sym.bitsize
|
||||
c.dest.addIntLit sym.alignment
|
||||
else:
|
||||
discard
|
||||
if sym.kind == skModule:
|
||||
c.toNifModuleId sym.position
|
||||
c.dest.addParLe symIdTag, c.toNif sym.info
|
||||
c.toNifModuleId sym.itemId.module
|
||||
c.dest.addIntLit sym.itemId.item
|
||||
c.dest.addIdent sym.name.s
|
||||
c.dest.writeFlags sym.flags
|
||||
c.dest.addIntLit sym.disamb
|
||||
c.dest.buildTree sym.kind.toNifTag:
|
||||
case sym.kind
|
||||
of skLet, skVar, skField, skForVar:
|
||||
c.toNif sym.guard
|
||||
c.dest.addIntLit sym.bitsize
|
||||
c.dest.addIntLit sym.alignment
|
||||
else:
|
||||
c.dest.addIntLit sym.position
|
||||
c.toNif sym.typ
|
||||
c.toNif sym.owner
|
||||
c.dest.addIdent toNifTag(sym.loc.k)
|
||||
c.dest.addStrLit sym.loc.snippet
|
||||
discard
|
||||
if sym.kind == skModule:
|
||||
c.toNifModuleId sym.position
|
||||
else:
|
||||
c.dest.addIntLit sym.position
|
||||
c.toNif sym.typ
|
||||
c.toNif sym.owner
|
||||
c.dest.addIdent toNifTag(sym.loc.k)
|
||||
c.dest.addStrLit sym.loc.snippet
|
||||
c.dest.addParRi
|
||||
|
||||
proc toNifDef(c: var EncodeContext; typ: PType) =
|
||||
c.dest.buildTree typeIdTag:
|
||||
@@ -115,7 +123,7 @@ proc writeNodeFlags(dest: var TokenBuf; flags: set[TNodeFlag]) {.inline.} =
|
||||
writeFlags dest, flags
|
||||
|
||||
template withNode(c: var EncodeContext; n: PNode; body: untyped) =
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(n.kind))
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(n.kind)), c.toNif n.info
|
||||
writeNodeFlags(c.dest, n.flags)
|
||||
c.toNif n.typ
|
||||
body
|
||||
@@ -127,10 +135,12 @@ proc toNif(c: var EncodeContext; n: PNode) =
|
||||
else:
|
||||
case n.kind:
|
||||
of nkEmpty:
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(nkEmpty))
|
||||
let info = c.toNif n.info
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(nkEmpty)), info
|
||||
c.dest.addParRi
|
||||
of nkIdent:
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(nkIdent))
|
||||
let info = c.toNif n.info
|
||||
c.dest.addParLe pool.tags.getOrIncl(toNifTag(nkIdent)), info
|
||||
c.dest.addIdent n.ident.s
|
||||
c.dest.addParRi
|
||||
of nkSym:
|
||||
|
||||
@@ -90,6 +90,26 @@ proc eqlFileIndex(x, y: int; c: EqlContext): bool =
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eql(x, y: TLineInfo; c: EqlContext): bool =
|
||||
# If parent PNode has a valid line info but it's child doesn't have one,
|
||||
# cannot translate such a tree to NIF.
|
||||
# Because in NIF, if a child node doesn't have line info,
|
||||
# nifstream assign the parent's line info to it.
|
||||
# So cannot have child node without line info if parent has a valid line info.
|
||||
if x == unknownLineInfo:
|
||||
result = true
|
||||
elif x.line != y.line:
|
||||
echo "line number mismatch: ", x.line, "/", y.line
|
||||
result = false
|
||||
elif x.col != y.col:
|
||||
echo "column number mismatch: ", x.col, "/", y.col
|
||||
result = false
|
||||
elif not eqlFileIndex(x.fileIndex.int, y.fileIndex.int, c):
|
||||
echo "file in line info mismatch"
|
||||
result = false
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eqlSymPos(x, y: PSym; c: EqlContext): bool =
|
||||
if x.kind == skModule:
|
||||
result = eqlFileIndex(x.position, y.position, c)
|
||||
@@ -123,6 +143,9 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
|
||||
elif x.kind != y.kind:
|
||||
echo "symbol kind mismatch: ", x.kind, "/", y.kind
|
||||
result = false
|
||||
elif not eql(x.info, y.info, c):
|
||||
echo "symbol line info mismatch"
|
||||
result = false
|
||||
elif x.flags != y.flags:
|
||||
echo "symbol flag mismatch: ", x.flags, "/", y.flags
|
||||
result = false
|
||||
@@ -229,6 +252,10 @@ proc eql(x, y: PNode; c: var EqlContext): bool =
|
||||
debug(x)
|
||||
debug(y)
|
||||
result = false
|
||||
elif not eql(x.info, y. info, c):
|
||||
echo "node lineinfo mismatch at ", `$`(c.confX, x.info)
|
||||
debug(x)
|
||||
result = false
|
||||
elif x.safeLen == y.safeLen:
|
||||
if c.nodeStack.len != 0:
|
||||
for i in countDown(c.nodeStack.len - 1, 0):
|
||||
|
||||
Reference in New Issue
Block a user