diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-05-30 10:15:41 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-05-30 10:15:41 +0200 |
commit | ddc6cec69e66f4cc28275f61b73962042e257575 (patch) | |
tree | 6b7752efde22f3a1bac23b083eb5e8e27f9a8a35 | |
parent | 688c54d8f158ff977161a234374b1cd321ba95f3 (diff) | |
download | Nim-ddc6cec69e66f4cc28275f61b73962042e257575.tar.gz |
refactoring: move DB model to incremental.nim
-rw-r--r-- | compiler/btrees.nim | 186 | ||||
-rw-r--r-- | compiler/incremental.nim | 188 | ||||
-rw-r--r-- | compiler/main.nim | 2 | ||||
-rw-r--r-- | compiler/modulegraphs.nim | 11 | ||||
-rw-r--r-- | compiler/modules.nim | 6 | ||||
-rw-r--r-- | compiler/passes.nim | 2 | ||||
-rw-r--r-- | compiler/rod.nim | 19 | ||||
-rw-r--r-- | compiler/rodimpl.nim | 149 | ||||
-rw-r--r-- | compiler/rodwrite.nim | 6 | ||||
-rw-r--r-- | compiler/sem.nim | 4 |
10 files changed, 410 insertions, 163 deletions
diff --git a/compiler/btrees.nim b/compiler/btrees.nim new file mode 100644 index 000000000..228481692 --- /dev/null +++ b/compiler/btrees.nim @@ -0,0 +1,186 @@ +# +# +# The Nim Compiler +# (c) Copyright 2018 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## BTree implementation with few features, but good enough for the +## Nim compiler's needs. + +const + M = 512 # max children per B-tree node = M-1 + # (must be even and greater than 2) + Mhalf = M div 2 + +type + Node[Key, Val] = ref object + entries: int + keys: array[M, Key] + case isInternal: bool + of false: + vals: array[M, Val] + of true: + links: array[M, Node[Key, Val]] + BTree*[Key, Val] = object + root: Node[Key, Val] + height: int + entries: int ## number of key-value pairs + +proc initBTree*[Key, Val](): BTree[Key, Val] = + BTree[Key, Val](root: Node[Key, Val](entries: 0, isInternal: false)) + +template less(a, b): bool = cmp(a, b) < 0 +template eq(a, b): bool = cmp(a, b) == 0 + +proc getOrDefault*[Key, Val](b: BTree[Key, Val], key: Key): Val = + var x = b.root + while x.isInternal: + for j in 0 ..< x.entries: + if j+1 == x.entries or less(key, x.keys[j+1]): + x = x.links[j] + break + assert(not x.isInternal) + for j in 0 ..< x.entries: + if eq(key, x.keys[j]): return x.vals[j] + +proc copyHalf[Key, Val](h, result: Node[Key, Val]) = + for j in 0 ..< Mhalf: + result.keys[j] = h.keys[Mhalf + j] + if h.isInternal: + for j in 0 ..< Mhalf: + result.links[j] = h.links[Mhalf + j] + else: + for j in 0 ..< Mhalf: + shallowCopy(result.vals[j], h.vals[Mhalf + j]) + +proc split[Key, Val](h: Node[Key, Val]): Node[Key, Val] = + ## split node in half + result = Node[Key, Val](entries: Mhalf, isInternal: h.isInternal) + h.entries = Mhalf + copyHalf(h, result) + +proc insert[Key, Val](h: Node[Key, Val], key: Key, val: Val): Node[Key, Val] = + #var t = Entry(key: key, val: val, next: nil) + var newKey = key + var j = 0 + if not h.isInternal: + while j < h.entries: + if less(key, h.keys[j]): break + inc j + for i in countdown(h.entries, j+1): + shallowCopy(h.vals[i], h.vals[i-1]) + h.vals[j] = val + else: + var newLink: Node[Key, Val] = nil + while j < h.entries: + if j+1 == h.entries or less(key, h.keys[j+1]): + let u = insert(h.links[j], key, val) + inc j + if u == nil: return nil + newKey = u.keys[0] + newLink = u + break + inc j + for i in countdown(h.entries, j+1): + h.links[i] = h.links[i-1] + h.links[j] = newLink + + for i in countdown(h.entries, j+1): + h.keys[i] = h.keys[i-1] + h.keys[j] = newKey + inc h.entries + return if h.entries < M: nil else: split(h) + +proc add*[Key, Val](b: var BTree[Key, Val]; key: Key; val: Val) = + let u = insert(b.root, key, val) + inc b.entries + if u == nil: return + + # need to split root + let t = Node[Key, Val](entries: 2, isInternal: true) + t.keys[0] = b.root.keys[0] + t.links[0] = b.root + t.keys[1] = u.keys[0] + t.links[1] = u + b.root = t + inc b.height + +proc toString[Key, Val](h: Node[Key, Val], indent: string; result: var string) = + if not h.isInternal: + for j in 0..<h.entries: + result.add(indent) + result.add($h.keys[j] & " " & $h.vals[j] & "\n") + else: + for j in 0..<h.entries: + if j > 0: result.add(indent & "(" & $h.keys[j] & ")\n") + toString(h.links[j], indent & " ", result) + +proc `$`[Key, Val](b: BTree[Key, Val]): string = + result = "" + toString(b.root, "", result) + +when isMainModule: + + import random, tables + + proc main = + var st = initBTree[string, string]() + st.add("www.cs.princeton.edu", "abc") + st.add("www.princeton.edu", "128.112.128.15") + st.add("www.yale.edu", "130.132.143.21") + st.add("www.simpsons.com", "209.052.165.60") + st.add("www.apple.com", "17.112.152.32") + st.add("www.amazon.com", "207.171.182.16") + st.add("www.ebay.com", "66.135.192.87") + st.add("www.cnn.com", "64.236.16.20") + st.add("www.google.com", "216.239.41.99") + st.add("www.nytimes.com", "199.239.136.200") + st.add("www.microsoft.com", "207.126.99.140") + st.add("www.dell.com", "143.166.224.230") + st.add("www.slashdot.org", "66.35.250.151") + st.add("www.espn.com", "199.181.135.201") + st.add("www.weather.com", "63.111.66.11") + st.add("www.yahoo.com", "216.109.118.65") + + assert st.getOrDefault("www.cs.princeton.edu") == "abc" + assert st.getOrDefault("www.harvardsucks.com") == nil + + assert st.getOrDefault("www.simpsons.com") == "209.052.165.60" + assert st.getOrDefault("www.apple.com") == "17.112.152.32" + assert st.getOrDefault("www.ebay.com") == "66.135.192.87" + assert st.getOrDefault("www.dell.com") == "143.166.224.230" + assert(st.entries == 16) + + when false: + var b2 = initBTree[string, string]() + const iters = 10_000 + for i in 1..iters: + b2.add($i, $(iters - i)) + for i in 1..iters: + let x = b2.getOrDefault($i) + if x != $(iters - i): + echo "got ", x, ", but expected ", iters - i + echo b2.entries + echo b2.height + + when true: + var b2 = initBTree[int, string]() + var t2 = initTable[int, string]() + const iters = 100_000 + for i in 1..iters: + let x = rand(high(int)) + if not t2.hasKey(x): + doAssert b2.getOrDefault(x).len == 0, " what, tree has this element " & $x + t2[x] = $x + b2.add(x, $x) + + doAssert b2.entries == t2.len + echo "unique entries ", b2.entries + for k, v in t2: + doAssert $k == v + doAssert b2.getOrDefault(k) == $k + + main() diff --git a/compiler/incremental.nim b/compiler/incremental.nim new file mode 100644 index 000000000..69dfb727e --- /dev/null +++ b/compiler/incremental.nim @@ -0,0 +1,188 @@ +# +# +# The Nim Compiler +# (c) Copyright 2018 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Basic type definitions the module graph needs in order to support +## incremental compilations. + +const nimIncremental* = defined(nimIncremental) + +import options, lineinfos + +when nimIncremental: + import ast, intsets, btrees, db_sqlite + + type + Writer* = object + sstack*: seq[PSym] # a stack of symbols to process + tstack*: seq[PType] # a stack of types to process + tmarks*, smarks*: IntSet + forwardedSyms*: seq[PSym] + + Reader* = object + syms*: BTree[int, PSym] + types*: BTree[int, PType] + + IncrementalCtx* = object + db*: DbConn + w*: Writer + r*: Reader + + proc init*(incr: var IncrementalCtx) = + incr.w.sstack = @[] + incr.w.tstack = @[] + incr.w.tmarks = initIntSet() + incr.w.smarks = initIntSet() + incr.w.forwardedSyms = @[] + incr.r.syms = initBTree[int, PSym]() + incr.r.types = initBTree[int, PType]() + + + proc hashFileCached*(conf: ConfigRef; fileIdx: FileIndex; fullpath: string): string = + result = msgs.getHash(fileIdx) + if result.len == 0: + result = $secureHashFile(fullpath) + msgs.setHash(fileIdx, result) + + + proc toDbFileId*(fileIdx: int32): int = + if fileIdx == -1: return -1 + let fullpath = fileIdx.toFullPath + let row = db.getRow(sql"select id, fullhash from filenames where fullpath = ?", + fullpath) + let id = row[0] + let fullhash = hashFileCached(fileIdx, fullpath) + if id.len == 0: + result = int db.insertID(sql"insert into filenames(fullpath, fullhash) values (?, ?)", + fullpath, fullhash) + else: + if row[1] != fullhash: + db.exec(sql"update filenames set fullhash = ? where fullpath = ?", fullhash, fullpath) + result = parseInt(id) + + proc fromDbFileId*(incr: var IncrementalCtx; conf: ConfigRef; dbId: int): FileIndex = + if dbId == -1: return -1 + let fullpath = db.getValue(sql"select fullpath from filenames where id = ?", dbId) + doAssert fullpath.len > 0, "cannot find file name for DB ID " & $dbId + result = fileInfoIdx(conf, fullpath) + + + proc addModuleDep*(incr: var IncrementalCtx; conf: ConfigRef; + module, fileIdx: FileIndex; + isIncludeFile: bool) = + if conf.symbolFiles != v2Sf: return + + let a = toDbFileId(incr, conf, module) + let b = toDbFileId(incr, conf, fileIdx) + + incr.db.exec(sql"insert into deps(module, dependency, isIncludeFile) values (?, ?, ?)", + a, b, ord(isIncludeFile)) + + # --------------- Database model --------------------------------------------- + + proc createDb*(db: DbConn) = + db.exec(sql""" + create table if not exists controlblock( + idgen integer not null + ); + """) + + db.exec(sql""" + create table if not exists filenames( + id integer primary key, + fullpath varchar(8000) not null, + fullHash varchar(256) not null + ); + """) + db.exec sql"create index if not exists FilenameIx on filenames(fullpath);" + + db.exec(sql""" + create table if not exists modules( + id integer primary key, + fullpath varchar(8000) not null, + interfHash varchar(256) not null, + fullHash varchar(256) not null, + + created timestamp not null default (DATETIME('now')) + );""") + db.exec(sql"""create unique index if not exists SymNameIx on modules(fullpath);""") + + db.exec(sql""" + create table if not exists deps( + id integer primary key, + module integer not null, + dependency integer not null, + isIncludeFile integer not null, + foreign key (module) references filenames(id), + foreign key (dependency) references filenames(id) + );""") + db.exec(sql"""create index if not exists DepsIx on deps(module);""") + + db.exec(sql""" + create table if not exists types( + id integer primary key, + nimid integer not null, + module integer not null, + data blob not null, + foreign key (module) references module(id) + ); + """) + db.exec sql"create index TypeByModuleIdx on types(module);" + db.exec sql"create index TypeByNimIdIdx on types(nimid);" + + db.exec(sql""" + create table if not exists syms( + id integer primary key, + nimid integer not null, + module integer not null, + name varchar(256) not null, + data blob not null, + exported int not null, + foreign key (module) references module(id) + ); + """) + db.exec sql"create index if not exists SymNameIx on syms(name);" + db.exec sql"create index SymByNameAndModuleIdx on syms(name, module);" + db.exec sql"create index SymByModuleIdx on syms(module);" + db.exec sql"create index SymByNimIdIdx on syms(nimid);" + + + db.exec(sql""" + create table if not exists toplevelstmts( + id integer primary key, + position integer not null, + module integer not null, + data blob not null, + foreign key (module) references module(id) + ); + """) + db.exec sql"create index TopLevelStmtByModuleIdx on toplevelstmts(module);" + db.exec sql"create index TopLevelStmtByPositionIdx on toplevelstmts(position);" + + db.exec(sql""" + create table if not exists statics( + id integer primary key, + module integer not null, + data blob not null, + foreign key (module) references module(id) + ); + """) + db.exec sql"create index StaticsByModuleIdx on toplevelstmts(module);" + db.exec sql"insert into controlblock(idgen) values (0)" + + +else: + type + IncrementalCtx* = object + + template init*(incr: IncrementalCtx) = discard + + template addModuleDep*(incr: var IncrementalCtx; conf: ConfigRef; + module, fileIdx: FileIndex; + isIncludeFile: bool) = + discard diff --git a/compiler/main.nim b/compiler/main.nim index ba2537ef8..0929974bd 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -157,7 +157,7 @@ const proc mainCommand*(graph: ModuleGraph; cache: IdentCache) = let conf = graph.config - setupModuleCache() + setupModuleCache(graph) # In "nim serve" scenario, each command must reset the registered passes clearPasses(graph) conf.lastCmdTime = epochTime() diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 100f69c1d..7c9837f54 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -9,7 +9,7 @@ ## This module implements the module graph data structure. The module graph ## represents a complete Nim project. Single modules can either be kept in RAM -## or stored in a ROD file. The ROD file mechanism is not yet integrated here. +## or stored in a Sqlite database. ## ## The caching of modules is critical for 'nimsuggest' and is tricky to get ## right. If module E is being edited, we need autocompletion (and type @@ -25,7 +25,8 @@ ## - Its dependent module stays the same. ## -import ast, intsets, tables, options, rod, lineinfos, hashes, idents +import ast, intsets, tables, options, lineinfos, hashes, idents, + incremental type ModuleGraph* = ref object @@ -54,6 +55,7 @@ type intTypeCache*: array[-5..64, PType] opContains*, opNot*: PSym emptyNode*: PNode + incr*: IncrementalCtx proc hash*(x: FileIndex): Hash {.borrow.} @@ -82,6 +84,7 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph = result.opNot = createMagic(result, "not", mNot) result.opContains = createMagic(result, "contains", mInSet) result.emptyNode = newNode(nkEmpty) + init(result.incr) proc resetAllModules*(g: ModuleGraph) = initStrTable(packageSyms) @@ -103,7 +106,7 @@ proc dependsOn(a, b: int): int {.inline.} = (a shl 15) + b proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) = assert m.position == m.info.fileIndex.int32 - addModuleDep(m.info.fileIndex, dep, isIncludeFile = false) + addModuleDep(g.incr, g.config, m.info.fileIndex, dep, isIncludeFile = false) if suggestMode: deps.incl m.position.dependsOn(dep.int) # we compute the transitive closure later when quering the graph lazily. @@ -111,7 +114,7 @@ proc addDep*(g: ModuleGraph; m: PSym, dep: FileIndex) = #invalidTransitiveClosure = true proc addIncludeDep*(g: ModuleGraph; module, includeFile: FileIndex) = - addModuleDep(module, includeFile, isIncludeFile = true) + addModuleDep(g.incr, g.config, module, includeFile, isIncludeFile = true) discard hasKeyOrPut(inclToMod, includeFile, module) proc parentModule*(g: ModuleGraph; fileIdx: FileIndex): FileIndex = diff --git a/compiler/modules.nim b/compiler/modules.nim index 9ac3dbb0b..61568e67c 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -75,7 +75,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; cache: IdentCache, f return else: discard - result.id = getModuleId(fileIdx, toFullPath(graph.config, fileIdx)) + result.id = getModuleId(graph, fileIdx, toFullPath(graph.config, fileIdx)) discard processModule(graph, result, if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil, rd, cache) @@ -107,8 +107,8 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex; # localError(result.info, errAttemptToRedefine, result.name.s) # restore the notes for outer module: graph.config.notes = - if s.owner.id == graph.config.mainPackageId: graph.config.mainPackageNotes - else: graph.config.foreignPackageNotes + if s.owner.id == graph.config.mainPackageId: graph.config.mainPackageNotes + else: graph.config.foreignPackageNotes proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} = diff --git a/compiler/passes.nim b/compiler/passes.nim index 9be7d060a..4ba17adcc 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -180,7 +180,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream, var stmtIndex = 0 var doContinue = true while doContinue: - let n = loadNode(module, stmtIndex) + let n = loadNode(graph, module, stmtIndex) if n == nil or graph.stopCompile(): break #if n.kind == nkImportStmt: # echo "yes and it's ", n diff --git a/compiler/rod.nim b/compiler/rod.nim index 82f556b3b..1b5331ba7 100644 --- a/compiler/rod.nim +++ b/compiler/rod.nim @@ -9,18 +9,21 @@ ## This module implements the canonalization for the various caching mechanisms. -import ast, idgen, lineinfos, msgs +import ast, idgen, lineinfos, msgs, incremental, modulegraphs -when not defined(nimSymbolfiles): - template setupModuleCache* = discard - template storeNode*(module: PSym; n: PNode) = discard - template loadNode*(module: PSym; index: var int): PNode = PNode(nil) +when not nimIncremental: + template setupModuleCache*(g: ModuleGraph) = discard + template storeNode*(g: ModuleGraph; module: PSym; n: PNode) = discard + template loadNode*(g: ModuleGraph; module: PSym; index: var int): PNode = PNode(nil) - template getModuleId*(fileIdx: FileIndex; fullpath: string): int = getID() + template getModuleId*(g: ModuleGraph; fileIdx: FileIndex; fullpath: string): int = getID() - template addModuleDep*(module, fileIdx: FileIndex; isIncludeFile: bool) = discard + template addModuleDep*(g: ModuleGraph; module, fileIdx: FileIndex; isIncludeFile: bool) = discard - template storeRemaining*(module: PSym) = discard + template storeRemaining*(g: ModuleGraph; module: PSym) = discard else: include rodimpl + + # idea for testing all this logic: *Always* load the AST from the DB, whether + # we already have it in RAM or not! diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim index aff4f6909..1a92ac64b 100644 --- a/compiler/rodimpl.nim +++ b/compiler/rodimpl.nim @@ -22,15 +22,10 @@ import strutils, os, intsets, tables, ropes, db_sqlite, msgs, options, types, ## - Depencency computation should use signature hashes in order to ## avoid recompiling dependent modules. -var db: DbConn +template db(): DbConn = g.incr.db -proc hashFileCached(fileIdx: int32; fullpath: string): string = - result = msgs.getHash(fileIdx) - if result.len == 0: - result = $secureHashFile(fullpath) - msgs.setHash(fileIdx, result) - -proc needsRecompile(fileIdx: int32; fullpath: string; cycleCheck: var IntSet): bool = +proc needsRecompile(g: ModuleGraph; fileIdx: int32; fullpath: string; + cycleCheck: var IntSet): bool = let root = db.getRow(sql"select id, fullhash from filenames where fullpath = ?", fullpath) if root[0].len == 0: return true @@ -43,11 +38,11 @@ proc needsRecompile(fileIdx: int32; fullpath: string; cycleCheck: var IntSet): b for row in db.fastRows(sql"select fullpath from filenames where id in (select dependency from deps where module = ?)", root[0]): let dep = row[0] - if needsRecompile(dep.fileInfoIdx, dep, cycleCheck): + if needsRecompile(g, dep.fileInfoIdx, dep, cycleCheck): return true return false -proc getModuleId*(fileIdx: int32; fullpath: string): int = +proc getModuleId*(g: ModuleGraph; fileIdx: int32; fullpath: string): int = if gSymbolFiles != v2Sf: return getID() let module = db.getRow( sql"select id, fullHash from modules where fullpath = ?", fullpath) @@ -103,27 +98,6 @@ proc pushSym(w: PRodWriter, s: PSym) = if not containsOrIncl(w.smarks, s.id): w.sstack.add(s) -proc toDbFileId(fileIdx: int32): int = - if fileIdx == -1: return -1 - let fullpath = fileIdx.toFullPath - let row = db.getRow(sql"select id, fullhash from filenames where fullpath = ?", - fullpath) - let id = row[0] - let fullhash = hashFileCached(fileIdx, fullpath) - if id.len == 0: - result = int db.insertID(sql"insert into filenames(fullpath, fullhash) values (?, ?)", - fullpath, fullhash) - else: - if row[1] != fullhash: - db.exec(sql"update filenames set fullhash = ? where fullpath = ?", fullhash, fullpath) - result = parseInt(id) - -proc fromDbFileId(dbId: int): int32 = - if dbId == -1: return -1 - let fullpath = db.getValue(sql"select fullpath from filenames where id = ?", dbId) - doAssert fullpath.len > 0, "cannot find file name for DB ID " & $dbId - result = fileInfoIdx(fullpath) - proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, result: var string) = if n == nil: @@ -395,7 +369,7 @@ proc storeType(w: PRodWriter; t: PType) = var w = initRodWriter(nil) -proc storeNode*(module: PSym; n: PNode) = +proc storeNode*(g: ModuleGraph; module: PSym; n: PNode) = if gSymbolFiles != v2Sf: return w.module = module var buf = newStringOfCap(160) @@ -421,7 +395,7 @@ proc storeNode*(module: PSym; n: PNode) = break inc i -proc storeRemaining*(module: PSym) = +proc storeRemaining*(g: ModuleGraph; module: PSym) = if gSymbolFiles != v2Sf: return w.module = module for s in w.forwardedSyms: @@ -437,7 +411,7 @@ type #tstack: seq[(PType, ptr PType)] # a stack of types to process #tmarks, smarks: IntSet - syms: Table[int, PSym] ## XXX make this more efficients + syms: Table[int, PSym] ## XXX make this more efficient types: Table[int, PType] cache: IdentCache @@ -813,7 +787,7 @@ proc loadModuleSymTab(r; module: PSym) = if sfSystemModule in module.flags: magicsys.systemModule = module -proc loadNode*(module: PSym; index: int): PNode = +proc loadNode*(g: ModuleGraph; module: PSym; index: int): PNode = assert gSymbolFiles == v2Sf if index == 0: loadModuleSymTab(gr, module) @@ -828,110 +802,9 @@ proc loadNode*(module: PSym; index: int): PNode = gr.module = module result = decodeNode(gr, b, module.info) -proc addModuleDep*(module, fileIdx: int32; isIncludeFile: bool) = - if gSymbolFiles != v2Sf: return - - let a = toDbFileId(module) - let b = toDbFileId(fileIdx) - - db.exec(sql"insert into deps(module, dependency, isIncludeFile) values (?, ?, ?)", - a, b, ord(isIncludeFile)) - -# --------------- Database model --------------------------------------------- - -proc createDb() = - db.exec(sql""" - create table if not exists controlblock( - idgen integer not null - ); - """) - - db.exec(sql""" - create table if not exists filenames( - id integer primary key, - fullpath varchar(8000) not null, - fullHash varchar(256) not null - ); - """) - db.exec sql"create index if not exists FilenameIx on filenames(fullpath);" - - db.exec(sql""" - create table if not exists modules( - id integer primary key, - fullpath varchar(8000) not null, - interfHash varchar(256) not null, - fullHash varchar(256) not null, - - created timestamp not null default (DATETIME('now')) - );""") - db.exec(sql"""create unique index if not exists SymNameIx on modules(fullpath);""") - - db.exec(sql""" - create table if not exists deps( - id integer primary key, - module integer not null, - dependency integer not null, - isIncludeFile integer not null, - foreign key (module) references filenames(id), - foreign key (dependency) references filenames(id) - );""") - db.exec(sql"""create index if not exists DepsIx on deps(module);""") - - db.exec(sql""" - create table if not exists types( - id integer primary key, - nimid integer not null, - module integer not null, - data blob not null, - foreign key (module) references module(id) - ); - """) - db.exec sql"create index TypeByModuleIdx on types(module);" - db.exec sql"create index TypeByNimIdIdx on types(nimid);" - - db.exec(sql""" - create table if not exists syms( - id integer primary key, - nimid integer not null, - module integer not null, - name varchar(256) not null, - data blob not null, - exported int not null, - foreign key (module) references module(id) - ); - """) - db.exec sql"create index if not exists SymNameIx on syms(name);" - db.exec sql"create index SymByNameAndModuleIdx on syms(name, module);" - db.exec sql"create index SymByModuleIdx on syms(module);" - db.exec sql"create index SymByNimIdIdx on syms(nimid);" - - - db.exec(sql""" - create table if not exists toplevelstmts( - id integer primary key, - position integer not null, - module integer not null, - data blob not null, - foreign key (module) references module(id) - ); - """) - db.exec sql"create index TopLevelStmtByModuleIdx on toplevelstmts(module);" - db.exec sql"create index TopLevelStmtByPositionIdx on toplevelstmts(position);" - - db.exec(sql""" - create table if not exists statics( - id integer primary key, - module integer not null, - data blob not null, - foreign key (module) references module(id) - ); - """) - db.exec sql"create index StaticsByModuleIdx on toplevelstmts(module);" - db.exec sql"insert into controlblock(idgen) values (0)" - -proc setupModuleCache* = +proc setupModuleCache*(g: ModuleGraph) = if gSymbolFiles != v2Sf: return - let dbfile = getNimcacheDir() / "rodfiles.db" + let dbfile = getNimcacheDir(g.config) / "rodfiles.db" if not fileExists(dbfile): db = open(connection=dbfile, user="nim", password="", database="nim") diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 0b27418b3..968cb9e7f 100644 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -622,12 +622,6 @@ proc process(c: PPassContext, n: PNode): PNode = # Note: The check for ``s.typ.kind = tyEnum`` is wrong for enum # type aliasing! Otherwise the same enum symbol would be included # several times! - # - # if (a.sons[2] <> nil) and (a.sons[2].kind = nkEnumTy) then begin - # a := s.typ.n; - # for j := 0 to sonsLen(a)-1 do - # addInterfaceSym(w, a.sons[j].sym); - # end of nkImportStmt: for i in countup(0, sonsLen(n) - 1): addModDep(w, getModuleName(w.config, n.sons[i]), n.info) diff --git a/compiler/sem.nim b/compiler/sem.nim index 52042fa7d..d0f106526 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -597,7 +597,7 @@ proc myProcess(context: PPassContext, n: PNode): PNode = else: result = newNodeI(nkEmpty, n.info) #if c.config.cmd == cmdIdeTools: findSuggest(c, n) - rod.storeNode(c.module, result) + rod.storeNode(c.graph, c.module, result) proc testExamples(c: PContext) = let inp = toFullPath(c.config, c.module.info) @@ -627,7 +627,7 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = replayMethodDefs(graph, c.rd) popOwner(c) popProcCon(c) - storeRemaining(c.module) + storeRemaining(c.graph, c.module) if c.runnableExamples != nil: testExamples(c) const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose, |