From da35281d447cfb6584fcdce516b2a5554a778a02 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 14 Mar 2013 17:22:56 +0900 Subject: [PATCH 1/4] fix Issue 9713 - Ddoc: Empty description suppress automatic example generation Even if proper description is empty, generated examples should be appeared --- src/doc.c | 2 +- test/compilable/ddoc2630.d | 8 ++++++++ test/compilable/extra-files/ddoc2630.html | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/doc.c b/src/doc.c index ee3d4ac11058..9e183dce17bd 100644 --- a/src/doc.c +++ b/src/doc.c @@ -1374,7 +1374,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++) diff --git a/test/compilable/ddoc2630.d b/test/compilable/ddoc2630.d index 752d786f76bf..55e11bc05cca 100644 --- a/test/compilable/ddoc2630.d +++ b/test/compilable/ddoc2630.d @@ -171,5 +171,13 @@ unittest foo(4); } +// ------------------------------------ + +/// test for bugzilla 9713 +void fooNoDescription() {} +/// +unittest { fooNoDescription(); } + +// ------------------------------------ void main() { } diff --git a/test/compilable/extra-files/ddoc2630.html b/test/compilable/extra-files/ddoc2630.html index 070f3393dc92..946add9f993e 100644 --- a/test/compilable/extra-files/ddoc2630.html +++ b/test/compilable/extra-files/ddoc2630.html @@ -105,6 +105,12 @@

ddoc2630

foo(4);

+
void fooNoDescription(); +
+
test for bugzilla 9713

+Examples:
+
fooNoDescription(); 


+

Page generated by Ddoc. From 11b2f76857c8a2d8fa14c0b6b3c69d60b4e5180c Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 14 Mar 2013 17:24:30 +0900 Subject: [PATCH 2/4] fix Issue 9714 - Ddoc: Combination of -D and -unittest reveals hidden unittest function Even if -unittest is specified, hidden function should not be appeared in ddoc output --- src/declaration.h | 1 + src/doc.c | 1 + test/compilable/ddoc2630.d | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/declaration.h b/src/declaration.h index d531f6a27bde..9eec1868a8dd 100644 --- a/src/declaration.h +++ b/src/declaration.h @@ -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; } diff --git a/src/doc.c b/src/doc.c index 9e183dce17bd..4ea041bb5a1a 100644 --- a/src/doc.c +++ b/src/doc.c @@ -649,6 +649,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 diff --git a/test/compilable/ddoc2630.d b/test/compilable/ddoc2630.d index 55e11bc05cca..c1352eb60db0 100644 --- a/test/compilable/ddoc2630.d +++ b/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 From 9708fb17e669b149ffb5653f5855410fc937f279 Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 14 Mar 2013 18:11:12 +0900 Subject: [PATCH 3/4] Refinement for #1641 - Reuse unindent mechanism that has introduced by #1377 - Remove trailing whitespace from auto-generated ddoc example --- src/doc.c | 134 +++++++--------------- src/parse.c | 18 ++- test/compilable/ddoc2630.d | 2 + test/compilable/extra-files/ddoc2630.html | 37 ++++-- test/compilable/extra-files/ddoc9475.html | 6 +- test/compilable/extra-files/ddoc9727.html | 14 ++- 6 files changed, 99 insertions(+), 112 deletions(-) diff --git a/src/doc.c b/src/doc.c index 4ea041bb5a1a..878ab72f7d2a 100644 --- a/src/doc.c +++ b/src/doc.c @@ -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 */ @@ -509,95 +552,6 @@ void Dsymbol::emitDitto(Scope *sc) 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(")"); - } - } -} - void ScopeDsymbol::emitMemberComments(Scope *sc) { //printf("ScopeDsymbol::emitMemberComments() %s\n", toChars()); @@ -1397,7 +1351,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 diff --git a/src/parse.c b/src/parse.c index 8d1e2c6155dc..af5a54a3c175 100644 --- a/src/parse.c +++ b/src/parse.c @@ -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); diff --git a/test/compilable/ddoc2630.d b/test/compilable/ddoc2630.d index c1352eb60db0..2c9b1b86fd53 100644 --- a/test/compilable/ddoc2630.d +++ b/test/compilable/ddoc2630.d @@ -177,6 +177,8 @@ unittest void fooNoDescription() {} /// unittest { fooNoDescription(); } +/// +unittest { if (true) {fooNoDescription(); } /* comment */ } // ------------------------------------ diff --git a/test/compilable/extra-files/ddoc2630.html b/test/compilable/extra-files/ddoc2630.html index 946add9f993e..7b7038a0ad68 100644 --- a/test/compilable/extra-files/ddoc2630.html +++ b/test/compilable/extra-files/ddoc2630.html @@ -10,7 +10,8 @@

