diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-07-19 14:13:16 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-07-19 14:13:23 +0200 |
commit | 9eb909baf985b8f6d2b8bc55fee8e67744e9b6fe (patch) | |
tree | e799899271ce59556e37856c39ea49a5d80997a8 | |
parent | ab9e44dc966cba2c57cfff25d42ca927a7942faa (diff) | |
download | Nim-9eb909baf985b8f6d2b8bc55fee8e67744e9b6fe.tar.gz |
fixes #4485; package handling works better; docgen works with --project on Nimble package level
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/docgen.nim | 20 | ||||
-rw-r--r-- | compiler/docgen2.nim | 20 | ||||
-rw-r--r-- | compiler/modules.nim | 22 | ||||
-rw-r--r-- | compiler/options.nim | 50 | ||||
-rw-r--r-- | compiler/packagehandling.nim | 56 |
6 files changed, 104 insertions, 66 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 792dd0ea8..9ec88ba8e 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -771,7 +771,7 @@ type procInstCache*: seq[PInstantiation] gcUnsafetyReason*: PSym # for better error messages wrt gcsafe #scope*: PScope # the scope where the proc was defined - of skModule: + of skModule, skPackage: # modules keep track of the generic symbols they use from other modules. # this is because in incremental compilation, when a module is about to # be replaced with a newer version, we must decrement the usage count diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 67092780b..cf03718ca 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -650,22 +650,32 @@ proc generateIndex*(d: PDoc) = writeIndexFile(d[], splitFile(options.outFile).dir / splitFile(d.filename).name & IndexExt) +proc getOutFile2(filename, ext, dir: string): string = + if gWholeProject: + let d = if options.outFile != "": options.outFile else: dir + createDir(d) + result = d / changeFileExt(filename, ext) + else: + result = getOutFile(filename, ext) + proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) = var content = genOutFile(d) if optStdout in gGlobalOptions: writeRope(stdout, content) else: - writeRope(content, getOutFile(filename, outExt), useWarning) + writeRope(content, getOutFile2(filename, outExt, "htmldoc"), useWarning) proc writeOutputJson*(d: PDoc, filename, outExt: string, useWarning = false) = - let content = $d.jArray + let content = %*{"orig": d.filename, + "nimble": getPackageName(d.filename), + "entries": d.jArray} if optStdout in gGlobalOptions: - write(stdout, content) + write(stdout, $content) else: var f: File - if open(f, getOutFile(filename, outExt), fmWrite): - write(f, content) + if open(f, getOutFile2(filename, outExt, "jsondoc"), fmWrite): + write(f, $content) close(f) else: discard "fixme: error report" diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index f83166f2b..03f8ce0cb 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -19,25 +19,25 @@ type module: PSym PGen = ref TGen -proc close(p: PPassContext, n: PNode): PNode = +template closeImpl(body: untyped) {.dirty.} = var g = PGen(p) let useWarning = sfMainModule notin g.module.flags - if gWholeProject or sfMainModule in g.module.flags: - writeOutput(g.doc, g.module.filename, HtmlExt, useWarning) + echo g.module.name.s, " ", g.module.owner.id, " ", gMainPackageId + if (g.module.owner.id == gMainPackageId and gWholeProject) or + sfMainModule in g.module.flags: + body try: generateIndex(g.doc) except IOError: discard +proc close(p: PPassContext, n: PNode): PNode = + closeImpl: + writeOutput(g.doc, g.module.filename, HtmlExt, useWarning) + proc closeJson(p: PPassContext, n: PNode): PNode = - var g = PGen(p) - let useWarning = sfMainModule notin g.module.flags - if gWholeProject or sfMainModule in g.module.flags: + closeImpl: writeOutputJson(g.doc, g.module.filename, ".json", useWarning) - try: - generateIndex(g.doc) - except IOError: - discard proc processNode(c: PPassContext, n: PNode): PNode = result = n diff --git a/compiler/modules.nim b/compiler/modules.nim index a45de6d72..8df300f5f 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -30,6 +30,9 @@ var ## XXX: we should implement recycling of file IDs ## if the user keeps renaming modules, the file IDs will keep growing gFuzzyGraphChecking*: bool # nimsuggest uses this. XXX figure out why. + packageSyms: TStrTable + +initStrTable(packageSyms) proc getModule*(fileIdx: int32): PSym = if fileIdx >= 0 and fileIdx < gCompiledModules.len: @@ -91,6 +94,7 @@ proc resetAllModules* = if gCompiledModules[i] != nil: resetModule(i.int32) resetPackageCache() + initStrTable(packageSyms) # for m in cgenModules(): echo "CGEN MODULE FOUND" proc resetAllModulesHard* = @@ -98,6 +102,7 @@ proc resetAllModulesHard* = gCompiledModules.setLen 0 gMemCacheData.setLen 0 magicsys.resetSysTypes() + initStrTable(packageSyms) # XXX #gOwners = @[] @@ -140,8 +145,16 @@ proc newModule(fileIdx: int32): PSym = rawMessage(errInvalidModuleName, result.name.s) result.info = newLineInfo(fileIdx, 1, 1) - result.owner = newSym(skPackage, getIdent(getPackageName(filename)), nil, - result.info) + let pack = getIdent(getPackageName(filename)) + var packSym = packageSyms.strTableGet(pack) + if packSym == nil: + let pck = getPackageName(filename) + let pck2 = if pck.len > 0: pck else: "unknown" + packSym = newSym(skPackage, getIdent(pck2), nil, result.info) + initStrTable(packSym.tab) + packageSyms.strTableAdd(packSym) + + result.owner = packSym result.position = fileIdx growCache gMemCacheData, fileIdx @@ -151,6 +164,11 @@ proc newModule(fileIdx: int32): PSym = incl(result.flags, sfUsed) initStrTable(result.tab) strTableAdd(result.tab, result) # a module knows itself + let existing = strTableGet(packSym.tab, result.name) + if existing != nil and existing.info.fileIndex != result.info.fileIndex: + localError(result.info, "module names need to be unique per Nimble package; module clashes with " & existing.info.fileIndex.toFullPath) + # strTableIncl() for error corrections: + discard strTableIncl(packSym.tab, result) proc compileModule*(fileIdx: int32, flags: TSymFlags): PSym = result = getModule(fileIdx) diff --git a/compiler/options.nim b/compiler/options.nim index dcee9eb7d..03ae83587 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -239,6 +239,8 @@ proc removeTrailingDirSep*(path: string): string = else: result = path +include packagehandling + proc getNimcacheDir*: string = result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir / genSubDir @@ -258,54 +260,6 @@ proc pathSubs*(p, config: string): string = if '~' in result: result = result.replace("~", home) -template newPackageCache(): expr = - newStringTable(when FileSystemCaseSensitive: - modeCaseInsensitive - else: - modeCaseSensitive) - -var packageCache = newPackageCache() - -proc resetPackageCache*() = packageCache = newPackageCache() - -iterator myParentDirs(p: string): string = - # XXX os's parentDirs is stupid (multiple yields) and triggers an old bug... - var current = p - while true: - current = current.parentDir - if current.len == 0: break - yield current - -proc getPackageName*(path: string): string = - var parents = 0 - block packageSearch: - for d in myParentDirs(path): - if packageCache.hasKey(d): - #echo "from cache ", d, " |", packageCache[d], "|", path.splitFile.name - return packageCache[d] - inc parents - for file in walkFiles(d / "*.nimble"): - result = file.splitFile.name - break packageSearch - for file in walkFiles(d / "*.babel"): - result = file.splitFile.name - break packageSearch - # we also store if we didn't find anything: - if result.isNil: result = "" - for d in myParentDirs(path): - #echo "set cache ", d, " |", result, "|", parents - packageCache[d] = result - dec parents - if parents <= 0: break - -proc withPackageName*(path: string): string = - let x = path.getPackageName - if x.len == 0: - result = path - else: - let (p, file, ext) = path.splitFile - result = (p / (x & '_' & file)) & ext - proc toGeneratedFile*(path, ext: string): string = ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" var (head, tail) = splitPath(path) diff --git a/compiler/packagehandling.nim b/compiler/packagehandling.nim new file mode 100644 index 000000000..c42a4d763 --- /dev/null +++ b/compiler/packagehandling.nim @@ -0,0 +1,56 @@ +# +# +# The Nim Compiler +# (c) Copyright 2016 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +iterator myParentDirs(p: string): string = + # XXX os's parentDirs is stupid (multiple yields) and triggers an old bug... + var current = p + while true: + current = current.parentDir + if current.len == 0: break + yield current + +template newPackageCache(): expr = + newStringTable(when FileSystemCaseSensitive: + modeCaseInsensitive + else: + modeCaseSensitive) + +var packageCache = newPackageCache() + +proc resetPackageCache*() = packageCache = newPackageCache() + +proc getPackageName*(path: string): string = + var parents = 0 + block packageSearch: + for d in myParentDirs(path): + if packageCache.hasKey(d): + #echo "from cache ", d, " |", packageCache[d], "|", path.splitFile.name + return packageCache[d] + inc parents + for file in walkFiles(d / "*.nimble"): + result = file.splitFile.name + break packageSearch + for file in walkFiles(d / "*.babel"): + result = file.splitFile.name + break packageSearch + # we also store if we didn't find anything: + if result.isNil: result = "" + for d in myParentDirs(path): + #echo "set cache ", d, " |", result, "|", parents + packageCache[d] = result + dec parents + if parents <= 0: break + +proc withPackageName*(path: string): string = + let x = path.getPackageName + if x.len == 0: + result = path + else: + let (p, file, ext) = path.splitFile + result = (p / (x & '_' & file)) & ext |