diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2020-07-01 00:26:23 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-01 09:26:23 +0200 |
commit | 2867a33ebcaddccdb52b101d0ea5f75f1d4bd66f (patch) | |
tree | a00dc63b69e03065bb88d1b246d6c8f9ebc12f50 | |
parent | 05384efec53256d8917a80d1117d8f822a8a2f55 (diff) | |
download | Nim-2867a33ebcaddccdb52b101d0ea5f75f1d4bd66f.tar.gz |
fix #14846; add macros.extractDocCommentsAndRunnables (#14849)
* fix #14846; add macros.extractDocCommentsAndRunnables * fixup * update tests * address comment
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | lib/core/macros.nim | 36 | ||||
-rw-r--r-- | lib/pure/asyncmacro.nim | 6 | ||||
-rw-r--r-- | nimdoc/testproject/expected/testproject.html | 29 | ||||
-rw-r--r-- | nimdoc/testproject/expected/testproject.idx | 3 | ||||
-rw-r--r-- | nimdoc/testproject/expected/theindex.html | 12 | ||||
-rw-r--r-- | nimdoc/testproject/testproject.nim | 14 |
7 files changed, 98 insertions, 3 deletions
diff --git a/changelog.md b/changelog.md index f32d6f19f..287bce3da 100644 --- a/changelog.md +++ b/changelog.md @@ -116,6 +116,7 @@ - Add `random.gauss`, that uses the ratio of uniforms method of sampling from a Gaussian distribution. - Add `typetraits.elementType` to get element type of an iterable. - `typetraits.$`: `$(int,)` is now `"(int,)"`; `$tuple[]` is now `"tuple[]"` +- add `macros.extractDocCommentsAndRunnables` helper - `strformat.fmt` and `strformat.&` support `= specifier`. `fmt"{expr=}"` now expands to `fmt"expr={expr}"`. diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 5be3a2cce..838707280 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1692,3 +1692,39 @@ when defined(nimMacrosSizealignof): proc isExported*(n: NimNode): bool {.noSideEffect.} = ## Returns whether the symbol is exported or not. + +proc extractDocCommentsAndRunnables*(n: NimNode): NimNode = + ## returns a `nnkStmtList` containing the top-level doc comments and + ## runnableExamples in `a`, stopping at the first child that is neither. + ## Example: + ## + ## .. code-block:: nim + ## import macros + ## macro transf(a): untyped = + ## result = quote do: + ## proc fun2*() = discard + ## let header = extractDocCommentsAndRunnables(a.body) + ## # correct usage: rest is appended + ## result.body = header + ## result.body.add quote do: discard # just an example + ## # incorrect usage: nesting inside a nnkStmtList: + ## # result.body = quote do: (`header`; discard) + ## + ## proc fun*() {.transf.} = + ## ## first comment + ## runnableExamples: discard + ## runnableExamples: discard + ## ## last comment + ## discard # first statement after doc comments + runnableExamples + ## ## not docgen'd + + result = newStmtList() + for ni in n: + case ni.kind + of nnkCommentStmt: + result.add ni + of nnkCall: + if ni[0].kind == nnkIdent and ni[0].strVal == "runnableExamples": + result.add ni + else: break + else: break diff --git a/lib/pure/asyncmacro.nim b/lib/pure/asyncmacro.nim index 621a4b00c..219ef6c67 100644 --- a/lib/pure/asyncmacro.nim +++ b/lib/pure/asyncmacro.nim @@ -180,8 +180,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} = # Extract the documentation comment from the original procedure declaration. # Note that we're not removing it from the body in order not to make this # transformation even more complex. - if prc.body.len > 1 and prc.body[0].kind == nnkCommentStmt: - outerProcBody.add(prc.body[0]) + let body2 = extractDocCommentsAndRunnables(prc.body) # -> var retFuture = newFuture[T]() var retFutureSym = genSym(nskVar, "retFuture") @@ -276,9 +275,10 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} = (cast[type(f)](internalTmpFuture)).read() if procBody.kind != nnkEmpty: - result.body = quote: + body2.add quote do: `awaitDefinition` `outerProcBody` + result.body = body2 #echo(treeRepr(result)) #if prcName == "recvLineInto": diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index a4f8876fd..648ecb629 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -200,6 +200,12 @@ function main() { title="low2[T: Ordinal | enum | range](x: T): T"><wbr />low2<span class="attachedType"></span></a></li> <li><a class="reference" href="#tripleStrLitTest" title="tripleStrLitTest()"><wbr />triple<wbr />Str<wbr />Lit<wbr />Test<span class="attachedType"></span></a></li> + <li><a class="reference" href="#asyncFun1" + title="asyncFun1(): Future[int]"><wbr />async<wbr />Fun1<span class="attachedType"></span></a></li> + <li><a class="reference" href="#asyncFun2" + title="asyncFun2(): owned(Future[void])"><wbr />async<wbr />Fun2<span class="attachedType"></span></a></li> + <li><a class="reference" href="#asyncFun3" + title="asyncFun3(): owned(Future[void])"><wbr />async<wbr />Fun3<span class="attachedType"></span></a></li> </ul> </li> @@ -656,6 +662,29 @@ at indent 0 </span><span class="Comment"># should be in</span></pre> </dd> +<a id="asyncFun1"></a> +<dt><pre><span class="Keyword">proc</span> <a href="#asyncFun1"><span class="Identifier">asyncFun1</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Future</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">Exception</span><span class="Other">,</span> <span class="Identifier">ValueError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt> +<dd> + +ok1 + +</dd> +<a id="asyncFun2"></a> +<dt><pre><span class="Keyword">proc</span> <a href="#asyncFun2"><span class="Identifier">asyncFun2</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">owned</span><span class="Other">(</span><span class="Identifier">Future</span><span class="Other">[</span><span class="Identifier">void</span><span class="Other">]</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">Exception</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt> +<dd> + + + +</dd> +<a id="asyncFun3"></a> +<dt><pre><span class="Keyword">proc</span> <a href="#asyncFun3"><span class="Identifier">asyncFun3</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">owned</span><span class="Other">(</span><span class="Identifier">Future</span><span class="Other">[</span><span class="Identifier">void</span><span class="Other">]</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">Exception</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt> +<dd> + + +<p><strong class="examples_text">Example:</strong></p> +<pre class="listing"><span class="Keyword">discard</span></pre>ok1 + +</dd> </dl></div> <div class="section" id="13"> diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx index 6d0bc6c5e..0b75b29d2 100644 --- a/nimdoc/testproject/expected/testproject.idx +++ b/nimdoc/testproject/expected/testproject.idx @@ -50,4 +50,7 @@ foo testproject.html#foo.t,SomeType,SomeType testproject: foo(a, b: SomeType) myfn testproject.html#myfn.t testproject: myfn() z14 testproject.html#z14.t testproject: z14() z15 testproject.html#z15.t testproject: z15() +asyncFun1 testproject.html#asyncFun1 testproject: asyncFun1(): Future[int] +asyncFun2 testproject.html#asyncFun2 testproject: asyncFun2(): owned(Future[void]) +asyncFun3 testproject.html#asyncFun3 testproject: asyncFun3(): owned(Future[void]) testNimDocTrailingExample testproject.html#testNimDocTrailingExample.t testproject: testNimDocTrailingExample() diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index 8d34506a6..0b835c409 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -85,6 +85,18 @@ function main() { <li><a class="reference external" data-doc-search-tag="utils: aEnum(): untyped" href="subdir/subdir_b/utils.html#aEnum.t">utils: aEnum(): untyped</a></li> </ul></dd> +<dt><a name="asyncFun1" href="#asyncFun1"><span>asyncFun1:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="testproject: asyncFun1(): Future[int]" href="testproject.html#asyncFun1">testproject: asyncFun1(): Future[int]</a></li> + </ul></dd> +<dt><a name="asyncFun2" href="#asyncFun2"><span>asyncFun2:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="testproject: asyncFun2(): owned(Future[void])" href="testproject.html#asyncFun2">testproject: asyncFun2(): owned(Future[void])</a></li> + </ul></dd> +<dt><a name="asyncFun3" href="#asyncFun3"><span>asyncFun3:</span></a></dt><dd><ul class="simple"> +<li><a class="reference external" + data-doc-search-tag="testproject: asyncFun3(): owned(Future[void])" href="testproject.html#asyncFun3">testproject: asyncFun3(): owned(Future[void])</a></li> + </ul></dd> <dt><a name="aVariable" href="#aVariable"><span>aVariable:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" data-doc-search-tag="testproject: aVariable" href="testproject.html#aVariable">testproject: aVariable</a></li> diff --git a/nimdoc/testproject/testproject.nim b/nimdoc/testproject/testproject.nim index 5282c6f77..25cdf39a4 100644 --- a/nimdoc/testproject/testproject.nim +++ b/nimdoc/testproject/testproject.nim @@ -343,6 +343,20 @@ when true: # issue #14473 toSeq([1,2]) echo doit() # using doAssert or similar to avoid echo would "hide" the original bug +when true: # issue #14846 + import asyncdispatch + proc asyncFun1*(): Future[int] {.async.} = + ## ok1 + result = 1 + proc asyncFun2*() {.async.} = discard + proc asyncFun3*() {.async.} = + runnableExamples: + discard + ## ok1 + discard + ## should be out + discard + when true: template testNimDocTrailingExample*() = # this must be last entry in this file, it checks against a bug (that got fixed) |