Skip to content

Commit

Permalink
fix nim-lang#13150 nim doc --project works with duplicate names and…
Browse files Browse the repository at this point in the history
… with imports below main project file
  • Loading branch information
timotheecour committed Jan 22, 2020
1 parent 2fad7f1 commit 3745d17
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 15 deletions.
2 changes: 2 additions & 0 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ type
# check for the owner when touching 'usedGenerics'.
usedGenerics*: seq[PInstantiation]
tab*: TStrTable # interface table for modules
nimblePkg*: PSym
of skLet, skVar, skField, skForVar:
guard*: PSym
bitsize*: int
Expand Down Expand Up @@ -1389,6 +1390,7 @@ proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
result.ast = s.ast
result.id = s.id
result.flags = s.flags
result.nimblePkg = s.nimblePkg
system.shallowCopy(result.tab, s.tab)
result.options = s.options
result.position = s.position
Expand Down
3 changes: 3 additions & 0 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
of "docseesrcurl":
expectArg(conf, switch, arg, pass, info)
conf.docSeeSrcUrl = arg
of "docroot":
expectArg(conf, switch, arg, pass, info)
conf.docRoot = processPath(conf, arg, info, notRelativeToProj=true)
of "mainmodule", "m":
discard "allow for backwards compatibility, but don't do anything"
of "define", "d":
Expand Down
37 changes: 29 additions & 8 deletions compiler/docgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ type

PDoc* = ref TDocumentor ## Alias to type less.

proc presentationPath*(conf: ConfigRef, file: AbsoluteFile): RelativeFile =
let file2 = $file
let docRoot = conf.getDocRoot()
case $docRoot:
# of "$mixed": relativeToPkg(conf, file)
of "$pkg": # TODO: check this works; right now failing at command line step
let dir = getNimbleFile(conf, file2).parentDir.AbsoluteDir
result = relativeTo(file, dir)
of "$path":
result = getRelativePathFromConfigPath(conf, file)
else:
result = relativeTo(file, docRoot)
echo (result,)
result = result.string.replace("..", "@@").RelativeFile

proc whichType(d: PDoc; n: PNode): PSym =
if n.kind == nkSym:
if d.types.strTableContains(n.sym):
Expand Down Expand Up @@ -174,8 +189,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
if execShellCmd(c2) != status:
rawMessage(conf, errGenerated, "executing of external program failed: " & c2)
result.emitted = initIntSet()
result.destFile = getOutFile2(conf, relativeTo(filename, conf.projectPath),
outExt, RelativeDir"htmldocs", false)
result.destFile = getOutFile2(conf, presentationPath(conf, filename), outExt, RelativeDir"htmldocs", false)
result.thisDir = result.destFile.splitFile.dir

template dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) =
Expand Down Expand Up @@ -294,13 +308,13 @@ proc getPlainDocstring(n: PNode): string =
if result.len > 0: return

proc belongsToPackage(conf: ConfigRef; module: PSym): bool =
result = module.kind == skModule and module.owner != nil and
module.owner.id == conf.mainPackageId
result = module.kind == skModule and module.nimblePkg != nil and
module.nimblePkg.id == conf.mainPackageId