ddoc2630

Examples:
 assert(foo(1, 1) == 2);
-


+ +

bool bar();
@@ -19,7 +20,8 @@

ddoc2630

 // documented
 assert(bar());
-


+ +

void doo();
@@ -39,12 +41,14 @@

ddoc2630

// documented assert(add(3, 3) == 6); assert(add(4, 4) == 8); -

Examples:
+ +

Examples:
 // documented
 assert(add(5, 5) == 10);
 assert(add(6, 6) == 12);
-


+ +

class Foo;
@@ -52,7 +56,8 @@

ddoc2630

Examples:
 Foo foo = new Foo;
-


+ +

class SomeClass;
@@ -60,7 +65,8 @@

ddoc2630

Examples:
 SomeClass sc = new SomeClass;
-


+ +

class Outer;
@@ -68,14 +74,16 @@

ddoc2630

Examples:
 Outer outer = new Outer;
-


+ +

class Inner;
Inner

Examples:
 Inner inner = new Inner;
-


+ +

@@ -100,16 +108,23 @@

ddoc2630

Examples:
 foo(2);
-


Examples:
+ +

Examples:
 foo(4);
-


+ +

void fooNoDescription();
test for bugzilla 9713

Examples:
-
fooNoDescription(); 


+
fooNoDescription();
+
+

Examples:
+
if (true) {fooNoDescription(); } /* comment */
+
+

diff --git a/test/compilable/extra-files/ddoc9475.html b/test/compilable/extra-files/ddoc9475.html index 4a013617aeda..6576aa7c233f 100644 --- a/test/compilable/extra-files/ddoc9475.html +++ b/test/compilable/extra-files/ddoc9475.html @@ -15,7 +15,8 @@

ddoc9475

// comment 2 documentedFunction(); } -

+ +

void bar();
@@ -23,7 +24,8 @@

ddoc9475

Examples:
 // bar comment
-


+ +

diff --git a/test/compilable/extra-files/ddoc9727.html b/test/compilable/extra-files/ddoc9727.html index 595553f67f19..741f0ff04c75 100644 --- a/test/compilable/extra-files/ddoc9727.html +++ b/test/compilable/extra-files/ddoc9727.html @@ -8,18 +8,20 @@

ddoc9727

The function foo.

Examples:
-
 foo(1);
-


Examples:
-foo can be used like this: + +

Examples:
+foo can be used like this:
 foo(2);
-


Examples:
-foo can also be used like this: + +

Examples:
+foo can also be used like this:
 foo(3);
-


+ +

From a85ad5474855e9aa618074cc970ff4fc755a31c7 Mon Sep 17 00:00:00 2001 From: k-hara Date: Tue, 19 Mar 2013 20:50:05 +0900 Subject: [PATCH 4/4] fix Issue 9757 - Ddoc: documented unittest after ditto should work --- src/doc.c | 6 ++++ test/compilable/ddoc2630.d | 37 +++++++++++++++++++++++ test/compilable/extra-files/ddoc2630.html | 27 +++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/src/doc.c b/src/doc.c index 878ab72f7d2a..47f701402c7c 100644 --- a/src/doc.c +++ b/src/doc.c @@ -550,6 +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; + + 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) diff --git a/test/compilable/ddoc2630.d b/test/compilable/ddoc2630.d index 2c9b1b86fd53..c9697ab4e626 100644 --- a/test/compilable/ddoc2630.d +++ b/test/compilable/ddoc2630.d @@ -182,4 +182,41 @@ 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() { } diff --git a/test/compilable/extra-files/ddoc2630.html b/test/compilable/extra-files/ddoc2630.html index 7b7038a0ad68..c17448a774c4 100644 --- a/test/compilable/extra-files/ddoc2630.html +++ b/test/compilable/extra-files/ddoc2630.html @@ -126,6 +126,33 @@

ddoc2630



+
void foo9757(); +
void bar9757(); +
void baz9757(); +
+
test for bugzilla 9757

+ +Examples:
+
foo9757(); bar9757();
+
+

Examples:
+
bar9757(); foo9757();
+
+

+
auto redBlackTree(E)(E[] elems...); +
auto redBlackTree(bool allowDuplicates, E)(E[] elems...); +
auto redBlackTree(alias less, E)(E[] elems...); +
+
with template functions

+ +Examples:
+
+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);
+
+


Page generated by Ddoc.