diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 3f237c9322..ac4ff2a77e 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -31,6 +31,10 @@ type length*: int16 sym*: PSym + Section = enum + GenericParams + ObjectDef + TRenderTokSeq* = seq[TRenderTok] TSrcGen* = object indent*: int @@ -45,7 +49,7 @@ type pendingWhitespace: int comStack*: seq[PNode] # comment stack flags*: TRenderFlags - inGenericParams: bool + inside: set[Section] # Keeps track of contexts we are in checkAnon: bool # we're in a context that can contain sfAnon inPragma: int when defined(nimpretty): @@ -73,6 +77,16 @@ proc isKeyword*(i: PIdent): bool = (i.id <= ord(tokKeywordHigh) - ord(tkSymbol)): result = true +proc isExported(n: PNode): bool = + ## Checks if an ident is exported. + ## This is meant to be used with idents in nkIdentDefs. + case n.kind + of nkPostfix: + n[0].ident.s == "*" and n[1].kind == nkIdent + of nkPragmaExpr: + n[0].isExported() + else: false + proc renderDefinitionName*(s: PSym, noQuotes = false): string = ## Returns the definition name of the symbol. ## @@ -85,6 +99,25 @@ proc renderDefinitionName*(s: PSym, noQuotes = false): string = else: result = '`' & x & '`' +template inside(g: var TSrcGen, section: Section, body: untyped) = + ## Runs `body` with `section` included in `g.inside`. + ## Removes it at the end of the body if `g` wasn't inside it + ## before the template. + let wasntInSection = section notin g.inside + g.inside.incl section + body + if wasntInSection: + g.inside.excl section + +template outside(g: var TSrcGen, section: Section, body: untyped) = + ## Temporarily removes `section` from `g.inside`. Adds it back + ## at the end of the body if `g` was inside it before the template + let wasInSection = section in g.inside + g.inside.excl section + body + if wasInSection: + g.inside.incl section + const IndentWidth = 2 longIndentWid = IndentWidth * 2 @@ -121,7 +154,7 @@ proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags; config: ConfigRef) = g.flags = renderFlags g.pendingNL = -1 g.pendingWhitespace = -1 - g.inGenericParams = false + g.inside = {} g.config = config proc addTok(g: var TSrcGen, kind: TokType, s: string; sym: PSym = nil) = @@ -831,14 +864,12 @@ proc gproc(g: var TSrcGen, n: PNode) = if n[patternPos].kind != nkEmpty: gpattern(g, n[patternPos]) - let oldInGenericParams = g.inGenericParams - g.inGenericParams = true - if renderNoBody in g.flags and n[miscPos].kind != nkEmpty and - n[miscPos][1].kind != nkEmpty: - gsub(g, n[miscPos][1]) - else: - gsub(g, n[genericParamsPos]) - g.inGenericParams = oldInGenericParams + g.inside(GenericParams): + if renderNoBody in g.flags and n[miscPos].kind != nkEmpty and + n[miscPos][1].kind != nkEmpty: + gsub(g, n[miscPos][1]) + else: + gsub(g, n[genericParamsPos]) gsub(g, n[paramsPos]) if renderNoPragmas notin g.flags: gsub(g, n[pragmasPos]) @@ -916,7 +947,7 @@ proc gasm(g: var TSrcGen, n: PNode) = gsub(g, n[1]) proc gident(g: var TSrcGen, n: PNode) = - if g.inGenericParams and n.kind == nkSym: + if GenericParams in g.inside and n.kind == nkSym: if sfAnon in n.sym.flags or (n.typ != nil and tfImplicitTypeParam in n.typ.flags): return @@ -1304,14 +1335,31 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) = gsub(g, n, pragmasPos) put(g, tkColon, ":") gsub(g, n, bodyPos) - of nkConstDef, nkIdentDefs: + of nkIdentDefs: + # Skip if this is a property in a type and its not exported + # (While also not allowing rendering of non exported fields) + if ObjectDef in g.inside and (not n[0].isExported() and renderNonExportedFields notin g.flags): + return + # We render the identDef without being inside the section incase we render something like + # y: proc (x: string) # (We wouldn't want to check if x is exported) + g.outside(ObjectDef): + gcomma(g, n, 0, -3) + if n.len >= 2 and n[^2].kind != nkEmpty: + putWithSpace(g, tkColon, ":") + 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, "=") + gsub(g, n[^1], c) + of nkConstDef: gcomma(g, n, 0, -3) if n.len >= 2 and n[^2].kind != nkEmpty: putWithSpace(g, tkColon, ":") 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) @@ -1468,20 +1516,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext, fromStmtList = false) = of nkObjectTy: if n.len > 0: putWithSpace(g, tkObject, "object") - gsub(g, n[0]) - gsub(g, n[1]) - gcoms(g) - gsub(g, n[2]) + g.inside(ObjectDef): + gsub(g, n[0]) + gsub(g, n[1]) + gcoms(g) + gsub(g, n[2]) else: put(g, tkObject, "object") of nkRecList: indentNL(g) for i in 0..
  • A
  • +
  • AnotherObject
  • B
  • +
    AnotherObject = object
    +  case x*: bool
    +  of true:
    +      y*: proc (x: string)
    +
    +  of false:
    +    
    +  
    +
    + + +
    @@ -424,7 +445,7 @@
    T19396 = object
       a*: int
    -
    +
    diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx index c29223a833..ac9bbb2ced 100644 --- a/nimdoc/testproject/expected/testproject.idx +++ b/nimdoc/testproject/expected/testproject.idx @@ -66,5 +66,6 @@ nim anything testproject.html#anything proc anything() 387 nim T19396 testproject.html#T19396 object T19396 392 nim somePragma testproject.html#somePragma.t template somePragma() 396 nim MyObject testproject.html#MyObject object MyObject 400 +nim AnotherObject testproject.html#AnotherObject object AnotherObject 405 nimgrp bar testproject.html#bar-procs-all proc 31 nimgrp baz testproject.html#baz-procs-all proc 34 diff --git a/nimdoc/testproject/expected/theindex.html b/nimdoc/testproject/expected/theindex.html index 24e3cff1c9..70916f7e0c 100644 --- a/nimdoc/testproject/expected/theindex.html +++ b/nimdoc/testproject/expected/theindex.html @@ -52,6 +52,10 @@
  • utils: template aEnum(): untyped
  • +
    AnotherObject:
    anything:
    • testproject: proc anything()
    • diff --git a/nimdoc/testproject/testproject.nim b/nimdoc/testproject/testproject.nim index d08a12544f..d2d3fef3fd 100644 --- a/nimdoc/testproject/testproject.nim +++ b/nimdoc/testproject/testproject.nim @@ -400,3 +400,11 @@ type # bug #21483 MyObject* = object someString*: string ## This is a string annotated* {.somePragma.}: string ## This is an annotated string + +type + AnotherObject* = object + case x*: bool + of true: + y*: proc (x: string) + of false: + hidden: string