Skip to content

Commit

Permalink
Merge pull request #1746 from 9rnsr/fix_ddoc
Browse files Browse the repository at this point in the history
Issue 9713 & 9714 - Ddoc bug fixes
  • Loading branch information
AndrejMitrovic committed Mar 20, 2013
2 parents 4ba8a61 + a85ad54 commit d736fbf
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 112 deletions.
1 change: 1 addition & 0 deletions src/declaration.h
Expand Up @@ -887,6 +887,7 @@ struct UnitTestDeclaration : FuncDeclaration
int isVirtual();
int addPreInvariant();
int addPostInvariant();
void emitComment(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);

UnitTestDeclaration *isUnitTestDeclaration() { return this; }
Expand Down
141 changes: 51 additions & 90 deletions src/doc.c
Expand Up @@ -477,6 +477,49 @@ void escapeStrayParenthesis(OutBuffer *buf, size_t start, Loc loc)

/******************************* emitComment **********************************/

/** Get leading indentation from 'src' which represents lines of code. */
static size_t getCodeIndent(const char *src)
{
while (src && *src == '\n')
++src; // skip until we find the first non-empty line

size_t codeIndent = 0;
while (src && (*src == ' ' || *src == '\t'))
{
codeIndent++;
src++;
}
return codeIndent;
}

void emitUnittestComment(Scope *sc, Dsymbol *s, size_t ofs)
{
OutBuffer *buf = sc->docbuf;

for (UnitTestDeclaration *utd = s->unittest; utd; utd = utd->unittest)
{
if (utd->protection == PROTprivate || !utd->comment || !utd->fbody || !utd->codedoc)
continue;

// Strip whitespaces to avoid showing empty summary
unsigned char *c = utd->comment;
while (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r') ++c;

OutBuffer codebuf;
codebuf.writestring("$(DDOC_EXAMPLES \n");
size_t o = codebuf.offset;
codebuf.writestring((char *)c);
size_t i = getCodeIndent(utd->codedoc);
while (i--) codebuf.writeByte(' ');
codebuf.writestring("----\n");
codebuf.writestring(utd->codedoc);
codebuf.writestring("----\n");
highlightText(sc, s, &codebuf, o);
codebuf.writestring(")");
buf->insert(buf->offset - ofs, codebuf.data, codebuf.offset);
}
}

/*
* Emit doc comment to documentation file
*/
Expand Down Expand Up @@ -507,95 +550,12 @@ void Dsymbol::emitDitto(Scope *sc)
buf->spread(sc->lastoffset, b.offset);
memcpy(buf->data + sc->lastoffset, b.data, b.offset);
sc->lastoffset += b.offset;
}

/** Remove leading indentation from 'src' which represents lines of code. */
static const char *unindent(const char *src)
{
OutBuffer codebuf;
codebuf.writestring(src);
codebuf.writebyte(0);

while (src && *src == '\n')
++src; // skip until we find the first non-empty line

size_t codeIndent = 0;
while (src && ((*src == ' ') || (*src == '\t')))
{
codeIndent++;
src++;
}

bool lineStart = true;
unsigned char *endp = codebuf.data + codebuf.offset;
for (unsigned char *p = codebuf.data; p < endp; )
{
if (lineStart)
{
size_t j = codeIndent;
unsigned char *q = p;
while (j-- > 0 && q < endp && ((*q == ' ') || (*q == '\t')))
++q;
codebuf.remove(p - codebuf.data, q - p);
assert(codebuf.data <= p);
assert(p < codebuf.data + codebuf.offset);
lineStart = false;
endp = codebuf.data + codebuf.offset; // update
continue;
}
if (*p == '\n')
lineStart = true;
++p;
}

codebuf.writebyte(0);
return codebuf.extractData();
}

/** Return true if entire string is made out of whitespace. */
static bool isAllWhitespace(const char *src)
{
for (const char *c = src; *c && *c != '\0'; c++)
{
switch (*c)
{
case ' ':
case '\t':
case '\n':
case '\r':
continue;

default: return false;
}
}

return true;
}

void emitUnittestComment(Scope *sc, Dsymbol *s, UnitTestDeclaration *test)
{
static char pre[] = "$(D_CODE \n";
OutBuffer *buf = sc->docbuf;

for (UnitTestDeclaration *utd = test; utd; utd = utd->unittest)
{
if (utd->protection == PROTprivate || !utd->comment || !utd->fbody)
continue;

OutBuffer codebuf;
if (utd->codedoc && strlen(utd->codedoc) && !isAllWhitespace(utd->codedoc))
{
buf->writestring("$(DDOC_EXAMPLES ");
buf->writestring((char *)utd->comment);
codebuf.writestring(pre);
codebuf.writestring(unindent(utd->codedoc));
codebuf.writestring(")");
codebuf.writeByte(0);
highlightCode2(sc, s, &codebuf, 0);
buf->writestring(codebuf.toChars());
buf->writestring(")");
}
}
Dsymbol *s = this;
if (!s->unittest && parent)
s = parent->isTemplateDeclaration();
if (s)
emitUnittestComment(sc, s, strlen(ddoc_decl_dd_e));
}

