merged better html links #850
This commit is contained in:
parent
831a8c8db4
commit
3e25d5f247
13 changed files with 559 additions and 56 deletions
113
compiler/typesrenderer.nim
Normal file
113
compiler/typesrenderer.nim
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import renderer, strutils, ast, msgs, types
|
||||
|
||||
const defaultParamSeparator* = ","
|
||||
|
||||
proc renderPlainSymbolName*(n: PNode): string =
|
||||
## Returns the first non '*' nkIdent node from the tree.
|
||||
##
|
||||
## Use this on documentation name nodes to extract the *raw* symbol name,
|
||||
## without decorations, parameters, or anything. That can be used as the base
|
||||
## for the HTML hyperlinks.
|
||||
result = ""
|
||||
case n.kind
|
||||
of nkPostfix:
|
||||
for i in 0 .. <n.len:
|
||||
result = renderPlainSymbolName(n[<n.len])
|
||||
if result.len > 0:
|
||||
return
|
||||
of nkIdent:
|
||||
if n.ident.s != "*":
|
||||
result = n.ident.s
|
||||
of nkSym:
|
||||
result = n.sym.renderDefinitionName(noQuotes = true)
|
||||
of nkPragmaExpr:
|
||||
result = renderPlainSymbolName(n[0])
|
||||
of nkAccQuoted:
|
||||
result = renderPlainSymbolName(n[<n.len])
|
||||
else:
|
||||
internalError(n.info, "renderPlainSymbolName() with " & $n.kind)
|
||||
assert (not result.isNil)
|
||||
|
||||
proc renderType(n: PNode): string =
|
||||
## Returns a string with the node type or the empty string.
|
||||
case n.kind:
|
||||
of nkIdent: result = n.ident.s
|
||||
of nkSym: result = typeToString(n.sym.typ)
|
||||
of nkVarTy:
|
||||
assert len(n) == 1
|
||||
result = renderType(n[0])
|
||||
of nkRefTy:
|
||||
assert len(n) == 1
|
||||
result = "ref." & renderType(n[0])
|
||||
of nkPtrTy:
|
||||
assert len(n) == 1
|
||||
result = "ptr." & renderType(n[0])
|
||||
of nkProcTy:
|
||||
assert len(n) > 1
|
||||
let params = n[0]
|
||||
assert params.kind == nkFormalParams
|
||||
assert len(params) > 0
|
||||
result = "proc("
|
||||
for i in 1 .. <len(params): result.add(renderType(params[i]) & ',')
|
||||
result[<len(result)] = ')'
|
||||
of nkIdentDefs:
|
||||
assert len(n) >= 3
|
||||
let typePos = len(n) - 2
|
||||
let typeStr = renderType(n[typePos])
|
||||
result = typeStr
|
||||
for i in 1 .. <typePos:
|
||||
assert n[i].kind == nkIdent
|
||||
result.add(',' & typeStr)
|
||||
of nkTupleTy:
|
||||
assert len(n) > 0
|
||||
result = "tuple["
|
||||
for i in 0 .. <len(n): result.add(renderType(n[i]) & ',')
|
||||
result[<len(result)] = ']'
|
||||
of nkBracketExpr:
|
||||
assert len(n) >= 2
|
||||
result = renderType(n[0]) & '['
|
||||
for i in 1 .. <len(n): result.add(renderType(n[i]) & ',')
|
||||
result[<len(result)] = ']'
|
||||
else: result = ""
|
||||
assert (not result.isNil)
|
||||
|
||||
|
||||
proc renderParamTypes(found: var seq[string], n: PNode) =
|
||||
## Recursive helper, adds to `found` any types, or keeps diving the AST.
|
||||
##
|
||||
## The normal `doc` generator doesn't include .typ information, so the
|
||||
## function won't render types for parameters with default values. The `doc2`
|
||||
## generator does include the information.
|
||||
case n.kind
|
||||
of nkFormalParams:
|
||||
for i in 1 .. <len(n): renderParamTypes(found, n[i])
|
||||
of nkIdentDefs:
|
||||
# These are parameter names + type + default value node.
|
||||
let typePos = len(n) - 2
|
||||
assert typePos > 0
|
||||
var typeStr = renderType(n[typePos])
|
||||
if typeStr.len < 1:
|
||||
# Try with the last node, maybe its a default value.
|
||||
assert n[typePos+1].kind != nkEmpty
|
||||
let typ = n[typePos+1].typ
|
||||
if not typ.isNil: typeStr = typeToString(typ, preferExported)
|
||||
if typeStr.len < 1:
|
||||
return
|
||||
for i in 0 .. <typePos:
|
||||
assert n[i].kind == nkIdent
|
||||
found.add(typeStr)
|
||||
else:
|
||||
internalError(n.info, "renderParamTypes(found,n) with " & $n.kind)
|
||||
|
||||
proc renderParamTypes*(n: PNode, sep = defaultParamSeparator): string =
|
||||
## Returns the types contained in `n` joined by `sep`.
|
||||
##
|
||||
## This proc expects to be passed as `n` the parameters of any callable. The
|
||||
## string output is meant for the HTML renderer. If there are no parameters,
|
||||
## the empty string is returned. The parameters will be joined by `sep` but
|
||||
## other characters may appear too, like ``[]`` or ``|``.
|
||||
result = ""
|
||||
var found: seq[string] = @[]
|
||||
renderParamTypes(found, n)
|
||||
if found.len > 0:
|
||||
result = found.join(sep)
|
||||
Loading…
Add table
Add a link
Reference in a new issue