diff options
-rw-r--r-- | compiler/docgen.nim | 65 | ||||
-rw-r--r-- | compiler/renderer.nim | 2 | ||||
-rw-r--r-- | lib/pure/sugar.nim | 5 | ||||
-rw-r--r-- | tests/nimdoc/trunnableexamples.nim | 25 |
4 files changed, 70 insertions, 27 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim index b09d08e6d..e902705fc 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -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) + + if d.conf.errorCounter > 0: + return (rdoccmd, code) - 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) + 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}: diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 7c11b8225..ed1c52bb7 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -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) = diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index aa1cc5fb8..9654a0678 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -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"] diff --git a/tests/nimdoc/trunnableexamples.nim b/tests/nimdoc/trunnableexamples.nim index 9e56e9143..2de1862bd 100644 --- a/tests/nimdoc/trunnableexamples.nim +++ b/tests/nimdoc/trunnableexamples.nim @@ -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: |