the Nim compiler supports the jsondoc2 command

This commit is contained in:
Andreas Rumpf 2016-07-12 22:35:55 +02:00
commit 813828f690
4 changed files with 64 additions and 25 deletions

View file

@ -25,6 +25,7 @@ type
indexValFilename: string indexValFilename: string
analytics: string # Google Analytics javascript, "" if doesn't exist analytics: string # Google Analytics javascript, "" if doesn't exist
seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML. seenSymbols: StringTableRef # avoids duplicate symbol generation for HTML.
jArray: JsonNode
PDoc* = ref TDocumentor ## Alias to type less. PDoc* = ref TDocumentor ## Alias to type less.
@ -81,6 +82,7 @@ proc newDocumentor*(filename: string, config: StringTableRef): PDoc =
result.seenSymbols = newStringTable(modeCaseInsensitive) result.seenSymbols = newStringTable(modeCaseInsensitive)
result.id = 100 result.id = 100
result.jArray = newJArray()
proc dispA(dest: var Rope, xml, tex: string, args: openArray[Rope]) = proc dispA(dest: var Rope, xml, tex: string, args: openArray[Rope]) =
if gCmd != cmdRst2tex: addf(dest, xml, args) 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, setIndexTerm(d[], symbolOrId, name, linkTitle,
xmltree.escape(plainDocstring.docstringSummary)) 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 if not isVisible(nameNode): return
var var
name = getName(d, nameNode) name = getName(d, nameNode)
@ -499,46 +501,44 @@ proc generateDoc*(d: PDoc, n: PNode) =
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0]) of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
else: discard 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 case n.kind
of nkCommentStmt: of nkCommentStmt:
if n.comment != nil and startsWith(n.comment, "##"): if n.comment != nil and startsWith(n.comment, "##"):
let stripped = n.comment.substr(2).strip let stripped = n.comment.substr(2).strip
result = %{ "comment": %stripped } d.add %{ "comment": %stripped }
of nkProcDef: of nkProcDef:
when useEffectSystem: documentRaises(n) when useEffectSystem: documentRaises(n)
result = genJSONItem(d, n, n.sons[namePos], skProc) d.add genJsonItem(d, n, n.sons[namePos], skProc)
of nkMethodDef: of nkMethodDef:
when useEffectSystem: documentRaises(n) when useEffectSystem: documentRaises(n)
result = genJSONItem(d, n, n.sons[namePos], skMethod) d.add genJsonItem(d, n, n.sons[namePos], skMethod)
of nkIteratorDef: of nkIteratorDef:
when useEffectSystem: documentRaises(n) when useEffectSystem: documentRaises(n)
result = genJSONItem(d, n, n.sons[namePos], skIterator) d.add genJsonItem(d, n, n.sons[namePos], skIterator)
of nkMacroDef: of nkMacroDef:
result = genJSONItem(d, n, n.sons[namePos], skMacro) d.add genJsonItem(d, n, n.sons[namePos], skMacro)
of nkTemplateDef: of nkTemplateDef:
result = genJSONItem(d, n, n.sons[namePos], skTemplate) d.add genJsonItem(d, n, n.sons[namePos], skTemplate)
of nkConverterDef: of nkConverterDef:
when useEffectSystem: documentRaises(n) 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: of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
if n.sons[i].kind != nkCommentStmt: if n.sons[i].kind != nkCommentStmt:
# order is always 'type var let const': # 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))) succ(skType, ord(n.kind)-ord(nkTypeSection)))
of nkStmtList: of nkStmtList:
result = if jArray != nil: jArray else: newJArray()
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var r = generateJson(d, n.sons[i], result) generateJson(d, n.sons[i])
if r != nil:
result.add(r)
of nkWhenStmt: of nkWhenStmt:
# generate documentation for the first branch only: # generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]) and jArray != nil: if not checkForFalse(n.sons[0].sons[0]):
discard generateJson(d, lastSon(n.sons[0]), jArray) generateJson(d, lastSon(n.sons[0]))
else: discard else: discard
proc genSection(d: PDoc, kind: TSymKind) = proc genSection(d: PDoc, kind: TSymKind) =
@ -607,6 +607,19 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
else: else:
writeRope(content, getOutFile(filename, outExt), useWarning) 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*() = proc commandDoc*() =
var ast = parseFile(gProjectMainIdx) var ast = parseFile(gProjectMainIdx)
if ast == nil: return if ast == nil: return
@ -636,13 +649,14 @@ proc commandRst2TeX*() =
splitter = "\\-" splitter = "\\-"
commandRstAux(gProjectFull, TexExt) commandRstAux(gProjectFull, TexExt)
proc commandJSON*() = proc commandJson*() =
var ast = parseFile(gProjectMainIdx) var ast = parseFile(gProjectMainIdx)
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true d.hasToc = true
var json = generateJson(d, ast) generateJson(d, ast)
var content = rope(pretty(json)) let json = d.jArray
let content = rope(pretty(json))
if optStdout in gGlobalOptions: if optStdout in gGlobalOptions:
writeRope(stdout, content) writeRope(stdout, content)

