fix #13491 #17279 runnableExamples now don't get lost in translation (#17282)

* fix #13491 runnableExamples rendering
* fix a runnableExamples thanks to this bugfix
This commit is contained in:
Timothee Cour
2021-03-08 22:09:24 -08:00
committed by GitHub
parent 6cb26d8010
commit d161d27cdd
4 changed files with 70 additions and 27 deletions

View File

@@ -456,18 +456,6 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
proc exampleOutputDir(d: PDoc): AbsoluteDir = d.conf.getNimcacheDir / RelativeDir"runnableExamples"
proc writeExample(d: PDoc; ex: PNode, rdoccmd: string) =
if d.conf.errorCounter > 0: return
let outputDir = d.exampleOutputDir
createDir(outputDir)
inc d.exampleCounter
let outp = outputDir / RelativeFile(extractFilename(d.filename.changeFileExt"" &
"_examples" & $d.exampleCounter & ".nim"))
#let nimcache = outp.changeFileExt"" & "_nimcache"
renderModule(ex, d.filename, outp.string, conf = d.conf)
if rdoccmd notin d.exampleGroups: d.exampleGroups[rdoccmd] = ExampleGroup(rdoccmd: rdoccmd, docCmd: d.conf.docCmd, index: d.exampleGroups.len)
d.exampleGroups[rdoccmd].code.add "import r\"$1\"\n" % outp.string
proc runAllExamples(d: PDoc) =
# This used to be: `let backend = if isDefined(d.conf, "js"): "js"` (etc), however
# using `-d:js` (etc) cannot work properly, e.g. would fail with `importjs`
@@ -498,6 +486,8 @@ proc runAllExamples(d: PDoc) =
rawMessage(d.conf, hintSuccess, ["runnableExamples: " & outp.string])
# removeFile(outp.changeFileExt(ExeExt)) # it's in nimcache, no need to remove
proc quoted(a: string): string = result.addQuoted(a)
proc prepareExample(d: PDoc; n: PNode): tuple[rdoccmd: string, code: string] =
## returns `rdoccmd` and source code for this runnableExamples
var rdoccmd = ""
@@ -508,19 +498,48 @@ proc prepareExample(d: PDoc; n: PNode): tuple[rdoccmd: string, code: string] =
if n1.kind notin nkStrKinds: globalError(d.conf, n1.info, "string litteral expected")
rdoccmd = n1.strVal
var docComment = newTree(nkCommentStmt)
let useRenderModule = false
let loc = d.conf.toFileLineCol(n.info)
let code = extractRunnableExamplesSource(d.conf, n)
docComment.comment = "autogenerated by docgen\nloc: $1\nrdoccmd: $2" % [loc, rdoccmd]
var runnableExamples = newTree(nkStmtList,
docComment,
newTree(nkImportStmt, newStrNode(nkStrLit, d.filename)))
runnableExamples.info = n.info
let ret = extractRunnableExamplesSource(d.conf, n)
for a in n.lastSon: runnableExamples.add a
# we could also use `ret` instead here, to keep sources verbatim
writeExample(d, runnableExamples, rdoccmd)
result = (rdoccmd, ret)
if d.conf.errorCounter > 0:
return (rdoccmd, code)
let comment = "autogenerated by docgen\nloc: $1\nrdoccmd: $2" % [loc, rdoccmd]
let outputDir = d.exampleOutputDir
createDir(outputDir)
inc d.exampleCounter
let outp = outputDir / RelativeFile(extractFilename(d.filename.changeFileExt"" & ("_examples$1.nim" % $d.exampleCounter)))
if useRenderModule:
var docComment = newTree(nkCommentStmt)
docComment.comment = comment
var runnableExamples = newTree(nkStmtList,
docComment,
newTree(nkImportStmt, newStrNode(nkStrLit, d.filename)))
runnableExamples.info = n.info
for a in n.lastSon: runnableExamples.add a
# buggy, refs bug #17292
# still worth fixing as it can affect other code relying on `renderModule`,
# so we keep this code path here for now, which could still be useful in some
# other situations.
renderModule(runnableExamples, outp.string, conf = d.conf)
else:
let code2 = """
#[
$1
]#
import $2
$3
""" % [comment, d.filename.quoted, code]
writeFile(outp.string, code2)
if rdoccmd notin d.exampleGroups:
d.exampleGroups[rdoccmd] = ExampleGroup(rdoccmd: rdoccmd, docCmd: d.conf.docCmd, index: d.exampleGroups.len)
d.exampleGroups[rdoccmd].code.add "import $1\n" % outp.string.quoted
result = (rdoccmd, code)
when false:
proc extractImports(n: PNode; result: PNode) =
if n.kind in {nkImportStmt, nkImportExceptStmt, nkFromStmt}:

View File

@@ -1647,7 +1647,7 @@ proc renderTree*(n: PNode, renderFlags: TRenderFlags = {}): string =
proc `$`*(n: PNode): string = n.renderTree
proc renderModule*(n: PNode, infile, outfile: string,
proc renderModule*(n: PNode, outfile: string,
renderFlags: TRenderFlags = {};
fid = FileIndex(-1);
conf: ConfigRef = nil) =

View File

@@ -54,7 +54,6 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
macro `=>`*(p, b: untyped): untyped =
## Syntax sugar for anonymous procedures. It also supports pragmas.
# TODO: xxx pending #13491: uncomment in runnableExamples
runnableExamples:
proc passTwoAndTwo(f: (int, int) -> int): int = f(2, 2)
@@ -69,8 +68,8 @@ macro `=>`*(p, b: untyped): untyped =
myBot.call = (name: string) {.noSideEffect.} => "Hello " & name & ", I'm a bot."
assert myBot.call("John") == "Hello John, I'm a bot."
# let f = () => (discard) # simplest proc that returns void
# f()
let f = () => (discard) # simplest proc that returns void
f()
var
params = @[ident"auto"]

View File

@@ -109,6 +109,31 @@ when true: # runnableExamples with rdoccmd
# passing seq (to run with multiple compilation options)
runnableExamples(@["-b:cpp", "-b:js"]): discard
runnableExamples:
block: # bug #17279
when int.sizeof == 8:
let x = 0xffffffffffffffff
doAssert x == -1
# bug #13491
block:
proc fun(): int = doAssert false
doAssertRaises(AssertionError, (discard fun()))
block:
template foo(body) = discard
foo (discard)
block:
template fn(body: untyped): untyped = true
doAssert(fn do: nonexistant)
import std/macros
macro foo*(x, y) =
result = newLetStmt(x[0][0], x[0][1])
foo:
a = 1
do: discard
# also check for runnableExamples at module scope
runnableExamples:
block: