summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-07-12 22:35:55 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-07-13 01:06:33 +0200
commit813828f6907ce05756145c57bc6dd4758ffb2a7e (patch)
tree1707e2cdd205a0a0ca9c6b162f22b52f78804e0e /compiler
parentf47165af11f71acf872ab9fd5ab56e3465b19dad (diff)
downloadNim-813828f6907ce05756145c57bc6dd4758ffb2a7e.tar.gz
the Nim compiler supports the jsondoc2 command
Diffstat (limited to 'compiler')
-rw-r--r--compiler/docgen.nim56
-rw-r--r--compiler/docgen2.nim17
-rw-r--r--compiler/main.nim15
3 files changed, 63 insertions, 25 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index fab759848..4bd10437d 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -25,6 +25,7 @@ type
     indexValFilename: string
     analytics: string  # Google Analytics javascript, "" if doesn't exist
     seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML.
+    jArray: JsonNode
 
   PDoc* = ref TDocumentor ## Alias to type less.
 
@@ -81,6 +82,7 @@ proc newDocumentor*(filename: string, config: StringTableRef): PDoc =
 
   result.seenSymbols = newStringTable(modeCaseInsensitive)
   result.id = 100
+  result.jArray = newJArray()
 
 proc dispA(dest: var Rope, xml, tex: string, args: openArray[Rope]) =
   if gCmd != cmdRst2tex: addf(dest, xml, args)
@@ -439,7 +441,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
   setIndexTerm(d[], symbolOrId, name, linkTitle,
     xmltree.escape(plainDocstring.docstringSummary))
 
-proc genJSONItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
+proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonNode =
   if not isVisible(nameNode): return
   var
     name = getName(d, nameNode)
@@ -499,46 +501,44 @@ proc generateDoc*(d: PDoc, n: PNode) =
   of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
   else: discard
 
-proc generateJson(d: PDoc, n: PNode, jArray: JsonNode = nil): JsonNode =
+proc add(d: PDoc; j: JsonNode) =
+  if j != nil: d.jArray.add j
+
+proc generateJson*(d: PDoc, n: PNode) =
   case n.kind
   of nkCommentStmt:
     if n.comment != nil and startsWith(n.comment, "##"):
       let stripped = n.comment.substr(2).strip
-      result = %{ "comment": %stripped }
+      d.add %{ "comment": %stripped }
   of nkProcDef:
     when useEffectSystem: documentRaises(n)
-    result = genJSONItem(d, n, n.sons[namePos], skProc)
+    d.add genJsonItem(d, n, n.sons[namePos], skProc)
   of nkMethodDef:
     when useEffectSystem: documentRaises(n)
-    result = genJSONItem(d, n, n.sons[namePos], skMethod)
+    d.add genJsonItem(d, n, n.sons[namePos], skMethod)
   of nkIteratorDef:
     when useEffectSystem: documentRaises(n)
-    result = genJSONItem(d, n, n.sons[namePos], skIterator)
+    d.add genJsonItem(d, n, n.sons[namePos], skIterator)
   of nkMacroDef:
-    result = genJSONItem(d, n, n.sons[namePos], skMacro)
+    d.add genJsonItem(d, n, n.sons[namePos], skMacro)
   of nkTemplateDef:
-    result = genJSONItem(d, n, n.sons[namePos], skTemplate)
+    d.add genJsonItem(d, n, n.sons[namePos], skTemplate)
   of nkConverterDef:
     when useEffectSystem: documentRaises(n)
-    result = genJSONItem(d, n, n.sons[namePos], skConverter)
+    d.add genJsonItem(d, n, n.sons[namePos], skConverter)
   of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
     for i in countup(0, sonsLen(n) - 1):
       if n.sons[i].kind != nkCommentStmt:
         # order is always 'type var let const':
