diff options
author | Jake Leahy <jake@leahy.dev> | 2022-12-12 17:44:17 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-12 07:44:17 +0100 |
commit | cbeefc877cd752cd2e19a82fe3aa2914912f3182 (patch) | |
tree | 6cd20d98ddb88382d8e673bfa7c354ea16e04e60 | |
parent | b981f3eeb73bc2a8e068cf7dc7cf54c4362bf19e (diff) | |
download | Nim-cbeefc877cd752cd2e19a82fe3aa2914912f3182.tar.gz |
Docs expand `using` parameters (#21076)
* Trying to fix by changing renderer * add renderExpandUsing flag This flag makes the renderer expand parameters that use using statement to have their full type * Update docs * Make comment better explain why checking for nkSym * Fix nil access when macro/template has parameter with no type * Fix nil access when node is not semmed yet
-rw-r--r-- | compiler/docgen.nim | 8 | ||||
-rw-r--r-- | compiler/renderer.nim | 33 | ||||
-rw-r--r-- | nimdoc/testproject/expected/testproject.html | 13 | ||||
-rw-r--r-- | nimdoc/testproject/expected/testproject.idx | 1 | ||||
-rw-r--r-- | nimdoc/testproject/expected/theindex.html | 2 | ||||
-rw-r--r-- | nimdoc/testproject/testproject.nim | 5 |
6 files changed, 52 insertions, 10 deletions
diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 0a24d2e09..fc37bd596 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -962,7 +962,7 @@ proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol = var literal = "" var r: TSrcGen initTokRender(r, genNode, {renderNoBody, renderNoComments, - renderNoPragmas, renderNoProcDefs}) + renderNoPragmas, renderNoProcDefs, renderExpandUsing}) var kind = tkEof while true: getNextTok(r, kind, literal) @@ -995,7 +995,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = var r: TSrcGen # Obtain the plain rendered string for hyperlink titles. initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments, - renderNoPragmas, renderNoProcDefs}) + renderNoPragmas, renderNoProcDefs, renderExpandUsing}) while true: getNextTok(r, kind, literal) if kind == tkEof: @@ -1028,7 +1028,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind, docFlags: DocFlags) = rstLangSymbol, priority = symbolPriority(k), info = lineinfo) nodeToHighlightedHtml(d, n, result, {renderNoBody, renderNoComments, - renderDocComments, renderSyms}, symbolOrIdEnc) + renderDocComments, renderSyms, renderExpandUsing}, symbolOrIdEnc) let seeSrc = genSeeSrc(d, toFullPath(d.conf, n.info), n.info.line.int) @@ -1094,7 +1094,7 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind): JsonItem = name = getName(d, nameNode) comm = genRecComment(d, n) r: TSrcGen - initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments}) + initTokRender(r, n, {renderNoBody, renderNoComments, renderDocComments, renderExpandUsing}) result.json = %{ "name": %name, "type": %($k), "line": %n.info.line.int, "col": %n.info.col} if comm != nil: diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 15b712d0d..ad74cf2fe 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -24,7 +24,7 @@ type TRenderFlag* = enum renderNone, renderNoBody, renderNoComments, renderDocComments, renderNoPragmas, renderIds, renderNoProcDefs, renderSyms, renderRunnableExamples, - renderIr + renderIr, renderExpandUsing TRenderFlags* = set[TRenderFlag] TRenderTok* = object kind*: TokType @@ -434,6 +434,24 @@ proc lsons(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = result = 0 for i in start..n.len + theEnd: inc(result, lsub(g, n[i])) +proc origUsingType(n: PNode): PSym {.inline.} = + ## Returns the type that a parameter references. Check with referencesUsing first + ## to check `n` is actually referencing a using node + # If the node is untyped the typ field will be nil + if n[0].sym.typ != nil: + n[0].sym.typ.sym + else: nil + +proc referencesUsing(n: PNode): bool = + ## Returns true if n references a using statement. + ## e.g. proc foo(x) # x doesn't have type or def value so it references a using + result = n.kind == nkIdentDefs and + # Sometimes the node might not have been semmed (e.g. doc0) and will be nkIdent instead + n[0].kind == nkSym and + # Templates/macros can have parameters with no type (But their orig type will be nil) + n.origUsingType != nil and + n[1].kind == nkEmpty and n[2].kind == nkEmpty + proc lsub(g: TSrcGen; n: PNode): int = # computes the length of a tree if isNil(n): return 0 @@ -474,8 +492,11 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkDo: result = lsons(g, n) + len("do__:_") of nkConstDef, nkIdentDefs: result = lcomma(g, n, 0, - 3) - if n[^2].kind != nkEmpty: result += lsub(g, n[^2]) + 2 - if n[^1].kind != nkEmpty: result += lsub(g, n[^1]) + 3 + if n.referencesUsing: + result += lsub(g, newSymNode(n.origUsingType)) + 2 + else: + if n[^2].kind != nkEmpty: result += lsub(g, n[^2]) + 2 + if n[^1].kind != nkEmpty: result += lsub(g, n[^1]) + 3 of nkVarTuple: if n[^1].kind == nkEmpty: result = lcomma(g, n, 0, - 2) + len("()") @@ -1284,7 +1305,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) = gcomma(g, n, 0, -3) if n.len >= 2 and n[^2].kind != nkEmpty: putWithSpace(g, tkColon, ":") - gsub(g, n, n.len - 2) + gsub(g, n[^2], c) + elif n.referencesUsing and renderExpandUsing in g.flags: + putWithSpace(g, tkColon, ":") + gsub(g, newSymNode(n.origUsingType), c) + if n.len >= 1 and n[^1].kind != nkEmpty: put(g, tkSpaces, Space) putWithSpace(g, tkEquals, "=") diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html index 4caff7ec7..b68b721ff 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -116,7 +116,8 @@ </ul> <ul class="simple nested-toc-section">bar - <li><a class="reference" href="#bar%2CT%2CT" title="bar[T](a, b: T): T">bar[T](a, b: T): T</a></li> + <li><a class="reference" href="#bar" title="bar(f: FooBuzz)">bar(f: FooBuzz)</a></li> +<li><a class="reference" href="#bar%2CT%2CT" title="bar[T](a, b: T): T">bar[T](a, b: T): T</a></li> </ul> <ul class="simple nested-toc-section">baz @@ -539,7 +540,15 @@ </div> <div id="bar-procs-all"> - <div id="bar,T,T"> + <div id="bar"> + <dt><pre><span class="Keyword">proc</span> <a href="#bar"><span class="Identifier">bar</span></a><span class="Other">(</span><span class="Identifier">f</span><span class="Other">:</span> <a href="testproject.html#FooBuzz"><span class="Identifier">FooBuzz</span></a><span class="Other">)</span> {.<span><span class="Other pragmadots">...</span></span><span class="pragmawrap"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">forbids</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span>.}</pre></dt> + <dd> + + + + </dd> +</div> +<div id="bar,T,T"> <dt><pre><span class="Keyword">proc</span> <a href="#bar%2CT%2CT"><span class="Identifier">bar</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <span class="Identifier">T</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt> <dd> diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx index 4d0e63c0c..4d0172313 100644 --- a/nimdoc/testproject/expected/testproject.idx +++ b/nimdoc/testproject/expected/testproject.idx @@ -7,6 +7,7 @@ bar testproject.html#bar,T,T testproject: bar[T](a, b: T): T baz testproject.html#baz,T,T testproject: baz[T](a, b: T): T buzz testproject.html#buzz,T,T testproject: buzz[T](a, b: T): T FooBuzz testproject.html#FooBuzz testproject: FooBuzz +bar testproject.html#bar testproject: bar(f: FooBuzz) aVariable testproject.html#aVariable testproject: aVariable A testproject.html#A testproject: A B testproject.html#B testproject: B diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index 402541540..9f73040f2 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -78,6 +78,8 @@ </ul></dd> <dt><a name="bar" href="#bar"><span>bar:</span></a></dt><dd><ul class="simple"> <li><a class="reference external" + data-doc-search-tag="testproject: bar(f: FooBuzz)" href="testproject.html#bar">testproject: bar(f: FooBuzz)</a></li> + <li><a class="reference external" data-doc-search-tag="testproject: bar[T](a, b: T): T" href="testproject.html#bar%2CT%2CT">testproject: bar[T](a, b: T): T</a></li> <li><a class="reference external" data-doc-search-tag="testproject: bar(): untyped" href="testproject.html#bar.m">testproject: bar(): untyped</a></li> diff --git a/nimdoc/testproject/testproject.nim b/nimdoc/testproject/testproject.nim index 57960c69f..d236552ac 100644 --- a/nimdoc/testproject/testproject.nim +++ b/nimdoc/testproject/testproject.nim @@ -42,6 +42,11 @@ proc buzz*[T](a, b: T): T {.deprecated: "since v0.20".} = type FooBuzz* {.deprecated: "FooBuzz msg".} = int +using f: FooBuzz + +proc bar*(f) = # `f` should be expanded to `f: FooBuzz` + discard + import std/macros var aVariable*: array[1, int] |