summary refs log tree commit diff stats
path: root/compiler/docgen.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/docgen.nim')
-rw-r--r--compiler/docgen.nim109
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)