aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-02-01 09:37:32 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-01 15:09:17 +0000
commit08895c48144cedaf81006803afe4a5a2becfdb92 (patch)
tree395b9eece35410bc75115e16a2c6b86e6bf35de8 /tools/bookmaker
parent4dab72f60664b50f66cdd1b26a59bfa873e899f7 (diff)
auto table generation
Replace manually entered summary tables with ones that are populated and sorted by bookmaker. This introduces a slight regression for anonymous enums but fixes a lot of bugs and omissions. The format is #Topic somethingTopical #Populate ## where somethingTopical is one of Subtopics, Constructors, Constants, Classes_and_Structs, Members, Member_Functions, and Related_Functions. Fix the bad formatting in SkCanvas reference. The #Error tag was was corrupting the markdown table. Remove the tag and replace it with #NoExample. Next up: revise self-check to know about populated topics. TBR=caryclark@google.com Docs-Preview: https://skia.org/?cl=102080 Bug: skia:6898 Change-Id: Idef5d1c14c740c18a81d6a5106182788dd2a09e1 Reviewed-on: https://skia-review.googlesource.com/102080 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'tools/bookmaker')
-rw-r--r--tools/bookmaker/bookmaker.cpp215
-rw-r--r--tools/bookmaker/bookmaker.h62
-rw-r--r--tools/bookmaker/definition.cpp3
-rw-r--r--tools/bookmaker/mdOut.cpp187
-rw-r--r--tools/bookmaker/selfCheck.cpp15
-rw-r--r--tools/bookmaker/spellCheck.cpp2
6 files changed, 353 insertions, 131 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index ab4670412c..0de8a46f3a 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -34,6 +34,8 @@ DEFINE_bool2(skip, z, false, "Skip degenerate missed in legacy preprocessor.");
find include/core -type f -name '*.h' -print -exec git blame {} \; > ~/all.blame.txt
todos:
+add new markup to associate typedef SaveLayerFlags with Enum so that, for
+ documentation purposes, this enum is named rather than anonymous
check column 1 of subtopic tables to see that they start lowercase and don't have a trailing period
space table better for Constants
should Return be on same line as 'Return Value'?
@@ -197,7 +199,8 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
this->setAsParent(definition);
}
{
- const string& fullTopic = hasEnd ? fParent->fFiddle : definition->fFiddle;
+ SkASSERT(hasEnd ? fParent : definition);
+ string fullTopic = hasEnd ? fParent->fFiddle : definition->fFiddle;
Definition* defPtr = fTopicMap[fullTopic];
if (hasEnd) {
if (!definition) {
@@ -343,7 +346,6 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
case MarkType::kAnchor:
case MarkType::kDefine:
case MarkType::kDuration:
- case MarkType::kError:
case MarkType::kFile:
case MarkType::kHeight:
case MarkType::kImage:
@@ -352,6 +354,7 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
case MarkType::kLiteral:
case MarkType::kOutdent:
case MarkType::kPlatform:
+ case MarkType::kPopulate:
case MarkType::kSeeAlso:
case MarkType::kSet:
case MarkType::kSubstitute:
@@ -873,13 +876,21 @@ bool HackParser::hackFiles() {
SkASSERT(!root->fParent);
fStart = root->fStart;
fChar = fStart;
+ fClassesAndStructs = nullptr;
+ fConstants = nullptr;
fConstructors = nullptr;
- fOperators = nullptr;
fMemberFunctions = nullptr;
+ fMembers = nullptr;
+ fOperators = nullptr;
+ fRelatedFunctions = nullptr;
this->topicIter(root);
- fprintf(fOut, "%.*s\n", (int) (root->fTerminator - fChar), fChar);
+ fprintf(fOut, "%.*s", (int) (fEnd - fChar), fChar);
fclose(fOut);
- SkDebugf("wrote %s\n", filename.c_str());
+ if (this->writtenFileDiffers(filename, root->fFileName)) {
+ SkDebugf("wrote %s\n", filename.c_str());
+ } else {
+ remove(filename.c_str());
+ }
return true;
}
@@ -896,7 +907,8 @@ string HackParser::searchTable(const Definition* tableHolder, const Definition*
const Definition* col0 = row->fChildren[0];
size_t len = col0->fContentEnd - col0->fContentStart;
string method = string(col0->fContentStart, len);
- if (len - 2 == method.find("()") && islower(method[0])) {
+ if (len - 2 == method.find("()") && islower(method[0])
+ && Definition::MethodType::kOperator != match->fMethodType) {
method = method.substr(0, len - 2);
}
if (string::npos == match->fName.find(method)) {
@@ -922,85 +934,148 @@ string HackParser::searchTable(const Definition* tableHolder, const Definition*
// returns true if topic has method
void HackParser::topicIter(const Definition* topic) {
- if (string::npos != topic->fName.find("Member_Functions")) {
- SkASSERT(!fMemberFunctions);
- fMemberFunctions = topic;
+ if (string::npos != topic->fName.find(MdOut::kClassesAndStructs)) {
+ SkASSERT(!fClassesAndStructs);
+ fClassesAndStructs = topic;
}
- if (string::npos != topic->fName.find("Constructors")) {
+ if (string::npos != topic->fName.find(MdOut::kConstants)) {
+ SkASSERT(!fConstants);
+ fConstants = topic;
+ }
+ if (string::npos != topic->fName.find(MdOut::kConstructors)) {
SkASSERT(!fConstructors);
fConstructors = topic;
}
- if (string::npos != topic->fName.find("Operators")) {
+ if (string::npos != topic->fName.find(MdOut::kMemberFunctions)) {
+ SkASSERT(!fMemberFunctions);
+ fMemberFunctions = topic;
+ }
+ if (string::npos != topic->fName.find(MdOut::kMembers)) {
+ SkASSERT(!fMembers);
+ fMembers = topic;
+ }
+ if (string::npos != topic->fName.find(MdOut::kOperators)) {
SkASSERT(!fOperators);
fOperators = topic;
}
+ if (string::npos != topic->fName.find(MdOut::kRelatedFunctions)) {
+ SkASSERT(!fRelatedFunctions);
+ fRelatedFunctions = topic;
+ }
for (auto child : topic->fChildren) {
- if (MarkType::kMethod == child->fMarkType) {
- bool hasIn = MarkType::kTopic != topic->fMarkType &&
- MarkType::kSubtopic != topic->fMarkType; // don't write #In if parent is class
- bool hasLine = child->fClone;
- for (auto part : child->fChildren) {
- hasIn |= MarkType::kIn == part->fMarkType;
- hasLine |= MarkType::kLine == part->fMarkType;
- }
- string oneLiner;
- if (!hasLine) {
- // find member_functions, add entry 2nd column text to #Line
- for (auto tableHolder : { fMemberFunctions, fConstructors, fOperators }) {
- if (!tableHolder) {
- continue;
- }
- if (Definition::MethodType::kConstructor == child->fMethodType
- && fConstructors != tableHolder) {
- continue;
- }
- if (Definition::MethodType::kOperator == child->fMethodType
- && fOperators != tableHolder) {
- continue;
- }
- string temp = this->searchTable(tableHolder, child);
- if ("" != temp) {
- SkASSERT("" == oneLiner || temp == oneLiner);
- oneLiner = temp;
- }
+ string oneLiner;
+ bool hasIn = false;
+ bool hasLine = false;
+ for (auto part : child->fChildren) {
+ hasIn |= MarkType::kIn == part->fMarkType;
+ hasLine |= MarkType::kLine == part->fMarkType;
+ }
+ switch (child->fMarkType) {
+ case MarkType::kMethod: {
+ if (Definition::MethodType::kOperator == child->fMethodType) {
+ SkDebugf("");
}
- if ("" == oneLiner) {
-#ifdef SK_DEBUG
- const Definition* rootParent = topic;
- while (rootParent->fParent && MarkType::kClass != rootParent->fMarkType
- && MarkType::kStruct != rootParent->fMarkType) {
- rootParent = rootParent->fParent;
+ hasIn |= MarkType::kTopic != topic->fMarkType &&
+ MarkType::kSubtopic != topic->fMarkType; // don't write #In if parent is class
+ hasLine |= child->fClone;
+ if (!hasLine) {
+ // find member_functions, add entry 2nd column text to #Line
+ for (auto tableHolder : { fMemberFunctions, fConstructors, fOperators }) {
+ if (!tableHolder) {
+ continue;
+ }
+ if (Definition::MethodType::kConstructor == child->fMethodType
+ && fConstructors != tableHolder) {
+ continue;
+ }
+ if (Definition::MethodType::kOperator == child->fMethodType
+ && fOperators != tableHolder) {
+ continue;
+ }
+ string temp = this->searchTable(tableHolder, child);
+ if ("" != temp) {
+ SkASSERT("" == oneLiner || temp == oneLiner);
+ oneLiner = temp;
+ }
+ }
+ if ("" == oneLiner) {
+ const Definition* csParent = child->csParent();
+ if (!csParent || !csParent->csParent()) {
+ SkDebugf("");
+ }
+ #ifdef SK_DEBUG
+ const Definition* rootParent = topic;
+ while (rootParent->fParent && MarkType::kClass != rootParent->fMarkType
+ && MarkType::kStruct != rootParent->fMarkType) {
+ rootParent = rootParent->fParent;
+ }
+ #endif
+ SkASSERT(rootParent);
+ SkASSERT(MarkType::kClass == rootParent->fMarkType
+ || MarkType::kStruct == rootParent->fMarkType);
+ hasLine = true;
}
-#endif
- SkASSERT(rootParent);
- SkASSERT(MarkType::kClass == rootParent->fMarkType
- || MarkType::kStruct == rootParent->fMarkType);
- hasLine = true;
}
- }
- if (hasIn && hasLine) {
- continue;
- }
- const char* start = fChar;
- const char* end = child->fContentStart;
- fprintf(fOut, "%.*s", (int) (end - start), start);
- fChar = end;
- // write to method markup header end
- if (!hasIn) {
- fprintf(fOut, "\n#In %s", topic->fName.c_str());
- }
- if (!hasLine) {
- fprintf(fOut, "\n#Line # %s ##", oneLiner.c_str());
- }
- }
- if (MarkType::kTopic == child->fMarkType || MarkType::kSubtopic == child->fMarkType ||
- MarkType::kStruct == child->fMarkType || MarkType::kClass == child->fMarkType) {
- this->topicIter(child);
+ if (hasIn && hasLine) {
+ continue;
+ }
+ const char* start = fChar;
+ const char* end = child->fContentStart;
+ fprintf(fOut, "%.*s", (int) (end - start), start);
+ fChar = end;
+ // write to method markup header end
+ if (!hasIn) {
+ fprintf(fOut, "\n#In %s", topic->fName.c_str());
+ }
+ if (!hasLine) {
+ fprintf(fOut, "\n#Line # %s ##", oneLiner.c_str());
+ }
+ } break;
+ case MarkType::kTopic:
+ case MarkType::kSubtopic:
+ this->addOneLiner(fRelatedFunctions, child, hasLine, true);
+ this->topicIter(child);
+ break;
+ case MarkType::kStruct:
+ case MarkType::kClass:
+ this->addOneLiner(fClassesAndStructs, child, hasLine, false);
+ this->topicIter(child);
+ break;
+ case MarkType::kEnum:
+ case MarkType::kEnumClass:
+ this->addOneLiner(fConstants, child, hasLine, true);
+ break;
+ case MarkType::kMember:
+ this->addOneLiner(fMembers, child, hasLine, false);
+ break;
+ default:
+ ;
}
}
}
+void HackParser::addOneLiner(const Definition* defTable, const Definition* child, bool hasLine,
+ bool lfAfter) {
+ if (hasLine) {
+ return;
+ }
+ string oneLiner = this->searchTable(defTable, child);
+ if ("" == oneLiner) {
+ return;
+ }
+ const char* start = fChar;
+ const char* end = child->fContentStart;
+ fprintf(fOut, "%.*s", (int) (end - start), start);
+ fChar = end;
+ if (!lfAfter) {
+ fprintf(fOut, "\n");
+ }
+ fprintf(fOut, "#Line # %s ##", oneLiner.c_str());
+ if (lfAfter) {
+ fprintf(fOut, "\n");
+ }
+}
bool BmhParser::hasEndToken() const {
const char* last = fLine + this->lineLength();
@@ -1424,7 +1499,6 @@ vector<string> BmhParser::typeName(MarkType markType, bool* checkEnd) {
case MarkType::kDefine:
case MarkType::kDefinedBy:
case MarkType::kDuration:
- case MarkType::kError:
case MarkType::kFile:
case MarkType::kHeight:
case MarkType::kImage:
@@ -1432,6 +1506,7 @@ vector<string> BmhParser::typeName(MarkType markType, bool* checkEnd) {
case MarkType::kLiteral:
case MarkType::kOutdent:
case MarkType::kPlatform:
+ case MarkType::kPopulate:
case MarkType::kReturn:
case MarkType::kSeeAlso:
case MarkType::kSet:
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 06e7e8154d..65e8f1562a 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -99,7 +99,6 @@ enum class MarkType {
kDuration,
kEnum,
kEnumClass,
- kError,
kExample,
kExperimental,
kExternal,
@@ -121,6 +120,7 @@ enum class MarkType {
kOutdent,
kParam,
kPlatform,
+ kPopulate,
kPrivate,
kReturn,
kRoot,
@@ -826,6 +826,18 @@ public:
bool crossCheck2(const Definition& includeToken) const;
bool crossCheck(const Definition& includeToken) const;
bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
+
+ const Definition* csParent() const {
+ Definition* test = fParent;
+ while (test) {
+ if (MarkType::kStruct == test->fMarkType || MarkType::kClass == test->fMarkType) {
+ return test;
+ }
+ test = test->fParent;
+ }
+ return nullptr;
+ }
+
bool exampleToScript(string* result, ExampleOptions ) const;
string extractText(TrimExtract trimExtract) const;
string fiddleName() const;
@@ -834,7 +846,6 @@ public:
bool hasMatch(const string& name) const;
const Definition* hasParam(const string& ref) const;
bool isClone() const { return fClone; }
- bool isStructOrClass() const;
Definition* iRootParent() {
Definition* test = fParent;
@@ -848,6 +859,7 @@ public:
}
virtual bool isRoot() const { return false; }
+ bool isStructOrClass() const;
int length() const {
return (int) (fContentEnd - fContentStart);
@@ -1224,7 +1236,6 @@ public:
, { "Duration", nullptr, MarkType::kDuration, R_N, E_N, M(Example) | M(NoExample) }
, { "Enum", &fEnumMap, MarkType::kEnum, R_Y, E_O, M_CSST | M(Root) }
, { "EnumClass", &fClassMap, MarkType::kEnumClass, R_Y, E_O, M_CSST | M(Root) }
-, { "Error", nullptr, MarkType::kError, R_N, E_N, M(Example) | M(NoExample) }
, { "Example", nullptr, MarkType::kExample, R_O, E_N, M_CSST | M_E | M(Method) }
, { "Experimental", nullptr, MarkType::kExperimental, R_Y, E_N, 0 }
, { "External", nullptr, MarkType::kExternal, R_Y, E_N, M(Root) }
@@ -1249,6 +1260,7 @@ public:
, { "Outdent", nullptr, MarkType::kOutdent, R_N, E_N, M(Code) }
, { "Param", nullptr, MarkType::kParam, R_Y, E_N, M(Method) }
, { "Platform", nullptr, MarkType::kPlatform, R_N, E_N, M(Example) | M(NoExample) }
+, { "Populate", nullptr, MarkType::kPopulate, R_N, E_N, M(Subtopic) }
, { "Private", nullptr, MarkType::kPrivate, R_N, E_N, 0 }
, { "Return", nullptr, MarkType::kReturn, R_Y, E_N, M(Method) }
, { "", nullptr, MarkType::kRoot, R_Y, E_N, 0 }
@@ -1422,7 +1434,6 @@ public:
, { nullptr, MarkType::kDuration }
, { &fIEnumMap, MarkType::kEnum }
, { &fIEnumMap, MarkType::kEnumClass }
- , { nullptr, MarkType::kError }
, { nullptr, MarkType::kExample }
, { nullptr, MarkType::kExperimental }
, { nullptr, MarkType::kExternal }
@@ -1444,6 +1455,7 @@ public:
, { nullptr, MarkType::kOutdent }
, { nullptr, MarkType::kParam }
, { nullptr, MarkType::kPlatform }
+ , { nullptr, MarkType::kPopulate }
, { nullptr, MarkType::kPrivate }
, { nullptr, MarkType::kReturn }
, { nullptr, MarkType::kRoot }
@@ -1980,6 +1992,9 @@ public:
this->reset();
}
+ void addOneLiner(const Definition* defTable, const Definition* child, bool hasLine,
+ bool lfAfter);
+
bool parseFromFile(const char* path) override {
if (!INHERITED::parseSetup(path)) {
return false;
@@ -1997,9 +2012,13 @@ public:
private:
const BmhParser& fBmhParser;
+ const Definition* fClassesAndStructs;
+ const Definition* fConstants;
const Definition* fConstructors;
- const Definition* fOperators;
const Definition* fMemberFunctions;
+ const Definition* fMembers;
+ const Definition* fOperators;
+ const Definition* fRelatedFunctions;
bool hackFiles();
typedef ParserCommon INHERITED;
@@ -2014,6 +2033,17 @@ public:
bool buildReferences(const char* docDir, const char* mdOutDirOrFile);
bool buildStatus(const char* docDir, const char* mdOutDir);
+
+ static constexpr const char* kClassesAndStructs = "Classes_and_Structs";
+ static constexpr const char* kConstants = "Constants";
+ static constexpr const char* kConstructors = "Constructors";
+ static constexpr const char* kMemberFunctions = "Member_Functions";
+ static constexpr const char* kMembers = "Members";
+ static constexpr const char* kOperators = "Operators";
+ static constexpr const char* kOverview = "Overview";
+ static constexpr const char* kRelatedFunctions = "Related_Functions";
+ static constexpr const char* kSubtopics = "Subtopics";
+
private:
enum class TableState {
kNone,
@@ -2025,6 +2055,7 @@ private:
bool buildRefFromFile(const char* fileName, const char* outDir);
bool checkParamReturnBody(const Definition* def) const;
void childrenOut(const Definition* def, const char* contentStart);
+ const Definition* csParent() const;
const Definition* findParamType();
const Definition* isDefined(const TextParser& parser, const string& ref, bool report) const;
string linkName(const Definition* ) const;
@@ -2034,8 +2065,11 @@ private:
void mdHeaderOut(int depth) { mdHeaderOutLF(depth, 2); }
void mdHeaderOutLF(int depth, int lf);
void overviewOut();
- bool parseFromFile(const char* path) override {
- return true;
+ bool parseFromFile(const char* path) override { return true; }
+ void populateTables(const Definition* def);
+
+ vector<const Definition*>& populator(const char* key) {
+ return fPopulators.find(key)->second.fMembers;
}
void reset() override {
@@ -2068,12 +2102,22 @@ private:
}
void resolveOut(const char* start, const char* end, BmhParser::Resolvable );
- void subtopicOut(const Definition* subtopic, vector<Definition*>& data);
+ void rowOut(const char * name, const string& description);
+ void subtopicOut(vector<const Definition*>& data);
+ void subtopicsOut();
+
+ struct TableContents {
+ string fDescription;
+ vector<const Definition*> fMembers;
+ };
+
+ unordered_map<string, TableContents> fPopulators;
+ vector<const Definition*> fClassStack;
const BmhParser& fBmhParser;
const Definition* fEnumClass;
Definition* fMethod;
- RootDefinition* fRoot;
+ const RootDefinition* fRoot;
const Definition* fLastParam;
TableState fTableState;
bool fHasFiddle;
diff --git a/tools/bookmaker/definition.cpp b/tools/bookmaker/definition.cpp
index ed4e06cd35..7885c6301c 100644
--- a/tools/bookmaker/definition.cpp
+++ b/tools/bookmaker/definition.cpp
@@ -533,9 +533,6 @@ bool Definition::exampleToScript(string* result, ExampleOptions exampleOptions)
case MarkType::kDuration:
durationStr = string(iter->fContentStart, iter->fContentEnd - iter->fContentStart);
break;
- case MarkType::kError:
- result->clear();
- return true;
case MarkType::kHeight:
heightStr = string(iter->fContentStart, iter->fContentEnd - iter->fContentStart);
break;
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 995491d136..b51bb8d77e 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -232,13 +232,13 @@ string MdOut::addReferences(const char* refStart, const char* refEnd,
continue;
}
}
- Definition* test = fRoot;
+ const Definition* test = fRoot;
do {
if (!test->isRoot()) {
continue;
}
for (string prefix : { "_", "::" } ) {
- RootDefinition* root = test->asRoot();
+ const RootDefinition* root = test->asRoot();
string prefixed = root->fName + prefix + ref;
if (const Definition* def = root->find(prefixed,
RootDefinition::AllowParens::kYes)) {
@@ -357,6 +357,15 @@ bool MdOut::buildRefFromFile(const char* name, const char* outDir) {
this->lfAlways(1);
FPRINTF("===");
}
+ fPopulators[kClassesAndStructs].fDescription = "embedded struct and class members";
+ fPopulators[kConstants].fDescription = "enum and enum class, const values";
+ fPopulators[kConstructors].fDescription = "functions that construct";
+ fPopulators[kMemberFunctions].fDescription = "static functions and member methods";
+ fPopulators[kMembers].fDescription = "member values";
+ fPopulators[kOperators].fDescription = "operator overloading methods";
+ fPopulators[kRelatedFunctions].fDescription = "similar methods grouped together";
+ fPopulators[kSubtopics].fDescription = "";
+ this->populateTables(fRoot);
this->markTypeOut(topicDef);
}
if (fOut) {
@@ -424,6 +433,24 @@ void MdOut::childrenOut(const Definition* def, const char* start) {
}
}
+const Definition* MdOut::csParent() const {
+ const Definition* csParent = fRoot->csParent();
+ if (!csParent) {
+ const Definition* topic = fRoot;
+ while (topic && MarkType::kTopic != topic->fMarkType) {
+ topic = topic->fParent;
+ }
+ for (auto child : topic->fChildren) {
+ if (child->isStructOrClass() || MarkType::kTypedef == child->fMarkType) {
+ csParent = child;
+ break;
+ }
+ }
+ SkASSERT(csParent || string::npos == fRoot->fFileName.find("Sk"));
+ }
+ return csParent;
+}
+
const Definition* MdOut::findParamType() {
SkASSERT(fMethod);
TextParser parser(fMethod->fFileName, fMethod->fStart, fMethod->fContentStart,
@@ -486,12 +513,12 @@ const Definition* MdOut::isDefined(const TextParser& parser, const string& ref,
if (const Definition* definition = fRoot->find(ref, RootDefinition::AllowParens::kYes)) {
return definition;
}
- Definition* test = fRoot;
+ const Definition* test = fRoot;
do {
if (!test->isRoot()) {
continue;
}
- RootDefinition* root = test->asRoot();
+ const RootDefinition* root = test->asRoot();
for (auto& leaf : root->fBranches) {
if (ref == leaf.first) {
return leaf.second;
@@ -626,7 +653,7 @@ string MdOut::linkRef(const string& leadingSpaces, const Definition* def,
const string* str = &def->fFiddle;
SkASSERT(str->length() > 0);
size_t under = str->find('_');
- Definition* curRoot = fRoot;
+ const Definition* curRoot = fRoot;
string classPart = string::npos != under ? str->substr(0, under) : *str;
bool classMatch = curRoot->fName == classPart;
while (curRoot->fParent) {
@@ -798,8 +825,6 @@ void MdOut::markTypeOut(Definition* def) {
FPRINTF("<a name=\"%s\"></a> Enum %s", def->fFiddle.c_str(), def->fName.c_str());
this->lf(2);
break;
- case MarkType::kError:
- break;
case MarkType::kExample: {
this->mdHeaderOut(3);
FPRINTF("Example\n"
@@ -816,7 +841,7 @@ void MdOut::markTypeOut(Definition* def) {
gpuAndCpu = platParse.strnstr("cpu", platParse.fEnd);
}
}
- if (fHasFiddle && !def->hasChild(MarkType::kError)) {
+ if (fHasFiddle) {
SkASSERT(def->fHash.length() > 0);
FPRINTF("<div><fiddle-embed name=\"%s\"", def->fHash.c_str());
if (showGpu) {
@@ -944,6 +969,18 @@ void MdOut::markTypeOut(Definition* def) {
} break;
case MarkType::kPlatform:
break;
+ case MarkType::kPopulate: {
+ SkASSERT(MarkType::kSubtopic == def->fParent->fMarkType);
+ string name = def->fParent->fName;
+ if (kSubtopics == name) {
+ this->subtopicsOut();
+ } else {
+ SkASSERT(kClassesAndStructs == name || kConstants == name || kConstructors == name
+ || kMemberFunctions == name || kMembers == name || kOperators == name
+ || kRelatedFunctions == name);
+ this->subtopicOut(this->populator(name.c_str()));
+ }
+ } break;
case MarkType::kPrivate:
break;
case MarkType::kReturn:
@@ -1147,32 +1184,55 @@ void MdOut::mdHeaderOutLF(int depth, int lf) {
FPRINTF(" ");
}
-void MdOut::overviewOut() {
-#if 0 // under development
- // substitute $1 with def (e.g. Subtopics); substitute $2 with ref (e.g. SkRect)
- const char header[] =
- "## $1\n"
- "\n"
- "| name | description |\n"
- "| --- | --- |\n";
- const char* topics[] = {
- "Classes_and_Structs", "embedded struct and class members",
- "Constants", "enum and enum class, const values",
- "Constructors", "functions that construct $2",
- "Member_Function", "static functions and member methods",
- "Members", "member values",
- "Operator", "operator overloading methods",
- "Related_Functions", "similar methods grouped together",
- };
- int found = 0;
- vector<Definition*> classesAndStructs;
- vector<Definition*> constants;
- vector<Definition*> constructors;
- vector<Definition*> memberFunctions;
- vector<Definition*> members;
- vector<Definition*> operators;
- vector<Definition*> relatedFunctions;
-#endif
+void MdOut::populateTables(const Definition* def) {
+ const Definition* csParent = this->csParent();
+ for (auto child : def->fChildren) {
+ if (MarkType::kTopic == child->fMarkType || MarkType::kSubtopic == child->fMarkType) {
+ bool legacyTopic = fPopulators.end() != fPopulators.find(child->fName);
+ if (!legacyTopic && child->fName != kOverview) {
+ this->populator(kRelatedFunctions).push_back(child);
+ }
+ this->populateTables(child);
+ continue;
+ }
+ if (child->isStructOrClass()) {
+ if (fClassStack.size() > 0) {
+ this->populator(kClassesAndStructs).push_back(child);
+ }
+ fClassStack.push_back(child);
+ this->populateTables(child);
+ fClassStack.pop_back();
+ continue;
+ }
+ if (MarkType::kEnum == child->fMarkType || MarkType::kEnumClass == child->fMarkType) {
+ this->populator(kConstants).push_back(child);
+ continue;
+ }
+ if (MarkType::kMember == child->fMarkType) {
+ this->populator(kMembers).push_back(child);
+ continue;
+ }
+ if (MarkType::kMethod != child->fMarkType) {
+ continue;
+ }
+ if (child->fClone) {
+ continue;
+ }
+ if (Definition::MethodType::kConstructor == child->fMethodType
+ || Definition::MethodType::kDestructor == child->fMethodType) {
+ this->populator(kConstructors).push_back(child);
+ continue;
+ }
+ if (Definition::MethodType::kOperator == child->fMethodType) {
+ this->populator(kOperators).push_back(child);
+ continue;
+ }
+ this->populator(kMemberFunctions).push_back(child);
+ if (csParent && (0 == child->fName.find(csParent->fName + "::Make")
+ || 0 == child->fName.find(csParent->fName + "::make"))) {
+ this->populator(kConstructors).push_back(child);
+ }
+ }
}
void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable resolvable) {
@@ -1253,3 +1313,62 @@ void MdOut::resolveOut(const char* start, const char* end, BmhParser::Resolvable
#endif
}
}
+
+void MdOut::rowOut(const char* name, const string& description) {
+ this->lfAlways(1);
+ FPRINTF("| ");
+ this->resolveOut(name, name + strlen(name), BmhParser::Resolvable::kYes);
+ FPRINTF(" | ");
+ this->resolveOut(&description.front(), &description.back() + 1, BmhParser::Resolvable::kYes);
+ FPRINTF(" |");
+ this->lf(1);
+}
+
+void MdOut::subtopicsOut() {
+ const Definition* csParent = this->csParent();
+ SkASSERT(csParent);
+ this->rowOut("name", "description");
+ this->rowOut("---", "---");
+ for (auto item : { kClassesAndStructs, kConstants, kConstructors, kMemberFunctions,
+ kMembers, kOperators, kRelatedFunctions } ) {
+ for (auto entry : this->populator(item)) {
+ if (entry->csParent() == csParent) {
+ string description = fPopulators.find(item)->second.fDescription;
+ if (kConstructors == item) {
+ description += " " + csParent->fName;
+ }
+ this->rowOut(item, description);
+ break;
+ }
+ }
+ }
+}
+
+void MdOut::subtopicOut(vector<const Definition*>& data) {
+ const Definition* csParent = this->csParent();
+ SkASSERT(csParent);
+ fRoot = csParent->asRoot();
+ this->rowOut("name", "description");
+ this->rowOut("---", "---");
+ std::map<string, const Definition*> items;
+ for (auto entry : data) {
+ if (entry->csParent() != csParent) {
+ continue;
+ }
+ size_t start = entry->fName.find_last_of("::");
+ string name = entry->fName.substr(string::npos == start ? 0 : start + 1);
+ items[name] = entry;
+ }
+ for (auto entry : items) {
+ const Definition* oneLiner = nullptr;
+ for (auto child : entry.second->fChildren) {
+ if (MarkType::kLine == child->fMarkType) {
+ oneLiner = child;
+ break;
+ }
+ }
+ SkASSERT(oneLiner);
+ this->rowOut(entry.first.c_str(), string(oneLiner->fContentStart,
+ oneLiner->fContentEnd - oneLiner->fContentStart));
+ }
+}
diff --git a/tools/bookmaker/selfCheck.cpp b/tools/bookmaker/selfCheck.cpp
index f30a5824bc..fd8ef59fa1 100644
--- a/tools/bookmaker/selfCheck.cpp
+++ b/tools/bookmaker/selfCheck.cpp
@@ -66,7 +66,7 @@ protected:
// should be 'creators' instead of constructors?
bool checkConstructorsSummary() {
for (auto& rootChild : fRoot->fChildren) {
- if (!this->isStructOrClass(rootChild)) {
+ if (!rootChild->isStructOrClass()) {
continue;
}
auto& cs = rootChild;
@@ -357,7 +357,7 @@ protected:
const Definition* classOrStruct() {
for (auto& rootChild : fRoot->fChildren) {
- if (this->isStructOrClass(rootChild)) {
+ if (rootChild->isStructOrClass()) {
return rootChild;
}
}
@@ -460,17 +460,6 @@ protected:
return true;
}
- bool isStructOrClass(const Definition* definition) const {
- if (MarkType::kStruct != definition->fMarkType &&
- MarkType::kClass != definition->fMarkType) {
- return false;
- }
- if (string::npos != definition->fFileName.find("undocumented.bmh")) {
- return false;
- }
- return true;
- }
-
private:
const BmhParser& fBmhParser;
RootDefinition* fRoot;
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index 838e44ec6e..0daa4602ad 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -187,8 +187,6 @@ bool SpellCheck::check(Definition* def) {
case MarkType::kEnumClass:
this->wordCheck(def->fName);
break;
- case MarkType::kError:
- break;
case MarkType::kExample:
break;
case MarkType::kExperimental: