From 08895c48144cedaf81006803afe4a5a2becfdb92 Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Thu, 1 Feb 2018 09:37:32 -0500 Subject: 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 Reviewed-by: Cary Clark --- tools/bookmaker/bookmaker.cpp | 215 +++++++++++++++++++++++++++-------------- tools/bookmaker/bookmaker.h | 62 ++++++++++-- tools/bookmaker/definition.cpp | 3 - tools/bookmaker/mdOut.cpp | 187 ++++++++++++++++++++++++++++------- tools/bookmaker/selfCheck.cpp | 15 +-- tools/bookmaker/spellCheck.cpp | 2 - 6 files changed, 353 insertions(+), 131 deletions(-) (limited to 'tools/bookmaker') 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 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 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& 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& data); + void rowOut(const char * name, const string& description); + void subtopicOut(vector& data); + void subtopicsOut(); + + struct TableContents { + string fDescription; + vector fMembers; + }; + + unordered_map fPopulators; + vector 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(" 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("
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 classesAndStructs; - vector constants; - vector constructors; - vector memberFunctions; - vector members; - vector operators; - vector 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& data) { + const Definition* csParent = this->csParent(); + SkASSERT(csParent); + fRoot = csParent->asRoot(); + this->rowOut("name", "description"); + this->rowOut("---", "---"); + std::map 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: -- cgit v1.2.3