diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 0a24d2e095..fc37bd596e 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 15b712d0d8..ad74cf2fe4 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 4caff7ec77..b68b721ff0 100644 --- a/nimdoc/testproject/expected/testproject.html +++ b/nimdoc/testproject/expected/testproject.html @@ -116,7 +116,8 @@
proc bar[T](a, b: T): T