proc externalDep(d: PDoc; module: PSym): string =
if optWholeProject in d.conf.globalOptions:
let full = AbsoluteFile toFullPath(d.conf, FileIndex module.position)
let tmp = getOutFile2(d.conf, full.relativeTo(d.conf.projectPath), HtmlExt,
let tmp = getOutFile2(d.conf, presentationPath(d.conf, full), HtmlExt,
RelativeDir"htmldocs", sfMainModule notin module.flags)
result = relativeTo(tmp, d.thisDir, '/').string
else:
Expand Down Expand Up @@ -1012,6 +1026,12 @@ proc genSection(d: PDoc, kind: TSymKind) =
proc cssHref(outDir: AbsoluteDir, destFile: AbsoluteFile): Rope =
rope($relativeTo(outDir / RelativeFile"nimdoc.out.css", destFile.splitFile().dir, '/'))

proc nativeToUnix(path: string): string =
doAssert not path.isAbsolute # absolute files need more care for the drive
when DirSep == '\\':
result = replace(path, '\\', '/')
else: result = path

proc genOutFile(d: PDoc): Rope =
var
code, content: Rope
Expand All @@ -1030,7 +1050,8 @@ proc genOutFile(d: PDoc): Rope =
# Extract the title. Non API modules generate an entry in the index table.
if d.meta[metaTitle].len != 0:
title = d.meta[metaTitle]
let external = AbsoluteFile(d.filename).relativeTo(d.conf.projectPath, '/').changeFileExt(HtmlExt).string
let external = presentationPath(d.conf, AbsoluteFile d.filename).changeFileExt(HtmlExt).string.nativeToUnix
# TODO: change \ to / on windows
setIndexTerm(d[], external, "", title)
else:
# Modules get an automatic title for the HTML, but no entry in the index.
Expand Down Expand Up @@ -1059,8 +1080,8 @@ proc generateIndex*(d: PDoc) =
let dir = if not d.conf.outDir.isEmpty: d.conf.outDir
else: d.conf.projectPath / RelativeDir"htmldocs"
createDir(dir)
let dest = dir / changeFileExt(relativeTo(AbsoluteFile d.filename,
d.conf.projectPath), IndexExt)
let rel = presentationPath(d.conf, AbsoluteFile d.filename)
let dest = dir / changeFileExt(rel, IndexExt)
writeIndexFile(d[], dest.string)

proc writeOutput*(d: PDoc, useWarning = false) =
Expand Down
6 changes: 4 additions & 2 deletions compiler/docgen2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,16 @@ type
config: ConfigRef
PGen = ref TGen

template shouldProcess(g): bool =
(g.module.owner.id == g.doc.conf.mainPackageId and optWholeProject in g.doc.conf.globalOptions) or
proc shouldProcess(g: PGen): bool =
(g.module.nimblePkg.id == g.doc.conf.mainPackageId and optWholeProject in g.doc.conf.globalOptions) or
sfMainModule in g.module.flags or g.config.projectMainIdx == g.module.info.fileIndex

template closeImpl(body: untyped) {.dirty.} =
var g = PGen(p)
let useWarning = sfMainModule notin g.module.flags
if shouldProcess(g):
let path = toFullPath(g.config, g.module.info)
echo0b (path, getPackageName(g.config, path))
body
try:
generateIndex(g.doc)
Expand Down
3 changes: 3 additions & 0 deletions compiler/main.nim
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ proc mainCommand*(graph: ModuleGraph) =
for s in definedSymbolNames(conf.symbols): definedSymbols.elems.add(%s)

var libpaths = newJArray()
var lazyPaths = newJArray()
for dir in conf.searchPaths: libpaths.elems.add(%dir.string)
for dir in conf.lazyPaths: lazyPaths.elems.add(%dir.string)

var hints = newJObject() # consider factoring with `listHints`
for a in hintMin..hintMax:
Expand All @@ -309,6 +311,7 @@ proc mainCommand*(graph: ModuleGraph) =
(key: "project_path", val: %conf.projectFull.string),
(key: "defined_symbols", val: definedSymbols),
(key: "lib_paths", val: %libpaths),
(key: "lazyPaths", val: %lazyPaths),
(key: "outdir", val: %conf.outDir.string),
(key: "out", val: %conf.outFile.string),
(key: "nimcache", val: %getNimcacheDir(conf).string),
Expand Down
2 changes: 2 additions & 0 deletions compiler/modules.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ proc partialInitModule(result: PSym; graph: ModuleGraph; fileIdx: FileIndex; fil
packSym = newSym(skPackage, getIdent(graph.cache, pck2), nil, result.info)
initStrTable(packSym.tab)
graph.packageSyms.strTableAdd(packSym)
result.nimblePkg = packSym
else:
result.nimblePkg = packSym
let existing = strTableGet(packSym.tab, result.name)
if existing != nil and existing.info.fileIndex != result.info.fileIndex:
when false:
Expand Down
32 changes: 32 additions & 0 deletions compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ type
implicitIncludes*: seq[string] # modules that are to be implicitly included
docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \
# The string uses the formatting variables `path` and `line`.
docRoot*: AbsoluteDir
# `nim doc --docRoot:foo --project --outdir:docs foo/sub/main.nim`
# genrates: docs/sub/main.html

# the used compiler
cIncludes*: seq[AbsoluteDir] # directories to search for included files
Expand Down Expand Up @@ -497,6 +500,9 @@ proc absOutFile*(conf: ConfigRef): AbsoluteFile =
if dirExists(result.string):
result.string.add ".out"

proc getDocRoot*(conf: ConfigRef): AbsoluteDir =
if conf.docRoot.isEmpty: conf.projectPath else: conf.docRoot

proc prepareToWriteOutput*(conf: ConfigRef): AbsoluteFile =
## Create the output directory and returns a full path to the output file
createDir conf.outDir
Expand Down Expand Up @@ -653,6 +659,32 @@ template patchModule(conf: ConfigRef) {.dirty.} =
let ov = conf.moduleOverrides[key]
if ov.len > 0: result = AbsoluteFile(ov)

proc isRelativeTo(path: string, base: string): bool=
# PENDING #13212
let path = path.normalizedPath
let base = base.normalizedPath
let ret = relativePath(path, base)
result = path.len > 0 and not ret.startsWith ".."

proc getRelativePathFromConfigPath*(conf: ConfigRef; f: AbsoluteFile): RelativeFile =
let f = $f
template search(paths) =
for it in paths:
let it = $it
if f.isRelativeTo(it):
return relativePath(f, it).RelativeFile
search(conf.searchPaths)
search(conf.lazyPaths)

proc relativeToPkg*(conf: ConfigRef, file: AbsoluteFile): string =
let file2 = $file
let dir = getNimbleFile(conf, file2).parentDir
result = relativePath(file2, dir)
# take care of things like in stdlib with multiple `--path:lib/pure` etc
let path2 = getRelativePathFromConfigPath(conf, file).string
if path2.len > result.len: result = path2
if result.len == 0: result = file2

proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile =
if f.isAbsolute:
result = if f.existsFile: AbsoluteFile(f) else: AbsoluteFile""
Expand Down
13 changes: 8 additions & 5 deletions compiler/packagehandling.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ iterator myParentDirs(p: string): string =
if current.len == 0: break
yield current

proc resetPackageCache*(conf: ConfigRef) =
conf.packageCache = newPackageCache()

proc getPackageName*(conf: ConfigRef; path: string): string =
proc getNimbleFile*(conf: ConfigRef; path: string): string =
## returns absolute path to nimble file, eg: /pathto/cligen.nimble
var parents = 0
block packageSearch:
for d in myParentDirs(path):
Expand All @@ -27,7 +25,7 @@ proc getPackageName*(conf: ConfigRef; path: string): string =
return conf.packageCache[d]
inc parents
for file in walkFiles(d / "*.nimble"):
result = file.splitFile.name
result = file
break packageSearch
# we also store if we didn't find anything:
when not defined(nimNoNilSeqs):
Expand All @@ -38,6 +36,11 @@ proc getPackageName*(conf: ConfigRef; path: string): string =
dec parents
if parents <= 0: break

proc getPackageName*(conf: ConfigRef; path: string): string =
## returns nimble package name, eg: `cligen`
let path = getNimbleFile(conf, path)
result = path.splitFile.name

proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string =
# Convert `path` so that 2 modules with same name
# in different directory get different name and they can be
Expand Down

0 comments on commit 3745d17

Please sign in to comment.