void ScopeDsymbol::emitMemberComments(Scope *sc)
Expand Down Expand Up @@ -649,6 +609,7 @@ void emitProtection(OutBuffer *buf, PROT prot)

void Dsymbol::emitComment(Scope *sc) { }
void InvariantDeclaration::emitComment(Scope *sc) { }
void UnitTestDeclaration::emitComment(Scope *sc) { }
#if DMDV2
void PostBlitDeclaration::emitComment(Scope *sc) { }
#endif
Expand Down Expand Up @@ -1374,7 +1335,7 @@ void DocComment::parseSections(unsigned char *comment)
void DocComment::writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf)
{
//printf("DocComment::writeSections()\n");
if (sections.dim)
if (sections.dim || s->unittest)
{
buf->writestring("$(DDOC_SECTIONS \n");
for (size_t i = 0; i < sections.dim; i++)
Expand All @@ -1396,7 +1357,7 @@ void DocComment::writeSections(Scope *sc, Dsymbol *s, OutBuffer *buf)
}
}
if (s->unittest)
emitUnittestComment(sc, s, s->unittest);
emitUnittestComment(sc, s, 0);
buf->writestring(")\n");
}
else
Expand Down
18 changes: 15 additions & 3 deletions src/parse.c
Expand Up @@ -1331,9 +1331,21 @@ UnitTestDeclaration *Parser::parseUnitTest()
char *docline = NULL;
if (global.params.doDocComments && endPtr > begPtr)
{
docline = (char *)mem.malloc((endPtr - begPtr) + 1);
memcpy(docline, begPtr, endPtr - begPtr);
docline[endPtr - begPtr] = 0;
/* Remove trailing whitespaces */
for (unsigned char *p = endPtr - 1;
begPtr <= p && (*p == ' ' || *p == '\n' || *p == '\t'); --p)
{
endPtr = p;
}

size_t len = endPtr - begPtr;
if (len > 0)
{
docline = (char *)mem.malloc(len + 2);
memcpy(docline, begPtr, len);
docline[len ] = '\n'; // Terminate all lines by LF
docline[len+1] = '\0';
}
}

f = new UnitTestDeclaration(loc, this->loc, docline);
Expand Down
49 changes: 48 additions & 1 deletion test/compilable/ddoc2630.d
@@ -1,4 +1,4 @@
// PERMUTE_ARGS:
// PERMUTE_ARGS: -unittest
// REQUIRED_ARGS: -D -w -o- -c -Ddtest_results/compilable -o-
// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh 2630

Expand Down Expand Up @@ -171,5 +171,52 @@ unittest
foo(4);
}

// ------------------------------------

/// test for bugzilla 9713
void fooNoDescription() {}
///
unittest { fooNoDescription(); }
///
unittest { if (true) {fooNoDescription(); } /* comment */ }

// ------------------------------------

/// test for bugzilla 9757
void foo9757() {}
/// ditto
void bar9757() {}
/// ditto
void baz9757() {}
///
unittest { foo9757(); bar9757(); }
///
unittest { bar9757(); foo9757(); }

/// with template functions
auto redBlackTree(E)(E[] elems...)
{
return 1;
}
/// ditto
auto redBlackTree(bool allowDuplicates, E)(E[] elems...)
{
return 2;
}
/// ditto
auto redBlackTree(alias less, E)(E[] elems...)
{
return 3;
}
///
unittest
{
auto rbt1 = redBlackTree(0, 1, 5, 7);
auto rbt2 = redBlackTree!string("hello", "world");
auto rbt3 = redBlackTree!true(0, 1, 5, 7, 5);
auto rbt4 = redBlackTree!"a > b"(0, 1, 5, 7);
}

// ------------------------------------

