diff options
Diffstat (limited to 'compiler/docgen.nim')
-rw-r--r-- | compiler/docgen.nim | 109 |
1 files changed, 60 insertions, 49 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 7ab2f0eee..db4e301d4 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -16,7 +16,7 @@ import wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast, packages/docutils/rst, packages/docutils/rstgen, times, packages/docutils/highlite, sempass2, json, xmltree, cgi, - typesrenderer, astalgo, modulepaths, configuration + typesrenderer, astalgo, modulepaths, lineinfos type TSections = array[TSymKind, Rope] @@ -30,6 +30,7 @@ type types: TStrTable isPureRst: bool conf*: ConfigRef + cache*: IdentCache PDoc* = ref TDocumentor ## Alias to type less. @@ -86,10 +87,11 @@ proc parseRst(text, filename: string, result = rstParse(text, filename, line, column, hasToc, rstOptions, docgenFindFile, compilerMsgHandler) -proc newDocumentor*(filename: string, conf: ConfigRef): PDoc = +proc newDocumentor*(filename: string; cache: IdentCache; conf: ConfigRef): PDoc = declareClosures() new(result) result.conf = conf + result.cache = cache initRstGenerator(result[], (if conf.cmd != cmdRst2tex: outHtml else: outLatex), conf.configVars, filename, {roSupportRawDirective}, docgenFindFile, compilerMsgHandler) @@ -190,7 +192,7 @@ proc genComment(d: PDoc, n: PNode): string = result = "" var dummyHasToc: bool if n.comment != nil: - renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), + renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info), toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options, d.conf), result) @@ -307,13 +309,13 @@ when false: result = findDocComment(n.sons[i]) if result != nil: return - proc extractDocComment*(s: PSym, d: PDoc = nil): string = + proc extractDocComment*(s: PSym, d: PDoc): string = let n = findDocComment(s.ast) result = "" if not n.isNil: if not d.isNil: var dummyHasToc: bool - renderRstToOut(d[], parseRst(n.comment, toFilename(n.info), + renderRstToOut(d[], parseRst(n.comment, toFilename(d.conf, n.info), toLinenumber(n.info), toColumn(n.info), dummyHasToc, d.options + {roSkipPounds}), result) @@ -349,18 +351,18 @@ proc getName(d: PDoc, n: PNode, splitAfter = -1): string = else: result = "" -proc getNameIdent(n: PNode): PIdent = +proc getNameIdent(cache: IdentCache; n: PNode): PIdent = case n.kind - of nkPostfix: result = getNameIdent(n.sons[1]) - of nkPragmaExpr: result = getNameIdent(n.sons[0]) + of nkPostfix: result = getNameIdent(cache, n.sons[1]) + of nkPragmaExpr: result = getNameIdent(cache, n.sons[0]) of nkSym: result = n.sym.name of nkIdent: result = n.ident of nkAccQuoted: var r = "" - for i in 0..<n.len: r.add(getNameIdent(n[i]).s) - result = getIdent(r) + for i in 0..<n.len: r.add(getNameIdent(cache, n[i]).s) + result = getIdent(cache, r) of nkOpenSymChoice, nkClosedSymChoice: - result = getNameIdent(n[0]) + result = getNameIdent(cache, n[0]) else: result = nil @@ -502,7 +504,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) = let docItemSeeSrc = getConfigVar(d.conf, "doc.item.seesrc") if docItemSeeSrc.len > 0: let cwd = canonicalizePath(d.conf, getCurrentDir()) - var path = n.info.toFullPath + var path = toFullPath(d.conf, n.info) if path.startsWith(cwd): path = path[cwd.len+1 .. ^1].replace('\\', '/') let gitUrl = getConfigVar(d.conf, "git.url") @@ -580,27 +582,27 @@ proc traceDeps(d: PDoc, it: PNode) = if d.section[k] != nil: add(d.section[k], ", ") dispA(d.conf, d.section[k], "<a class=\"reference external\" href=\"$1.html\">$1</a>", - "$1", [rope(getModuleName(d.conf, it))]) + "$1", [rope(splitFile(getModuleName(d.conf, it)).name)]) proc generateDoc*(d: PDoc, n: PNode) = case n.kind of nkCommentStmt: add(d.modDesc, genComment(d, n)) of nkProcDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skProc) of nkFuncDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skFunc) of nkMethodDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skMethod) of nkIteratorDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skIterator) of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro) of nkTemplateDef: genItem(d, n, n.sons[namePos], skTemplate) of nkConverterDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: for i in countup(0, sonsLen(n) - 1): @@ -630,23 +632,23 @@ proc generateJson*(d: PDoc, n: PNode) = d.add %{ "comment": %stripped, "line": %n.info.line.int, "col": %n.info.col } of nkProcDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skProc) of nkFuncDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skFunc) of nkMethodDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skMethod) of nkIteratorDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skIterator) of nkMacroDef: d.add genJsonItem(d, n, n.sons[namePos], skMacro) of nkTemplateDef: d.add genJsonItem(d, n, n.sons[namePos], skTemplate) of nkConverterDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: for i in countup(0, sonsLen(n) - 1): @@ -673,23 +675,23 @@ proc generateTags*(d: PDoc, n: PNode, r: var Rope) = let stripped = n.comment.substr(2).strip r.add stripped of nkProcDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skProc) of nkFuncDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skFunc) of nkMethodDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skMethod) of nkIteratorDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skIterator) of nkMacroDef: r.add genTagsItem(d, n, n.sons[namePos], skMacro) of nkTemplateDef: r.add genTagsItem(d, n, n.sons[namePos], skTemplate) of nkConverterDef: - when useEffectSystem: documentRaises(n) + when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: for i in countup(0, sonsLen(n) - 1): @@ -777,10 +779,14 @@ proc getOutFile2(conf: ConfigRef; filename, ext, dir: string): string = proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) = var content = genOutFile(d) + var success = true if optStdout in d.conf.globalOptions: writeRope(stdout, content) else: - writeRope(content, getOutFile2(d.conf, filename, outExt, "htmldocs"), useWarning) + let outfile = getOutFile2(d.conf, filename, outExt, "htmldocs") + success = writeRope(content, outfile) + if not success: + rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, filename) proc writeOutputJson*(d: PDoc, filename, outExt: string, useWarning = false) = @@ -798,18 +804,18 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string, else: discard "fixme: error report" -proc commandDoc*(conf: ConfigRef) = - var ast = parseFile(conf.projectMainIdx.FileIndex, newIdentCache(), conf) +proc commandDoc*(cache: IdentCache, conf: ConfigRef) = + var ast = parseFile(conf.projectMainIdx, cache, conf) if ast == nil: return - var d = newDocumentor(conf.projectFull, conf) + var d = newDocumentor(conf.projectFull, cache, conf) d.hasToc = true generateDoc(d, ast) writeOutput(d, conf.projectFull, HtmlExt) generateIndex(d) -proc commandRstAux(conf: ConfigRef; filename, outExt: string) = +proc commandRstAux(cache: IdentCache, conf: ConfigRef; filename, outExt: string) = var filen = addFileExt(filename, "txt") - var d = newDocumentor(filen, conf) + var d = newDocumentor(filen, cache, conf) d.onTestSnippet = proc (d: var RstGenerator; filename, cmd: string; status: int; content: string) = var outp: string @@ -841,17 +847,16 @@ proc commandRstAux(conf: ConfigRef; filename, outExt: string) = writeOutput(d, filename, outExt) generateIndex(d) -proc commandRst2Html*(conf: ConfigRef) = - commandRstAux(conf, conf.projectFull, HtmlExt) +proc commandRst2Html*(cache: IdentCache, conf: ConfigRef) = + commandRstAux(cache, conf, conf.projectFull, HtmlExt) -proc commandRst2TeX*(conf: ConfigRef) = - splitter = "\\-" - commandRstAux(conf, conf.projectFull, TexExt) +proc commandRst2TeX*(cache: IdentCache, conf: ConfigRef) = + commandRstAux(cache, conf, conf.projectFull, TexExt) -proc commandJson*(conf: ConfigRef) = - var ast = parseFile(conf.projectMainIdx.FileIndex, newIdentCache(), conf) +proc commandJson*(cache: IdentCache, conf: ConfigRef) = + var ast = parseFile(conf.projectMainIdx, cache, conf) if ast == nil: return - var d = newDocumentor(conf.projectFull, conf) + var d = newDocumentor(conf.projectFull, cache, conf) d.hasToc = true generateJson(d, ast) let json = d.jArray @@ -861,12 +866,14 @@ proc commandJson*(conf: ConfigRef) = writeRope(stdout, content) else: #echo getOutFile(gProjectFull, JsonExt) - writeRope(content, getOutFile(conf, conf.projectFull, JsonExt), useWarning = false) + let filename = getOutFile(conf, conf.projectFull, JsonExt) + if not writeRope(content, filename): + rawMessage(conf, errCannotOpenFile, filename) -proc commandTags*(conf: ConfigRef) = - var ast = parseFile(conf.projectMainIdx.FileIndex, newIdentCache(), conf) +proc commandTags*(cache: IdentCache, conf: ConfigRef) = + var ast = parseFile(conf.projectMainIdx, cache, conf) if ast == nil: return - var d = newDocumentor(conf.projectFull, conf) + var d = newDocumentor(conf.projectFull, cache, conf) d.hasToc = true var content: Rope @@ -876,9 +883,11 @@ proc commandTags*(conf: ConfigRef) = writeRope(stdout, content) else: #echo getOutFile(gProjectFull, TagsExt) - writeRope(content, getOutFile(conf, conf.projectFull, TagsExt), useWarning = false) + let filename = getOutFile(conf, conf.projectFull, TagsExt) + if not writeRope(content, filename): + rawMessage(conf, errCannotOpenFile, filename) -proc commandBuildIndex*(conf: ConfigRef) = +proc commandBuildIndex*(cache: IdentCache, conf: ConfigRef) = var content = mergeIndexes(conf.projectFull).rope let code = ropeFormatNamedVars(conf, getConfigVar(conf, "doc.file"), ["title", @@ -887,4 +896,6 @@ proc commandBuildIndex*(conf: ConfigRef) = ["Index".rope, nil, nil, rope(getDateStr()), rope(getClockStr()), content, nil, nil, nil]) # no analytics because context is not available - writeRope(code, getOutFile(conf, "theindex", HtmlExt)) + let filename = getOutFile(conf, "theindex", HtmlExt) + if not writeRope(code, filename): + rawMessage(conf, errCannotOpenFile, filename) |