runnableExample: put each example to its own file; fixes #7285
This commit is contained in:
parent
06dbe9697f
commit
0d68ef9f11
2 changed files with 27 additions and 30 deletions
|
|
@ -31,7 +31,7 @@ type
|
||||||
isPureRst: bool
|
isPureRst: bool
|
||||||
conf*: ConfigRef
|
conf*: ConfigRef
|
||||||
cache*: IdentCache
|
cache*: IdentCache
|
||||||
runnableExamples*: PNode
|
exampleCounter: int
|
||||||
|
|
||||||
PDoc* = ref TDocumentor ## Alias to type less.
|
PDoc* = ref TDocumentor ## Alias to type less.
|
||||||
|
|
||||||
|
|
@ -285,29 +285,26 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
|
||||||
dispA(d.conf, result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
dispA(d.conf, result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
|
||||||
[rope(esc(d.target, literal))])
|
[rope(esc(d.target, literal))])
|
||||||
|
|
||||||
proc testExamples*(d: PDoc) =
|
proc testExample(d: PDoc; ex: PNode) =
|
||||||
if d.runnableExamples == nil or d.conf.errorCounter > 0: return
|
if d.conf.errorCounter > 0: return
|
||||||
let outputDir = d.conf.getNimcacheDir / "runnableExamples"
|
let outputDir = d.conf.getNimcacheDir / "runnableExamples"
|
||||||
createDir(outputDir)
|
createDir(outputDir)
|
||||||
let inp = toFullPath(d.conf, d.runnableExamples.info)
|
inc d.exampleCounter
|
||||||
let outp = outputDir / extractFilename(inp.changeFileExt"" & "_examples.nim")
|
let outp = outputDir / extractFilename(d.filename.changeFileExt"" &
|
||||||
let nimcache = outp.changeFileExt"" & "_nimcache"
|
"_examples" & $d.exampleCounter & ".nim")
|
||||||
renderModule(d.runnableExamples, inp, outp, conf = d.conf)
|
#let nimcache = outp.changeFileExt"" & "_nimcache"
|
||||||
|
renderModule(ex, d.filename, outp, conf = d.conf)
|
||||||
let backend = if isDefined(d.conf, "js"): "js"
|
let backend = if isDefined(d.conf, "js"): "js"
|
||||||
elif isDefined(d.conf, "cpp"): "cpp"
|
elif isDefined(d.conf, "cpp"): "cpp"
|
||||||
elif isDefined(d.conf, "objc"): "objc"
|
elif isDefined(d.conf, "objc"): "objc"
|
||||||
else: "c"
|
else: "c"
|
||||||
if os.execShellCmd(os.getAppFilename() & " " & backend &
|
if os.execShellCmd(os.getAppFilename() & " " & backend &
|
||||||
" --nimcache:" & nimcache & " -r " & outp) != 0:
|
" --nimcache:" & outputDir & " -r " & outp) != 0:
|
||||||
quit "[Examples] failed: see " & outp
|
quit "[Examples] failed: see " & outp
|
||||||
else:
|
else:
|
||||||
# keep generated source file `outp` to allow inspection.
|
# keep generated source file `outp` to allow inspection.
|
||||||
rawMessage(d.conf, hintSuccess, ["runnableExamples: " & outp])
|
rawMessage(d.conf, hintSuccess, ["runnableExamples: " & outp])
|
||||||
removeFile(outp.changeFileExt(ExeExt))
|
removeFile(outp.changeFileExt(ExeExt))
|
||||||
try:
|
|
||||||
removeDir(nimcache)
|
|
||||||
except OSError:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc extractImports(n: PNode; result: PNode) =
|
proc extractImports(n: PNode; result: PNode) =
|
||||||
if n.kind in {nkImportStmt, nkImportExceptStmt, nkFromStmt}:
|
if n.kind in {nkImportStmt, nkImportExceptStmt, nkFromStmt}:
|
||||||
|
|
@ -317,16 +314,15 @@ proc extractImports(n: PNode; result: PNode) =
|
||||||
for i in 0..<n.safeLen: extractImports(n[i], result)
|
for i in 0..<n.safeLen: extractImports(n[i], result)
|
||||||
|
|
||||||
proc prepareExamples(d: PDoc; n: PNode) =
|
proc prepareExamples(d: PDoc; n: PNode) =
|
||||||
let inp = toFullPath(d.conf, n.info)
|
var runnableExamples = newTree(nkStmtList,
|
||||||
if d.runnableExamples == nil:
|
newTree(nkImportStmt, newStrNode(nkStrLit, d.filename)))
|
||||||
d.runnableExamples = newTree(nkStmtList,
|
runnableExamples.info = n.info
|
||||||
newTree(nkImportStmt, newStrNode(nkStrLit, expandFilename(inp))))
|
|
||||||
d.runnableExamples.info = n.info
|
|
||||||
let imports = newTree(nkStmtList)
|
let imports = newTree(nkStmtList)
|
||||||
var savedLastSon = copyTree n.lastSon
|
var savedLastSon = copyTree n.lastSon
|
||||||
extractImports(savedLastSon, imports)
|
extractImports(savedLastSon, imports)
|
||||||
for imp in imports: d.runnableExamples.add imp
|
for imp in imports: runnableExamples.add imp
|
||||||
d.runnableExamples.add newTree(nkBlockStmt, newNode(nkEmpty), copyTree savedLastSon)
|
runnableExamples.add newTree(nkBlockStmt, newNode(nkEmpty), copyTree savedLastSon)
|
||||||
|
testExample(d, runnableExamples)
|
||||||
|
|
||||||
proc isRunnableExample(n: PNode): bool =
|
proc isRunnableExample(n: PNode): bool =
|
||||||
# Templates and generics don't perform symbol lookups.
|
# Templates and generics don't perform symbol lookups.
|
||||||
|
|
@ -873,7 +869,6 @@ proc commandDoc*(cache: IdentCache, conf: ConfigRef) =
|
||||||
generateDoc(d, ast)
|
generateDoc(d, ast)
|
||||||
writeOutput(d, conf.projectFull, HtmlExt)
|
writeOutput(d, conf.projectFull, HtmlExt)
|
||||||
generateIndex(d)
|
generateIndex(d)
|
||||||
testExamples(d)
|
|
||||||
|
|
||||||
proc commandRstAux(cache: IdentCache, conf: ConfigRef; filename, outExt: string) =
|
proc commandRstAux(cache: IdentCache, conf: ConfigRef; filename, outExt: string) =
|
||||||
var filen = addFileExt(filename, "txt")
|
var filen = addFileExt(filename, "txt")
|
||||||
|
|
@ -908,7 +903,6 @@ proc commandRstAux(cache: IdentCache, conf: ConfigRef; filename, outExt: string)
|
||||||
d.modDesc = rope(modDesc)
|
d.modDesc = rope(modDesc)
|
||||||
writeOutput(d, filename, outExt)
|
writeOutput(d, filename, outExt)
|
||||||
generateIndex(d)
|
generateIndex(d)
|
||||||
testExamples(d)
|
|
||||||
|
|
||||||
proc commandRst2Html*(cache: IdentCache, conf: ConfigRef) =
|
proc commandRst2Html*(cache: IdentCache, conf: ConfigRef) =
|
||||||
commandRstAux(cache, conf, conf.projectFull, HtmlExt)
|
commandRstAux(cache, conf, conf.projectFull, HtmlExt)
|
||||||
|
|
@ -932,7 +926,6 @@ proc commandJson*(cache: IdentCache, conf: ConfigRef) =
|
||||||
let filename = getOutFile(conf, conf.projectFull, JsonExt)
|
let filename = getOutFile(conf, conf.projectFull, JsonExt)
|
||||||
if not writeRope(content, filename):
|
if not writeRope(content, filename):
|
||||||
rawMessage(conf, errCannotOpenFile, filename)
|
rawMessage(conf, errCannotOpenFile, filename)
|
||||||
testExamples(d)
|
|
||||||
|
|
||||||
proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
proc commandTags*(cache: IdentCache, conf: ConfigRef) =
|
||||||
var ast = parseFile(conf.projectMainIdx, cache, conf)
|
var ast = parseFile(conf.projectMainIdx, cache, conf)
|
||||||
|
|
|
||||||
|
|
@ -21,42 +21,46 @@ type
|
||||||
module: PSym
|
module: PSym
|
||||||
PGen = ref TGen
|
PGen = ref TGen
|
||||||
|
|
||||||
|
template shouldProcess(g): bool =
|
||||||
|
(g.module.owner.id == g.doc.conf.mainPackageId and optWholeProject in g.doc.conf.globalOptions) or
|
||||||
|
sfMainModule in g.module.flags
|
||||||
|
|
||||||
template closeImpl(body: untyped) {.dirty.} =
|
template closeImpl(body: untyped) {.dirty.} =
|
||||||
var g = PGen(p)
|
var g = PGen(p)
|
||||||
let useWarning = sfMainModule notin g.module.flags
|
let useWarning = sfMainModule notin g.module.flags
|
||||||
#echo g.module.name.s, " ", g.module.owner.id, " ", gMainPackageId
|
#echo g.module.name.s, " ", g.module.owner.id, " ", gMainPackageId
|
||||||
if (g.module.owner.id == g.doc.conf.mainPackageId and optWholeProject in g.doc.conf.globalOptions) or
|
if shouldProcess(g):
|
||||||
sfMainModule in g.module.flags:
|
|
||||||
body
|
body
|
||||||
try:
|
try:
|
||||||
generateIndex(g.doc)
|
generateIndex(g.doc)
|
||||||
testExamples(g.doc)
|
|
||||||
except IOError:
|
except IOError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc close(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
proc close(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
||||||
closeImpl:
|
closeImpl:
|
||||||
writeOutput(g.doc, toFilename(graph.config, FileIndex g.module.position), HtmlExt, useWarning)
|
writeOutput(g.doc, toFullPath(graph.config, FileIndex g.module.position), HtmlExt, useWarning)
|
||||||
|
|
||||||
proc closeJson(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
proc closeJson(graph: ModuleGraph; p: PPassContext, n: PNode): PNode =
|
||||||
closeImpl:
|
closeImpl:
|
||||||
writeOutputJson(g.doc, toFilename(graph.config, FileIndex g.module.position), ".json", useWarning)
|
writeOutputJson(g.doc, toFullPath(graph.config, FileIndex g.module.position), ".json", useWarning)
|
||||||
|
|
||||||
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)
|
||||||
|
if shouldProcess(g):
|
||||||
generateDoc(g.doc, n)
|
generateDoc(g.doc, n)
|
||||||
|
|
||||||
proc processNodeJson(c: PPassContext, n: PNode): PNode =
|
proc processNodeJson(c: PPassContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
var g = PGen(c)
|
var g = PGen(c)
|
||||||
|
if shouldProcess(g):
|
||||||
generateJson(g.doc, n)
|
generateJson(g.doc, n)
|
||||||
|
|
||||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
|
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
|
||||||
var g: PGen
|
var g: PGen
|
||||||
new(g)
|
new(g)
|
||||||
g.module = module
|
g.module = module
|
||||||
var d = newDocumentor(toFilename(graph.config, FileIndex module.position), graph.cache, graph.config)
|
var d = newDocumentor(toFullPath(graph.config, FileIndex module.position), graph.cache, graph.config)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
g.doc = d
|
g.doc = d
|
||||||
result = g
|
result = g
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue