Skip to content
Browse files

Merge pull request #1773 from 9rnsr/fix9474

Issue 9474 - Ddoc'd unittests should work correctly with interspersed version(none)
  • Loading branch information...
2 parents 91b937c + c74a858 commit 65b882c81e56c0c8e2e8f802778611ce6503e2bc @WalterBright WalterBright committed
Showing with 130 additions and 36 deletions.
  1. +2 −0 src/func.c
  2. +28 −33 src/parse.c
  3. +2 −2 src/parse.h
  4. +48 −1 test/compilable/ddocunittest.d
  5. +50 −0 test/compilable/extra-files/ddocunittest.html
View
2 src/func.c
@@ -4447,6 +4447,8 @@ Dsymbol *UnitTestDeclaration::syntaxCopy(Dsymbol *s)
void UnitTestDeclaration::semantic(Scope *sc)
{
+ protection = sc->protection;
+
if (scope)
{ sc = scope;
scope = NULL;
View
61 src/parse.c
@@ -143,7 +143,7 @@ Dsymbols *Parser::parseModule()
return new Dsymbols();
}
-Dsymbols *Parser::parseDeclDefs(int once)
+Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl)
{ Dsymbol *s;
Dsymbols *decldefs;
Dsymbols *a;
@@ -153,6 +153,9 @@ Dsymbols *Parser::parseDeclDefs(int once)
StorageClass storageClass;
Condition *condition;
unsigned char *comment;
+ Dsymbol *lastDecl = NULL; // used to link unittest to its previous declaration
+ if (!pLastDecl)
+ pLastDecl = &lastDecl;
//printf("Parser::parseDeclDefs()\n");
decldefs = new Dsymbols();
@@ -232,6 +235,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
case TOKinterface:
Ldeclaration:
a = parseDeclarations(STCundefined, NULL);
+ if (a->dim) *pLastDecl = (*a)[a->dim-1];
decldefs->append(a);
continue;
@@ -269,20 +273,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
case TOKunittest:
s = parseUnitTest();
- if (decldefs && decldefs->dim)
- {
- Dsymbol *ds = (*decldefs)[decldefs->dim-1];
- AttribDeclaration *ad;
- while ((ad = ds->isAttribDeclaration()) != NULL)
- {
- if (ad->decl && ad->decl->dim)
- ds = (*ad->decl)[ad->decl->dim-1];
- else
- break;
- }
-
- ds->unittest = (UnitTestDeclaration *)s;
- }
+ if (*pLastDecl) (*pLastDecl)->unittest = (UnitTestDeclaration *)s;
break;
case TOKnew:
@@ -310,12 +301,12 @@ Dsymbols *Parser::parseDeclDefs(int once)
else if (token.value == TOKif)
{ condition = parseStaticIfCondition();
if (token.value == TOKcolon)
- a = parseBlock();
+ a = parseBlock(pLastDecl);
else
{
Loc lookingForElseSave = lookingForElse;
lookingForElse = loc;
- a = parseBlock();
+ a = parseBlock(pLastDecl);
lookingForElse = lookingForElseSave;
}
aelse = NULL;
@@ -323,7 +314,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
{
Loc elseloc = this->loc;
nextToken();
- aelse = parseBlock();
+ aelse = parseBlock(pLastDecl);
checkDanglingElse(elseloc);
}
s = new StaticIfDeclaration(condition, a, aelse);
@@ -394,7 +385,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
stc = parseAttribute(&exps);
if (stc)
goto Lstc; // it's a predefined attribute
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new UserAttributeDeclaration(exps, a);
break;
}
@@ -471,6 +462,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
peek(&token)->value == TOKassign)
{
a = parseAutoDeclarations(storageClass, comment);
+ if (a->dim) *pLastDecl = (*a)[a->dim-1];
decldefs->append(a);
continue;
}
@@ -491,10 +483,11 @@ Dsymbols *Parser::parseDeclDefs(int once)
)
{
a = parseDeclarations(storageClass, comment);
+ if (a->dim) *pLastDecl = (*a)[a->dim-1];
decldefs->append(a);
continue;
}
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new StorageClassDeclaration(storageClass, a);
break;
@@ -509,7 +502,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
check(TOKlparen);
Expression *e = parseAssignExp();
check(TOKrparen);
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new DeprecatedDeclaration(e, a);
break;
}
@@ -518,7 +511,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
{
warning(loc, "use @(attributes) instead of [attributes]");
Expressions *exps = parseArguments();
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new UserAttributeDeclaration(exps, a);
break;
}
@@ -531,7 +524,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
{
enum LINK linksave = linkage;
linkage = parseLinkage();
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new LinkDeclaration(linkage, a);
linkage = linksave;
break;
@@ -555,7 +548,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
break;
default: break;
}
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new ProtDeclaration(prot, a);
break;
@@ -583,7 +576,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
else
n = global.structalign; // default
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new AlignDeclaration(n, a);
break;
}
@@ -608,7 +601,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
if (token.value == TOKsemicolon)
a = NULL;
else
- a = parseBlock();
+ a = parseBlock(pLastDecl);
s = new PragmaDeclaration(loc, ident, args, a);
break;
}
@@ -661,12 +654,12 @@ Dsymbols *Parser::parseDeclDefs(int once)
Lcondition:
{
if (token.value == TOKcolon)
- a = parseBlock();
+ a = parseBlock(pLastDecl);
else
{
Loc lookingForElseSave = lookingForElse;
lookingForElse = loc;
- a = parseBlock();
+ a = parseBlock(pLastDecl);
lookingForElse = lookingForElseSave;
}
}
@@ -675,7 +668,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
{
Loc elseloc = this->loc;
nextToken();
- aelse = parseBlock();
+ aelse = parseBlock(pLastDecl);
checkDanglingElse(elseloc);
}
s = new ConditionalDeclaration(condition, a, aelse);
@@ -698,6 +691,8 @@ Dsymbols *Parser::parseDeclDefs(int once)
if (s)
{ decldefs->push(s);
addComment(s, comment);
+ if (!s->isAttribDeclaration())
+ *pLastDecl = s;
}
} while (!once);
return decldefs;
@@ -851,7 +846,7 @@ StorageClass Parser::parseTypeCtor()
* Parse declarations after an align, protection, or extern decl.
*/
-Dsymbols *Parser::parseBlock()
+Dsymbols *Parser::parseBlock(Dsymbol **pLastDecl)
{
Dsymbols *a = NULL;
@@ -873,7 +868,7 @@ Dsymbols *Parser::parseBlock()
lookingForElse = 0;
nextToken();
- a = parseDeclDefs(0);
+ a = parseDeclDefs(0, pLastDecl);
if (token.value != TOKrcurly)
{ /* { */
error("matching '}' expected, not %s", token.toChars());
@@ -889,12 +884,12 @@ Dsymbols *Parser::parseBlock()
#if 0
a = NULL;
#else
- a = parseDeclDefs(0); // grab declarations up to closing curly bracket
+ a = parseDeclDefs(0, pLastDecl); // grab declarations up to closing curly bracket
#endif
break;
default:
- a = parseDeclDefs(1);
+ a = parseDeclDefs(1, pLastDecl);
break;
}
return a;
View
4 src/parse.h
@@ -71,9 +71,9 @@ struct Parser : Lexer
Parser(Module *module, unsigned char *base, size_t length, int doDocComment);
Dsymbols *parseModule();
- Dsymbols *parseDeclDefs(int once);
+ Dsymbols *parseDeclDefs(int once, Dsymbol **pLastDecl = NULL);
Dsymbols *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
- Dsymbols *parseBlock();
+ Dsymbols *parseBlock(Dsymbol **pLastDecl);
void composeStorageClass(StorageClass stc);
StorageClass parseAttribute(Expressions **pexps);
StorageClass parsePostfix();
View
49 test/compilable/ddocunittest.d
@@ -174,6 +174,53 @@ unittest
}
// ------------------------------------
+// 9474
+
+///
+void foo9474() { }
+
+version(none)
+unittest { }
+
+/// Example
+unittest { foo9474(); }
+
+/// doc
+void bar9474() { }
+
+version(none)
+unittest { }
+
+/// Example
+unittest { bar9474(); }
+
+///
+struct S9474
+{
+}
+///
+unittest { S9474 s; }
+
+///
+auto autovar9474 = 1;
+///
+unittest { int v = autovar9474; }
+
+///
+auto autofun9474() { return 1; }
+///
+ unittest { int n = autofun9474(); }
+
+///
+template Template9474()
+{
+ /// Shouldn't link following unittest to here
+ void foo() {}
+}
+///
+unittest { alias Template9474!() T; }
+
+// ------------------------------------
// 9713
///
@@ -221,7 +268,6 @@ unittest
}
// ------------------------------------
-
// Issue 9758
/// test
@@ -230,5 +276,6 @@ void foo(){}
///
unittest { }
+// ------------------------------------
void main() { }
View
50 test/compilable/extra-files/ddocunittest.html
@@ -117,6 +117,56 @@
</pre>
<br><br>
</dd>
+<dt><big><a name="foo9474"></a>void <u>foo9474</u>();
+</big></dt>
+<dd><b>Examples:</b><br>
+Example
+<pre class="d_code"><u>foo9474</u>();
+</pre>
+<br><br>
+</dd>
+<dt><big><a name="bar9474"></a>void <u>bar9474</u>();
+</big></dt>
+<dd>doc<br><br>
+<b>Examples:</b><br>
+Example
+<pre class="d_code"><u>bar9474</u>();
+</pre>
+<br><br>
+</dd>
+<dt><big><a name="S9474"></a>struct <u>S9474</u>;
+</big></dt>
+<dd><b>Examples:</b><br>
+<pre class="d_code"><u>S9474</u> s;
+</pre>
+<br><br>
+</dd>
+<dt><big><a name="autovar9474"></a>int <u>autovar9474</u>;
+</big></dt>
+<dd><b>Examples:</b><br>
+<pre class="d_code"><font color=blue>int</font> v = <u>autovar9474</u>;
+</pre>
+<br><br>
+</dd>
+<dt><big><a name="autofun9474"></a>auto <u>autofun9474</u>();
+</big></dt>
+<dd><b>Examples:</b><br>
+<pre class="d_code"><font color=blue>int</font> n = <u>autofun9474</u>();
+</pre>
+<br><br>
+</dd>
+<dt><big><a name="Template9474"></a>template <u>Template9474</u>()</big></dt>
+<dd><b>Examples:</b><br>
+<pre class="d_code"><font color=blue>alias</font> <u>Template9474</u>!() T;
+</pre>
+<br><br>
+<dl><dt><big><a name="foo"></a>void <u>foo</u>();
+</big></dt>
+<dd>Shouldn't link following unittest to here<br><br>
+
+</dd>
+</dl>
+</dd>
<dt><big><a name="fooNoDescription"></a>void <u>fooNoDescription</u>();
</big></dt>
<dd><b>Examples:</b><br>

0 comments on commit 65b882c

Please sign in to comment.
Something went wrong with that request. Please try again.