mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-08 00:00:55 +00:00
encodes/decodes itemId.module
This commit is contained in:
@@ -6,3 +6,5 @@ let
|
||||
typeIdTag* = registerTag("typeId")
|
||||
typeTag* = registerTag("t")
|
||||
sonsTag* = registerTag("sons")
|
||||
|
||||
modIdTag* = registerTag("modId")
|
||||
|
||||
@@ -8,6 +8,7 @@ type
|
||||
graph: ModuleGraph
|
||||
symbols: Table[int, PSym]
|
||||
types: Table[int, PType]
|
||||
modules: Table[int, FileIndex] # maps module id in NIF to FileIndex of the module
|
||||
|
||||
proc nodeKind(n: Cursor): TNodeKind {.inline.} =
|
||||
assert n.kind == ParLe
|
||||
@@ -58,6 +59,23 @@ when false:
|
||||
else:
|
||||
expectTag(n, id)
|
||||
|
||||
proc fromNifModuleId(c: var DecodeContext; n: var Cursor): FileIndex =
|
||||
if n.kind == ParLe:
|
||||
expectTag n, modIdTag
|
||||
incExpect n, IntLit
|
||||
let id = pool.integers[n.intId]
|
||||
incExpect n, StringLit
|
||||
let path = pool.strings[n.litId].AbsoluteFile
|
||||
result = fileInfoIdx(c.graph.config, path)
|
||||
assert id notin c.modules
|
||||
c.modules[id] = result
|
||||
inc n
|
||||
skipParRi n
|
||||
elif n.kind == IntLit:
|
||||
let id = pool.integers[n.intId]
|
||||
result = c.modules[id]
|
||||
inc n
|
||||
|
||||
proc fromNifSymbol(c: var DecodeContext; n: var Cursor): PSym
|
||||
proc fromNifType(c: var DecodeContext; n: var Cursor): PType
|
||||
proc fromNif(c: var DecodeContext; n: var Cursor): PNode
|
||||
@@ -68,7 +86,9 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
|
||||
let id = pool.integers[n.intId]
|
||||
incExpect n, Ident
|
||||
let ident = c.graph.cache.getIdent(pool.strings[n.litId])
|
||||
incExpect n, IntLit
|
||||
inc n
|
||||
let itemIdModule = c.fromNifModuleId(n).int32
|
||||
expect n, IntLit
|
||||
let itemId = pool.integers[n.intId].int32
|
||||
incExpect n, ParLe
|
||||
let kind = parseSymKind(pool.tags[n.tagId])
|
||||
@@ -79,17 +99,17 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
|
||||
let flags = if n.kind == Ident: pool.strings[n.litId].parseSymFlags else: {}
|
||||
inc n
|
||||
var position = if kind == skModule:
|
||||
expect n, StringLit
|
||||
let path = pool.strings[n.litId].AbsoluteFile
|
||||
fileInfoIdx(c.graph.config, path).int
|
||||
c.fromNifModuleId(n).int
|
||||
else:
|
||||
expect n, IntLit
|
||||
pool.integers[n.intId]
|
||||
incExpect n, IntLit
|
||||
let p = pool.integers[n.intId]
|
||||
inc n
|
||||
p
|
||||
expect n, IntLit
|
||||
let disamb = pool.integers[n.intId].int32
|
||||
inc n
|
||||
|
||||
result = PSym(itemId: ItemId(module: 0, item: itemId),
|
||||
result = PSym(itemId: ItemId(module: itemIdModule, item: itemId),
|
||||
kind: kind,
|
||||
name: ident,
|
||||
flags: flags,
|
||||
@@ -116,7 +136,9 @@ proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
|
||||
expectTag n, typeIdTag
|
||||
incExpect n, IntLit
|
||||
let id = pool.integers[n.intId]
|
||||
incExpect n, IntLit
|
||||
inc n
|
||||
let itemIdModule = c.fromNifModuleId(n).int32
|
||||
expect n, IntLit
|
||||
let itemId = pool.integers[n.intId].int32
|
||||
incExpect n, Ident
|
||||
let kind = parseTypeKind(pool.strings[n.litId])
|
||||
@@ -124,7 +146,7 @@ proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
|
||||
let flags = if n.kind == Ident: pool.strings[n.litId].parseTypeFlags else: {}
|
||||
inc n
|
||||
|
||||
result = PType(itemId: ItemId(module: 0, item: itemId),
|
||||
result = PType(itemId: ItemId(module: itemIdModule, item: itemId),
|
||||
kind: kind,
|
||||
flags: flags)
|
||||
assert id notin c.types
|
||||
|
||||
@@ -8,6 +8,7 @@ type
|
||||
conf: ConfigRef
|
||||
decodedSyms: HashSet[PSym]
|
||||
decodedTypes: HashSet[PType]
|
||||
decodedFileIndices: HashSet[FileIndex]
|
||||
dest: TokenBuf
|
||||
|
||||
proc initEncodeContext(conf: ConfigRef): EncodeContext =
|
||||
@@ -30,6 +31,18 @@ proc writeFlags[E](dest: var TokenBuf; flags: set[E]) =
|
||||
else:
|
||||
dest.addDotToken
|
||||
|
||||
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
|
||||
# if any import/include statements are changed.
|
||||
if not c.decodedFileIndices.containsOrIncl(moduleId.FileIndex):
|
||||
c.dest.buildTree modIdTag:
|
||||
c.dest.addIntLit moduleId
|
||||
let path = toFullPath(c.conf, moduleId.FileIndex)
|
||||
c.dest.addStrLit path
|
||||
else:
|
||||
c.dest.addIntLit moduleId
|
||||
|
||||
proc toNif(c: var EncodeContext; sym: PSym)
|
||||
proc toNif(c: var EncodeContext; typ: PType)
|
||||
proc toNif(c: var EncodeContext; n: PNode)
|
||||
@@ -38,17 +51,14 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
|
||||
c.dest.buildTree symIdTag:
|
||||
c.dest.addIntLit sym.id
|
||||
c.dest.addIdent sym.name.s
|
||||
c.toNifModuleId sym.itemId.module
|
||||
c.dest.addIntLit sym.itemId.item
|
||||
c.dest.buildTree sym.kind.toNifTag:
|
||||
# TODO: add kind specific data
|
||||
discard
|
||||
c.dest.writeFlags sym.flags
|
||||
if sym.kind == skModule:
|
||||
# position is module's FileIndex but it cannot be directly encoded
|
||||
# as the uniqueness of it can broke
|
||||
# if any import/include statements are changed.
|
||||
let path = toFullPath(c.conf, sym.position.FileIndex)
|
||||
c.dest.addStrLit path
|
||||
c.toNifModuleId sym.position
|
||||
else:
|
||||
c.dest.addIntLit sym.position
|
||||
c.dest.addIntLit sym.disamb
|
||||
@@ -60,6 +70,7 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
|
||||
proc toNifDef(c: var EncodeContext; typ: PType) =
|
||||
c.dest.buildTree typeIdTag:
|
||||
c.dest.addIntLit typ.id
|
||||
c.toNifModuleId typ.itemId.module
|
||||
c.dest.addIntLit typ.itemId.item
|
||||
c.dest.addIdent toNifTag(typ.kind)
|
||||
c.dest.writeFlags typ.flags
|
||||
@@ -75,8 +86,6 @@ proc toNifDef(c: var EncodeContext; typ: PType) =
|
||||
c.toNif typ.owner
|
||||
c.toNif typ.sym
|
||||
|
||||
#include nifencodertypes
|
||||
|
||||
proc toNif(c: var EncodeContext; sym: PSym) =
|
||||
if sym == nil:
|
||||
c.dest.addDotToken()
|
||||
|
||||
@@ -81,21 +81,33 @@ proc eql(x, y: TLoc): bool =
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eqlFileIndex(x, y: int; c: EqlContext): bool =
|
||||
let xpath = c.confX.toFullPath(x.FileIndex)
|
||||
let ypath = c.confY.toFullPath(y.FileIndex)
|
||||
if xpath != ypath:
|
||||
echo "file index mismatch: ", xpath, "/", ypath
|
||||
result = false
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eqlSymPos(x, y: PSym; c: EqlContext): bool =
|
||||
if x.kind == skModule:
|
||||
let xpath = c.confX.toFullPath(x.position.FileIndex)
|
||||
let ypath = c.confY.toFullPath(y.position.FileIndex)
|
||||
if xpath != ypath:
|
||||
echo "symbol position mismatch: ", xpath, "/", ypath
|
||||
result = false
|
||||
else:
|
||||
result = true
|
||||
result = eqlFileIndex(x.position, y.position, c)
|
||||
elif x.position != y.position:
|
||||
echo "symbol position mismatch: ", x.position, "/", y.position
|
||||
result = false
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eqlItemId(x, y: ItemId; c: EqlContext): bool =
|
||||
if x.item != y.item:
|
||||
echo "itemId.item mismatch: ", x.item, "/", y.item
|
||||
result = false
|
||||
elif not eqlFileIndex(x.module, y.module, c):
|
||||
result = false
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc eql(x, y: PSym; c: var EqlContext): bool =
|
||||
if x == nil and y == nil:
|
||||
result = true
|
||||
@@ -105,8 +117,8 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
|
||||
elif x.name.s != y.name.s:
|
||||
echo "symbol name mismatch: ", x.name.s, "/", y.name.s
|
||||
result = false
|
||||
elif x.itemId.item != y.itemId.item:
|
||||
echo "symbol itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
|
||||
elif not eqlItemId(x.itemId, y.itemId, c):
|
||||
echo "symbol itemId mismatch"
|
||||
result = false
|
||||
elif x.kind != y.kind:
|
||||
echo "symbol kind mismatch: ", x.kind, "/", y.kind
|
||||
@@ -146,8 +158,8 @@ proc eql(x, y: PType; c: var EqlContext): bool =
|
||||
elif x == nil or y == nil:
|
||||
echo "type is missing"
|
||||
result = false
|
||||
elif x.itemId.item != y.itemId.item:
|
||||
echo "type itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
|
||||
elif not eqlItemId(x.itemId, y.itemId, c):
|
||||
echo "type itemId mismatch"
|
||||
result = false
|
||||
elif x.kind != y.kind:
|
||||
echo "type kind mismatch: ", x.kind, "/", y.kind
|
||||
|
||||
Reference in New Issue
Block a user