void main() { }
68 changes: 58 additions & 10 deletions test/compilable/extra-files/ddoc2630.html
Expand Up @@ -10,7 +10,8 @@ <h1>ddoc2630</h1>
<b>Examples:</b><br>
<pre class="d_code">
<font color=blue>assert</font>(<u>foo</u>(1, 1) == 2);
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="bar"></a>bool <u>bar</u>();
</big></dt>
Expand All @@ -19,7 +20,8 @@ <h1>ddoc2630</h1>
<pre class="d_code">
<font color=green>// documented
</font><font color=blue>assert</font>(<u>bar</u>());
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="doo"></a>void <u>doo</u>();
</big></dt>
Expand All @@ -39,43 +41,49 @@ <h1>ddoc2630</h1>
<font color=green>// documented
</font><font color=blue>assert</font>(<u>add</u>(3, 3) == 6);
<font color=blue>assert</font>(<u>add</u>(4, 4) == 8);
</pre><br><br><b>Examples:</b><br>
</pre>
<br><br><b>Examples:</b><br>
<pre class="d_code">
<font color=green>// documented
</font><font color=blue>assert</font>(<u>add</u>(5, 5) == 10);
<font color=blue>assert</font>(<u>add</u>(6, 6) == 12);
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="Foo"></a>class <u>Foo</u>;
</big></dt>
<dd>class <u>Foo</u><br><br>
<b>Examples:</b><br>
<pre class="d_code">
<u>Foo</u> foo = <font color=blue>new</font> <u>Foo</u>;
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="SomeClass"></a>class <u>SomeClass</u>;
</big></dt>
<dd>some class - 1 example<br><br>
<b>Examples:</b><br>
<pre class="d_code">
<u>SomeClass</u> sc = <font color=blue>new</font> <u>SomeClass</u>;
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="Outer"></a>class <u>Outer</u>;
</big></dt>
<dd><u>Outer</u> - 1 example<br><br>
<b>Examples:</b><br>
<pre class="d_code">
<u>Outer</u> outer = <font color=blue>new</font> <u>Outer</u>;
</pre><br><br>
</pre>
<br><br>
<dl><dt><big><a name="Outer.Inner"></a>class <u>Inner</u>;
</big></dt>
<dd><u>Inner</u><br><br>
<b>Examples:</b><br>
<pre class="d_code">
<u>Inner</u> inner = <font color=blue>new</font> <u>Inner</u>;
</pre><br><br>
</pre>
<br><br>
</dd>
</dl>
</dd>
Expand All @@ -100,11 +108,51 @@ <h1>ddoc2630</h1>
<b>Examples:</b><br>
<pre class="d_code">
<u>foo</u>(2);
</pre><br><br><b>Examples:</b><br>
</pre>
<br><br><b>Examples:</b><br>
<pre class="d_code">
<u>foo</u>(4);
</pre><br><br>
</pre>
<br><br>
</dd>
<dt><big><a name="fooNoDescription"></a>void <u>fooNoDescription</u>();
</big></dt>
<dd>test for bugzilla 9713<br><br>
<b>Examples:</b><br>
<pre class="d_code"><u>fooNoDescription</u>();
</pre>
<br><br><b>Examples:</b><br>
<pre class="d_code"><font color=blue>if</font> (<font color=blue>true</font>) {<u>fooNoDescription</u>(); } <font color=green>/* comment */</font>
</pre>
<br><br>
</dd>
<dt><big><a name="foo9757"></a>void <u>foo9757</u>();
<br><a name="bar9757"></a>void <u>bar9757</u>();
<br><a name="baz9757"></a>void <u>baz9757</u>();
</big></dt>
<dd>test for bugzilla 9757<br><br>

<b>Examples:</b><br>
<pre class="d_code">foo9757(); bar9757();
</pre>
<br><br><b>Examples:</b><br>
<pre class="d_code">bar9757(); foo9757();
</pre>
<br><br></dd>
<dt><big><a name="redBlackTree"></a>auto <u>redBlackTree</u>(E)(E[] <i>elems</i>...);
<br><a name="redBlackTree"></a>auto <u>redBlackTree</u>(bool allowDuplicates, E)(E[] <i>elems</i>...);
<br><a name="redBlackTree"></a>auto <u>redBlackTree</u>(alias less, E)(E[] <i>elems</i>...);
</big></dt>
<dd>with template functions<br><br>

<b>Examples:</b><br>
<pre class="d_code">
<font color=blue>auto</font> rbt1 = <u>redBlackTree</u>(0, 1, 5, 7);
<font color=blue>auto</font> rbt2 = <u>redBlackTree</u>!string(<font color=red>"hello"</font>, <font color=red>"world"</font>);
<font color=blue>auto</font> rbt3 = <u>redBlackTree</u>!<font color=blue>true</font>(0, 1, 5, 7, 5);
<font color=blue>auto</font> rbt4 = <u>redBlackTree</u>!<font color=red>"a &gt; b"</font>(0, 1, 5, 7);
</pre>
<br><br></dd>
</dl>

<hr><small>Page generated by <a href="http://dlang.org/ddoc.html">Ddoc</a>. </small>
Expand Down

0 comments on commit d736fbf

Please sign in to comment.