generate tables instead of manual entry
- make descriptions of table entries phrases instead of sentences;
lower case start, no ending period (not enforced, yet)
- add #Line markup to move one line descriptions to the #Method
body. Later, will generate tables like Member_Functions from this
- add #In markup to associate a #Method with a #Subtopic. Later, will
generate tables of related methods from this
- remove return type from operator overloads in tables
- add new colorTypes to examples that index into arrays of strings
to name them
Docs-Preview: https://skia.org/?cl=100422
TBR=caryclark@google.com
Bug: skia:6898
Change-Id: I8558048866369f419f1944832b99c05da3fd52bb
Reviewed-on: https://skia-review.googlesource.com/100422
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
diff --git a/tools/bookmaker/selfCheck.cpp b/tools/bookmaker/selfCheck.cpp
index 16db3da..f30a582 100644
--- a/tools/bookmaker/selfCheck.cpp
+++ b/tools/bookmaker/selfCheck.cpp
@@ -54,6 +54,9 @@
if (!this->checkCreators()) {
return false;
}
+ if (!this->checkRelatedFunctions()) {
+ return false;
+ }
}
return true;
}
@@ -131,14 +134,7 @@
// Check that summary contains all methods
bool checkMethodSummary() {
// look for struct or class in fChildren
- Definition* cs = nullptr;
- for (auto& rootChild : fRoot->fChildren) {
- if (!this->isStructOrClass(rootChild)) {
- continue;
- }
- cs = rootChild;
- // expect Overview as Topic in every main class or struct or its parent
- }
+ const Definition* cs = this->classOrStruct();
if (!cs) {
return true; // topics may not have included classes or structs
}
@@ -179,91 +175,152 @@
// Check that all operators are in a table of contents
bool checkOperatorsSummary() {
- for (auto& rootChild : fRoot->fChildren) {
- if (!this->isStructOrClass(rootChild)) {
+ const Definition* cs = this->classOrStruct();
+ if (!cs) {
+ return true; // topics may not have included classes or structs
+ }
+ const Definition* operators = this->findTopic("Operators", Optional::kYes);
+ if (operators && MarkType::kSubtopic != operators->fMarkType) {
+ return operators->reportError<bool>("expected #Subtopic Operators");
+ }
+ vector<string> operatorEntries;
+ if (operators) {
+ if (!this->collectEntries(operators, &operatorEntries)) {
+ return false;
+ }
+ }
+ for (auto& csChild : cs->fChildren) {
+ if (Definition::MethodType::kOperator != csChild->fMethodType) {
continue;
}
- auto& cs = rootChild;
- const Definition* operators = this->findTopic("Operators", Optional::kYes);
- if (operators && MarkType::kSubtopic != operators->fMarkType) {
- return operators->reportError<bool>("expected #Subtopic Operators");
+ string name;
+ if (!this->childName(csChild, &name)) {
+ return false;
}
- vector<string> operatorEntries;
- if (operators) {
- if (!this->collectEntries(operators, &operatorEntries)) {
- return false;
+ bool found = false;
+ for (auto str : operatorEntries) {
+ if (string::npos != str.find(name)) {
+ found = true;
+ break;
}
}
- for (auto& csChild : cs->fChildren) {
- if (Definition::MethodType::kOperator != csChild->fMethodType) {
- continue;
- }
- string name;
- if (!this->childName(csChild, &name)) {
- return false;
- }
- bool found = false;
- for (auto str : operatorEntries) {
- if (string::npos != str.find(name)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return csChild->reportError<bool>("missing operator in Operators");
- }
+ if (!found) {
+ return csChild->reportError<bool>("missing operator in Operators");
}
}
return true;
}
+ bool checkRelatedFunctions() {
+ auto related = this->findTopic("Related_Functions", Optional::kYes);
+ if (!related) {
+ return true;
+ }
+ vector<string> relatedEntries;
+ if (!this->collectEntries(related, &relatedEntries)) {
+ return false;
+ }
+ const Definition* cs = this->classOrStruct();
+ vector<string> methodNames;
+ if (cs) {
+ string prefix = cs->fName + "::";
+ for (auto& csChild : cs->fChildren) {
+ if (MarkType::kMethod != csChild->fMarkType) {
+ // only check methods for now
+ continue;
+ }
+ if (Definition::MethodType::kConstructor == csChild->fMethodType) {
+ continue;
+ }
+ if (Definition::MethodType::kDestructor == csChild->fMethodType) {
+ continue;
+ }
+ if (Definition::MethodType::kOperator == csChild->fMethodType) {
+ continue;
+ }
+ if (csChild->fClone) {
+ // FIXME: check to see if all cloned methods are in table
+ // since format of clones is in flux, defer this check for now
+ continue;
+ }
+
+ SkASSERT(string::npos != csChild->fName.find(prefix));
+ string name = csChild->fName.substr(csChild->fName.find(prefix));
+ methodNames.push_back(name);
+ }
+ }
+ vector<string> trim = methodNames;
+ for (auto entryName : relatedEntries) {
+ auto entryDef = this->findTopic(entryName, Optional::kNo);
+ if (!entryDef) {
+
+ }
+ vector<string> entries;
+ this->collectEntries(entryDef, &entries);
+ for (auto entry : entries) {
+ auto it = std::find(methodNames.begin(), methodNames.end(), entry);
+ if (it == methodNames.end()) {
+ return cs->reportError<bool>("missing method");
+ }
+ it = std::find(trim.begin(), trim.end(), entry);
+ if (it != trim.end()) {
+ using std::swap;
+ swap(*it, trim.back());
+ trim.pop_back();
+ }
+ }
+ }
+ if (trim.size() > 0) {
+ return cs->reportError<bool>("extra method");
+ }
+ return true;
+ }
+
bool checkSeeAlso() {
return true;
}
bool checkSubtopicSummary() {
- for (auto& rootChild : fRoot->fChildren) {
- if (!this->isStructOrClass(rootChild)) {
+ const auto& cs = this->classOrStruct();
+ if (!cs) {
+ return true;
+ }
+ auto overview = this->findOverview(cs);
+ if (!overview) {
+ return false;
+ }
+ const Definition* subtopics = this->findTopic("Subtopics", Optional::kNo);
+ if (MarkType::kSubtopic != subtopics->fMarkType) {
+ return subtopics->reportError<bool>("expected #Subtopic Subtopics");
+ }
+ const Definition* relatedFunctions = this->findTopic("Related_Functions", Optional::kYes);
+ if (relatedFunctions && MarkType::kSubtopic != relatedFunctions->fMarkType) {
+ return relatedFunctions->reportError<bool>("expected #Subtopic Related_Functions");
+ }
+ vector<string> subtopicEntries;
+ if (!this->collectEntries(subtopics, &subtopicEntries)) {
+ return false;
+ }
+ if (relatedFunctions && !this->collectEntries(relatedFunctions, &subtopicEntries)) {
+ return false;
+ }
+ for (auto& csChild : cs->fChildren) {
+ if (MarkType::kSubtopic != csChild->fMarkType) {
continue;
}
- auto& cs = rootChild;
- auto overview = this->findOverview(cs);
- if (!overview) {
+ string name;
+ if (!this->childName(csChild, &name)) {
return false;
}
- const Definition* subtopics = this->findTopic("Subtopics", Optional::kNo);
- if (MarkType::kSubtopic != subtopics->fMarkType) {
- return subtopics->reportError<bool>("expected #Subtopic Subtopics");
- }
- const Definition* relatedFunctions = this->findTopic("Related_Functions", Optional::kYes);
- if (relatedFunctions && MarkType::kSubtopic != relatedFunctions->fMarkType) {
- return relatedFunctions->reportError<bool>("expected #Subtopic Related_Functions");
- }
- vector<string> subtopicEntries;
- if (!this->collectEntries(subtopics, &subtopicEntries)) {
- return false;
- }
- if (relatedFunctions && !this->collectEntries(relatedFunctions, &subtopicEntries)) {
- return false;
- }
- for (auto& csChild : cs->fChildren) {
- if (MarkType::kSubtopic != csChild->fMarkType) {
- continue;
+ bool found = false;
+ for (auto str : subtopicEntries) {
+ if (string::npos != str.find(name)) {
+ found = true;
+ break;
}
- string name;
- if (!this->childName(csChild, &name)) {
- return false;
- }
- bool found = false;
- for (auto str : subtopicEntries) {
- if (string::npos != str.find(name)) {
- found = true;
- break;
- }
- }
- if (!found) {
- return csChild->reportError<bool>("missing SubTopic in SubTopics");
- }
+ }
+ if (!found) {
+ return csChild->reportError<bool>("missing SubTopic in SubTopics");
}
}
return true;
@@ -298,6 +355,15 @@
return true;
}
+ const Definition* classOrStruct() {
+ for (auto& rootChild : fRoot->fChildren) {
+ if (this->isStructOrClass(rootChild)) {
+ return rootChild;
+ }
+ }
+ return nullptr;
+ }
+
static const Definition* overview_def(const Definition* parent) {
Definition* overview = nullptr;
if (parent) {
@@ -316,7 +382,7 @@
const Definition* findOverview(const Definition* parent) {
// expect Overview as Topic in every main class or struct
const Definition* overview = overview_def(parent);
- const Definition* parentOverview = overview_def(parent->fParent);
+ const Definition* parentOverview = parent ? overview_def(parent->fParent) : nullptr;
if (overview && parentOverview) {
return overview->reportError<const Definition*>("expected only one Overview 2");
}
@@ -333,11 +399,13 @@
};
const Definition* findTopic(string name, Optional optional) {
- string topicKey = fRoot->fName + '_' + name;
+ string undashed = name;
+ std::replace(undashed.begin(), undashed.end(), '-', '_');
+ string topicKey = fRoot->fName + '_' + undashed;
auto topicKeyIter = fBmhParser.fTopicMap.find(topicKey);
if (fBmhParser.fTopicMap.end() == topicKeyIter) {
// TODO: remove this and require member functions outside of overview
- topicKey = fRoot->fName + "_Overview_" + name; // legacy form for now
+ topicKey = fRoot->fName + "_Overview_" + undashed; // legacy form for now
topicKeyIter = fBmhParser.fTopicMap.find(topicKey);
if (fBmhParser.fTopicMap.end() == topicKeyIter) {
if (Optional::kNo == optional) {
@@ -392,7 +460,7 @@
return true;
}
- bool isStructOrClass(const Definition* definition) {
+ bool isStructOrClass(const Definition* definition) const {
if (MarkType::kStruct != definition->fMarkType &&
MarkType::kClass != definition->fMarkType) {
return false;