summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/renderer.nim95
-rw-r--r--nimdoc/testproject/expected/testproject.html23
-rw-r--r--nimdoc/testproject/expected/testproject.idx1
-rw-r--r--nimdoc/testproject/expected/theindex.html4
-rw-r--r--nimdoc/testproject/testproject.nim8
5 files changed, 106 insertions, 25 deletions
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 3f237c932..ac4ff2a77 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..<n.len:
-      if n[i].kind == nkIdentDefs and n[i][0].skipPragmaExpr.kind == nkPostfix or
-                        renderNonExportedFields in g.flags:
-        optNL(g)
-        gsub(g, n[i], c)
-        gcoms(g)
+      optNL(g)
+      gsub(g, n[i], c)
+      gcoms(g)
     dedent(g)
     putNL(g)
   of nkOfInherit:
diff --git a/nimdoc/testproject/expected/testproject.html b/nimdoc/testproject/expected/testproject.html
index a5c9b6af2..78a730e59 100644
--- a/nimdoc/testproject/expected/testproject.html
+++ b/nimdoc/testproject/expected/testproject.html
@@ -56,6 +56,12 @@
     <ul class="simple simple-toc-section">
       <li><a class="reference" href="#A" title="A {.inject.} = enum
   aA">A</a></li>
+<li><a class="reference" href="#AnotherObject" title="AnotherObject = object
+  case x*: bool
+  of true:
+      y*: proc (x: string)
+
+  of false:">AnotherObject</a></li>
 <li><a class="reference" href="#B" title="B {.inject.} = enum
   bB">B</a></li>
 <li><a class="reference" href="#Foo" title="Foo = enum
@@ -370,6 +376,21 @@
     
   </dd>
 </div>
+<div id="AnotherObject">
+  <dt><pre><a href="testproject.html#AnotherObject"><span class="Identifier">AnotherObject</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Keyword">case</span> <span class="Identifier">x</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+  <span class="Keyword">of</span> <span class="Identifier">true</span><span class="Other">:</span>
+      <span class="Identifier">y</span><span class="Operator">*</span><span class="Other">:</span> <span class="Keyword">proc</span> <span class="Other">(</span><span class="Identifier">x</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span>
+
+  <span class="Keyword">of</span> <span class="Identifier">false</span><span class="Other">:</span>
+    
+  </pre></dt>
+  <dd>
+    
+    
+    
+  </dd>
+</div>
 <div id="B">
   <dt><pre><a href="testproject.html#B"><span class="Identifier">B</span></a> {.<span class="Identifier">inject</span>.} <span class="Other">=</span> <span class="Keyword">enum</span>
   <span class="Identifier">bB</span></pre></dt>
@@ -424,7 +445,7 @@
 <div id="T19396">
   <dt><pre><a href="testproject.html#T19396"><span class="Identifier">T19396</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
   <span class="Identifier">a</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int</span>
-</pre></dt>
+  </pre></dt>
   <dd>
     
     
diff --git a/nimdoc/testproject/expected/testproject.idx b/nimdoc/testproject/expected/testproject.idx
index c29223a83..ac9bbb2ce 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 24e3cff1c..70916f7e0 100644
--- a/nimdoc/testproject/expected/theindex.html
+++ b/nimdoc/testproject/expected/theindex.html
@@ -52,6 +52,10 @@
 <li><a class="reference external"
           data-doc-search-tag="utils: template aEnum(): untyped" href="subdir/subdir_b/utils.html#aEnum.t">utils: template aEnum(): untyped</a></li>
           </ul></dd>
+<dt><a name="AnotherObject" href="#AnotherObject"><span>AnotherObject:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="testproject: object AnotherObject" href="testproject.html#AnotherObject">testproject: object AnotherObject</a></li>
+          </ul></dd>
 <dt><a name="anything" href="#anything"><span>anything:</span></a></dt><dd><ul class="simple">
 <li><a class="reference external"
           data-doc-search-tag="testproject: proc anything()" href="testproject.html#anything">testproject: proc anything()</a></li>
diff --git a/nimdoc/testproject/testproject.nim b/nimdoc/testproject/testproject.nim
index d08a12544..d2d3fef3f 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