-        result = genJSONItem(d, n.sons[i], n.sons[i].sons[0],
+        d.add genJsonItem(d, n.sons[i], n.sons[i].sons[0],
                 succ(skType, ord(n.kind)-ord(nkTypeSection)))
   of nkStmtList:
-    result = if jArray != nil: jArray else: newJArray()
-
     for i in countup(0, sonsLen(n) - 1):
-      var r = generateJson(d, n.sons[i], result)
-      if r != nil:
-        result.add(r)
-
+      generateJson(d, n.sons[i])
   of nkWhenStmt:
     # generate documentation for the first branch only:
-    if not checkForFalse(n.sons[0].sons[0]) and jArray != nil:
-      discard generateJson(d, lastSon(n.sons[0]), jArray)
+    if not checkForFalse(n.sons[0].sons[0]):
+      generateJson(d, lastSon(n.sons[0]))
   else: discard
 
 proc genSection(d: PDoc, kind: TSymKind) =
@@ -607,6 +607,19 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
   else:
     writeRope(content, getOutFile(filename, outExt), useWarning)
 
+proc writeOutputJson*(d: PDoc, filename, outExt: string,
+                      useWarning = false) =
+  let content = $d.jArray
+  if optStdout in gGlobalOptions:
+    write(stdout, content)
+  else:
+    var f: File
+    if open(f, getOutFile(filename, outExt), fmWrite):
+      write(f, content)
+      close(f)
+    else:
+      discard "fixme: error report"
+
 proc commandDoc*() =
   var ast = parseFile(gProjectMainIdx)
   if ast == nil: return
@@ -636,13 +649,14 @@ proc commandRst2TeX*() =
   splitter = "\\-"
   commandRstAux(gProjectFull, TexExt)
 
-proc commandJSON*() =
+proc commandJson*() =
   var ast = parseFile(gProjectMainIdx)
   if ast == nil: return
   var d = newDocumentor(gProjectFull, options.gConfigVars)
   d.hasToc = true
-  var json = generateJson(d, ast)
-  var content = rope(pretty(json))
+  generateJson(d, ast)
+  let json = d.jArray
+  let content = rope(pretty(json))
 
   if optStdout in gGlobalOptions:
     writeRope(stdout, content)
diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim
index 27de06811..f83166f2b 100644
--- a/compiler/docgen2.nim
+++ b/compiler/docgen2.nim
@@ -29,11 +29,26 @@ proc close(p: PPassContext, n: PNode): PNode =
     except IOError:
       discard
 
+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:
+    writeOutputJson(g.doc, g.module.filename, ".json", useWarning)
+    try:
+      generateIndex(g.doc)
+    except IOError:
+      discard
+
 proc processNode(c: PPassContext, n: PNode): PNode =
   result = n
   var g = PGen(c)
   generateDoc(g.doc, n)
 
+proc processNodeJson(c: PPassContext, n: PNode): PNode =
+  result = n
+  var g = PGen(c)
+  generateJson(g.doc, n)
+
 proc myOpen(module: PSym): PPassContext =
   var g: PGen
   new(g)
@@ -44,6 +59,8 @@ proc myOpen(module: PSym): PPassContext =
   result = g
 
 const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close)
+const docgen2JsonPass* = makePass(open = myOpen, process = processNodeJson,
+                                  close = closeJson)
 
 proc finishDoc2Pass*(project: string) =
   discard
diff --git a/compiler/main.nim b/compiler/main.nim
index b1b9006bd..0db66b53e 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -46,10 +46,11 @@ proc commandCheck =
   rodPass()
   compileProject()
 
-proc commandDoc2 =
+proc commandDoc2(json: bool) =
   msgs.gErrorMax = high(int)  # do not stop after first error
   semanticPasses()
-  registerPass(docgen2Pass)
+  if json: registerPass(docgen2JsonPass)
+  else: registerPass(docgen2Pass)
   #registerPass(cleanupPass())
   compileProject()
   finishDoc2Pass(gProjectName)
@@ -281,7 +282,7 @@ proc mainCommand* =
     gCmd = cmdDoc
     loadConfigs(DocConfig)
     defineSymbol("nimdoc")
-    commandDoc2()
+    commandDoc2(false)
   of "rst2html":
     gCmd = cmdRst2html
     loadConfigs(DocConfig)
@@ -296,7 +297,13 @@ proc mainCommand* =
     loadConfigs(DocConfig)
     wantMainModule()
     defineSymbol("nimdoc")
-    commandJSON()
+    commandJson()
+  of "jsondoc2":
+    gCmd = cmdDoc
+    loadConfigs(DocConfig)
+    wantMainModule()
+    defineSymbol("nimdoc")
+    commandDoc2(true)
   of "buildindex":
     gCmd = cmdDoc
     loadConfigs(DocConfig)