View file

@ -29,11 +29,26 @@ proc close(p: PPassContext, n: PNode): PNode =
except IOError: except IOError:
discard 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 = proc processNode(c: PPassContext, n: PNode): PNode =
result = n result = n
var g = PGen(c) var g = PGen(c)
generateDoc(g.doc, n) 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 = proc myOpen(module: PSym): PPassContext =
var g: PGen var g: PGen
new(g) new(g)
@ -44,6 +59,8 @@ proc myOpen(module: PSym): PPassContext =
result = g result = g
const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close) const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close)
const docgen2JsonPass* = makePass(open = myOpen, process = processNodeJson,
close = closeJson)
proc finishDoc2Pass*(project: string) = proc finishDoc2Pass*(project: string) =
discard discard

View file

@ -46,10 +46,11 @@ proc commandCheck =
rodPass() rodPass()
compileProject() compileProject()
proc commandDoc2 = proc commandDoc2(json: bool) =
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
semanticPasses() semanticPasses()
registerPass(docgen2Pass) if json: registerPass(docgen2JsonPass)
else: registerPass(docgen2Pass)
#registerPass(cleanupPass()) #registerPass(cleanupPass())
compileProject() compileProject()
finishDoc2Pass(gProjectName) finishDoc2Pass(gProjectName)
@ -281,7 +282,7 @@ proc mainCommand* =
gCmd = cmdDoc gCmd = cmdDoc
loadConfigs(DocConfig) loadConfigs(DocConfig)
defineSymbol("nimdoc") defineSymbol("nimdoc")
commandDoc2() commandDoc2(false)
of "rst2html": of "rst2html":
gCmd = cmdRst2html gCmd = cmdRst2html
loadConfigs(DocConfig) loadConfigs(DocConfig)
@ -296,7 +297,13 @@ proc mainCommand* =
loadConfigs(DocConfig) loadConfigs(DocConfig)
wantMainModule() wantMainModule()
defineSymbol("nimdoc") defineSymbol("nimdoc")
commandJSON() commandJson()
of "jsondoc2":
gCmd = cmdDoc
loadConfigs(DocConfig)
wantMainModule()
defineSymbol("nimdoc")
commandDoc2(true)
of "buildindex": of "buildindex":
gCmd = cmdDoc gCmd = cmdDoc
loadConfigs(DocConfig) loadConfigs(DocConfig)

View file

@ -6,6 +6,7 @@ Advanced commands:
//rst2html convert a reStructuredText file to HTML //rst2html convert a reStructuredText file to HTML
//rst2tex convert a reStructuredText file to TeX //rst2tex convert a reStructuredText file to TeX
//jsondoc extract the documentation to a json file //jsondoc extract the documentation to a json file
//jsondoc2 extract documentation to a json file (uses doc2)
//buildIndex build an index for the whole documentation //buildIndex build an index for the whole documentation
//run run the project (with Tiny C backend; buggy!) //run run the project (with Tiny C backend; buggy!)
//genDepend generate a DOT file containing the //genDepend generate a DOT file containing the