int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg dg, void *ctx, size_t *pn) { assert(dg); if (!members) return 0; size_t n = pn ? *pn : 0; // take over index int result = 0; for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; if (AttribDeclaration *a = s->isAttribDeclaration()) result = foreach(sc, a->include(sc, NULL), dg, ctx, &n); else if (TemplateMixin *tm = s->isTemplateMixin()) result = foreach(sc, tm->members, dg, ctx, &n); else if (s->isTemplateInstance()) ; else if (s->isUnitTestDeclaration()) ; else result = dg(ctx, n++, s); if (result) break; } if (pn) *pn = n; // update index return result; }
/** * Collects all unit test functions from the given array of symbols. * * This is a helper function used by the implementation of __traits(getUnitTests). * * Input: * symbols array of symbols to collect the functions from * uniqueUnitTests an associative array (should actually be a set) to * keep track of already collected functions. We're * using an AA here to avoid doing a linear search of unitTests * * Output: * unitTests array of DsymbolExp's of the collected unit test functions * uniqueUnitTests updated with symbols from unitTests[ ] */ static void collectUnitTests(Dsymbols *symbols, AA *uniqueUnitTests, Expressions *unitTests) { if (!symbols) return; for (size_t i = 0; i < symbols->dim; i++) { Dsymbol *symbol = (*symbols)[i]; UnitTestDeclaration *unitTest = symbol->isUnitTestDeclaration(); if (unitTest) { if (!_aaGetRvalue(uniqueUnitTests, unitTest)) { FuncAliasDeclaration* alias = new FuncAliasDeclaration(unitTest, 0); alias->protection = unitTest->protection; Expression* e = new DsymbolExp(Loc(), alias); unitTests->push(e); bool* value = (bool*) _aaGet(&uniqueUnitTests, unitTest); *value = true; } } else { AttribDeclaration *attrDecl = symbol->isAttribDeclaration(); if (attrDecl) { Dsymbols *decl = attrDecl->include(NULL, NULL); collectUnitTests(decl, uniqueUnitTests, unitTests); } } } }