aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-02-06 09:41:53 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-06 15:20:25 +0000
commit4855f78dd16ad50003ec537c98062e24a831cd45 (patch)
tree9566730a4f8416078131a0dc8255aecdeb9e3bf3 /tools/bookmaker
parent2aa5bab573cff2d9bfb40f7af6014a93bf2d4fda (diff)
fix bookmaker nightly
- mark the interfaces that use SkMask as deprecated - add more autogenerated subtopics - make subtopic names singular, avoiding collision with Skia names - simplify #Deprecated and #Bug tags - add "#Deprecated soon" to note things to be deprecated - fix some spelling errors - refresh web docs - add self-check functionality to find methods outside subtopics TBR=caryclark@google.com Docs-Preview: https://skia.org/?cl=102150 Bug: skia:6898 Change-Id: I0e742a56d49dccd4409bb68eed9167c8ad7611ce Reviewed-on: https://skia-review.googlesource.com/102150 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.cpp44
-rw-r--r--tools/bookmaker/bookmaker.h44
-rw-r--r--tools/bookmaker/definition.cpp17
-rw-r--r--tools/bookmaker/includeWriter.cpp38
-rw-r--r--tools/bookmaker/mdOut.cpp61
-rw-r--r--tools/bookmaker/selfCheck.cpp394
-rw-r--r--tools/bookmaker/spellCheck.cpp45
7 files changed, 197 insertions, 446 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index 0de8a46f3a..9d5a2782f3 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -248,7 +248,6 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
case MarkType::kDescription:
case MarkType::kStdOut:
// may be one-liner
- case MarkType::kBug:
case MarkType::kNoExample:
case MarkType::kParam:
case MarkType::kReturn:
@@ -285,7 +284,6 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
}
// not one-liners
case MarkType::kCode:
- case MarkType::kDeprecated:
case MarkType::kExample:
case MarkType::kExperimental:
case MarkType::kFormula:
@@ -344,7 +342,9 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
// always treated as one-liners (can't detect misuse easily)
case MarkType::kAlias:
case MarkType::kAnchor:
+ case MarkType::kBug:
case MarkType::kDefine:
+ case MarkType::kDeprecated:
case MarkType::kDuration:
case MarkType::kFile:
case MarkType::kHeight:
@@ -361,6 +361,7 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
case MarkType::kTime:
case MarkType::kVolatile:
case MarkType::kWidth:
+ // todo : add check disallowing children?
if (hasEnd && MarkType::kAnchor != markType && MarkType::kLine != markType) {
return this->reportError<bool>("one liners omit end element");
} else if (!hasEnd && MarkType::kAnchor == markType) {
@@ -415,7 +416,15 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
definition->fContentEnd = text->fContentEnd;
definition->fTerminator = fChar;
definition->fChildren.emplace_back(text);
- }
+ } else if (MarkType::kDeprecated == markType) {
+ this->skipSpace();
+ fParent->fDeprecated = true;
+ fParent->fToBeDeprecated = this->skipExact("soon");
+ this->skipSpace();
+ if ('\n' != this->peek()) {
+ return this->reportError<bool>("unexpected text after #Deprecated");
+ }
+ }
break;
case MarkType::kExternal:
(void) this->collectExternals(); // FIXME: detect errors in external defs?
@@ -1250,6 +1259,20 @@ TextParser::TextParser(const Definition* definition) :
definition->fLineCount) {
}
+string TextParser::ReportFilename(string file) {
+ string fullName;
+#ifdef SK_BUILD_FOR_WIN
+ TCHAR pathChars[MAX_PATH];
+ DWORD pathLen = GetCurrentDirectory(MAX_PATH, pathChars);
+ for (DWORD index = 0; index < pathLen; ++index) {
+ fullName += pathChars[index] == (char)pathChars[index] ? (char)pathChars[index] : '?';
+ }
+ fullName += '\\';
+#endif
+ fullName += file;
+ return fullName;
+}
+
void TextParser::reportError(const char* errorStr) const {
this->reportWarning(errorStr);
SkDebugf(""); // convenient place to set a breakpoint
@@ -1265,17 +1288,8 @@ void TextParser::reportWarning(const char* errorStr) const {
spaces -= lineLen;
lineLen = err.lineLength();
}
- string fileName;
-#ifdef SK_BUILD_FOR_WIN
- TCHAR pathChars[MAX_PATH];
- DWORD pathLen = GetCurrentDirectory(MAX_PATH, pathChars);
- for (DWORD index = 0; index < pathLen; ++index) {
- fileName += pathChars[index] == (char)pathChars[index] ? (char)pathChars[index] : '?';
- }
- fileName += '\\';
-#endif
- fileName += fFileName;
- SkDebugf("\n%s(%zd): error: %s\n", fileName.c_str(), err.fLineCount, errorStr);
+ string fullName = this->ReportFilename(fFileName);
+ SkDebugf("\n%s(%zd): error: %s\n", fullName.c_str(), err.fLineCount, errorStr);
if (0 == lineLen) {
SkDebugf("[blank line]\n");
} else {
@@ -1476,7 +1490,6 @@ vector<string> BmhParser::typeName(MarkType markType, bool* checkEnd) {
this->skipNoName();
break;
case MarkType::kCode:
- case MarkType::kDeprecated:
case MarkType::kDescription:
case MarkType::kDoxygen:
case MarkType::kExperimental:
@@ -1498,6 +1511,7 @@ vector<string> BmhParser::typeName(MarkType markType, bool* checkEnd) {
case MarkType::kBug: // fixme: expect number
case MarkType::kDefine:
case MarkType::kDefinedBy:
+ case MarkType::kDeprecated:
case MarkType::kDuration:
case MarkType::kFile:
case MarkType::kHeight:
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 65e8f1562a..96372756a1 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -390,6 +390,7 @@ public:
}
void reportError(const char* errorStr) const;
+ static string ReportFilename(string file);
void reportWarning(const char* errorStr) const;
template <typename T> T reportError(const char* errorStr) const {
@@ -841,6 +842,7 @@ public:
bool exampleToScript(string* result, ExampleOptions ) const;
string extractText(TrimExtract trimExtract) const;
string fiddleName() const;
+ const Definition* findClone(string match) const;
string formatFunction() const;
const Definition* hasChild(MarkType markType) const;
bool hasMatch(const string& name) const;
@@ -919,9 +921,11 @@ public:
Type fType = Type::kNone;
bool fClone = false;
bool fCloned = false;
+ bool fDeprecated = false;
bool fOperatorConst = false;
bool fPrivate = false;
bool fShort = false;
+ bool fToBeDeprecated = false;
bool fMemberStart = false;
bool fAnonymous = false;
mutable bool fVisited = false;
@@ -2034,15 +2038,15 @@ 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* kClassesAndStructs = "Class_or_Struct";
+ static constexpr const char* kConstants = "Constant";
+ static constexpr const char* kConstructors = "Constructor";
+ static constexpr const char* kMemberFunctions = "Member_Function";
+ static constexpr const char* kMembers = "Member";
+ static constexpr const char* kOperators = "Operator";
static constexpr const char* kOverview = "Overview";
- static constexpr const char* kRelatedFunctions = "Related_Functions";
- static constexpr const char* kSubtopics = "Subtopics";
+ static constexpr const char* kRelatedFunctions = "Related_Function";
+ static constexpr const char* kSubtopics = "Subtopic";
private:
enum class TableState {
@@ -2051,6 +2055,16 @@ private:
kColumn,
};
+ struct TableContents {
+ TableContents()
+ : fShowClones(false) {
+ }
+
+ string fDescription;
+ vector<const Definition*> fMembers;
+ bool fShowClones;
+ };
+
string addReferences(const char* start, const char* end, BmhParser::Resolvable );
bool buildRefFromFile(const char* fileName, const char* outDir);
bool checkParamReturnBody(const Definition* def) const;
@@ -2068,8 +2082,11 @@ private:
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;
+ TableContents& populator(const char* key) {
+ auto entry = fPopulators.find(key);
+ // FIXME: this should have been detected earlier
+ SkASSERT(fPopulators.end() != entry);
+ return entry->second;
}
void reset() override {
@@ -2103,14 +2120,9 @@ private:
void resolveOut(const char* start, const char* end, BmhParser::Resolvable );
void rowOut(const char * name, const string& description);
- void subtopicOut(vector<const Definition*>& data);
+ void subtopicOut(const TableContents& tableContents);
void subtopicsOut();
- struct TableContents {
- string fDescription;
- vector<const Definition*> fMembers;
- };
-
unordered_map<string, TableContents> fPopulators;
vector<const Definition*> fClassStack;
diff --git a/tools/bookmaker/definition.cpp b/tools/bookmaker/definition.cpp
index 7885c6301c..757169b1a9 100644
--- a/tools/bookmaker/definition.cpp
+++ b/tools/bookmaker/definition.cpp
@@ -560,6 +560,7 @@ bool Definition::exampleToScript(string* result, ExampleOptions exampleOptions)
break;
case MarkType::kToDo:
break;
+ case MarkType::kBug:
case MarkType::kMarkChar:
case MarkType::kPlatform:
// ignore for now
@@ -1014,6 +1015,22 @@ string Definition::fiddleName() const {
return fFiddle.substr(start, end - start);
}
+const Definition* Definition::findClone(string match) const {
+ for (auto child : fChildren) {
+ if (!child->fClone) {
+ continue;
+ }
+ if (match == child->fName) {
+ return child;
+ }
+ auto inner = child->findClone(match);
+ if (inner) {
+ return inner;
+ }
+ }
+ return nullptr;
+}
+
const Definition* Definition::hasChild(MarkType markType) const {
for (auto iter : fChildren) {
if (markType == iter->fMarkType) {
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index ba93d3e615..77baca0016 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -53,6 +53,13 @@ void IncludeWriter::descriptionOut(const Definition* def) {
commentStart = prop->fTerminator;
break;
case MarkType::kDeprecated:
+ SkASSERT(def->fDeprecated);
+ if (def->fToBeDeprecated) {
+ this->writeString("To be deprecated soon.");
+ } else {
+ this->writeString("Deprecated.");
+ }
+ this->lfcr();
case MarkType::kPrivate:
commentLen = (int) (prop->fStart - commentStart);
if (commentLen > 0) {
@@ -62,6 +69,9 @@ void IncludeWriter::descriptionOut(const Definition* def) {
}
}
commentStart = prop->fContentStart;
+ if (def->fToBeDeprecated) {
+ commentStart += 4; // skip over "soon" // FIXME: this is awkward
+ }
commentLen = (int) (prop->fContentEnd - commentStart);
if (commentLen > 0) {
this->writeBlockIndent(commentLen, commentStart);
@@ -159,7 +169,7 @@ void IncludeWriter::descriptionOut(const Definition* def) {
break;
}
}
- SkASSERT(wroteCode || (commentLen > 0 && commentLen < 1500));
+ SkASSERT(wroteCode || (commentLen > 0 && commentLen < 1500) || def->fDeprecated);
if (commentLen > 0) {
this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
}
@@ -440,23 +450,35 @@ void IncludeWriter::enumMembersOut(const RootDefinition* root, Definition& child
commentEnd = currentEnumItem->fContentEnd;
}
TextParser enumComment(fFileName, commentStart, commentEnd, currentEnumItem->fLineCount);
+ bool isDeprecated = false;
if (enumComment.skipToLineStart()) { // skip const value
commentStart = enumComment.fChar;
commentLen = (int) (commentEnd - commentStart);
} else {
- const Definition* privateDef = currentEnumItem->fChildren[0];
- SkASSERT(MarkType::kPrivate == privateDef->fMarkType);
- commentStart = privateDef->fContentStart;
- commentLen = (int) (privateDef->fContentEnd - privateDef->fContentStart);
+ const Definition* childDef = currentEnumItem->fChildren[0];
+ isDeprecated = MarkType::kDeprecated == childDef->fMarkType;
+ if (MarkType::kPrivate == childDef->fMarkType || isDeprecated) {
+ commentStart = childDef->fContentStart;
+ if (currentEnumItem->fToBeDeprecated) {
+ SkASSERT(isDeprecated);
+ commentStart += 4; // skip over "soon" // FIXME: this is awkward
+ }
+ commentLen = (int) (childDef->fContentEnd - commentStart);
+ }
}
// FIXME: may assert here if there's no const value
// should have detected and errored on that earlier when enum fContentStart was set
- SkASSERT(commentLen > 0 && commentLen < 1000);
+ SkASSERT((commentLen > 0 && commentLen < 1000) || isDeprecated);
if (!currentEnumItem->fShort) {
this->writeCommentHeader();
fIndent += 4;
- bool wroteLineFeed = Wrote::kLF ==
- this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
+ bool wroteLineFeed = false;
+ if (isDeprecated) {
+ this->writeString(currentEnumItem->fToBeDeprecated
+ ? "To be deprecated soon." : "Deprecated.");
+ }
+ wroteLineFeed = Wrote::kLF ==
+ this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
fIndent -= 4;
if (wroteLineFeed || fColumn > 100 - 3 /* space * / */ ) {
this->lfcr();
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index b51bb8d77e..7bc70af669 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -975,9 +975,6 @@ void MdOut::markTypeOut(Definition* def) {
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;
@@ -1187,17 +1184,20 @@ void MdOut::mdHeaderOutLF(int depth, int lf) {
void MdOut::populateTables(const Definition* def) {
const Definition* csParent = this->csParent();
for (auto child : def->fChildren) {
+ if (string::npos != child->fName.find("Rect_Set")) {
+ SkDebugf("");
+ }
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->populator(kRelatedFunctions).fMembers.push_back(child);
}
this->populateTables(child);
continue;
}
if (child->isStructOrClass()) {
if (fClassStack.size() > 0) {
- this->populator(kClassesAndStructs).push_back(child);
+ this->populator(kClassesAndStructs).fMembers.push_back(child);
}
fClassStack.push_back(child);
this->populateTables(child);
@@ -1205,11 +1205,11 @@ void MdOut::populateTables(const Definition* def) {
continue;
}
if (MarkType::kEnum == child->fMarkType || MarkType::kEnumClass == child->fMarkType) {
- this->populator(kConstants).push_back(child);
+ this->populator(kConstants).fMembers.push_back(child);
continue;
}
if (MarkType::kMember == child->fMarkType) {
- this->populator(kMembers).push_back(child);
+ this->populator(kMembers).fMembers.push_back(child);
continue;
}
if (MarkType::kMethod != child->fMarkType) {
@@ -1220,17 +1220,26 @@ void MdOut::populateTables(const Definition* def) {
}
if (Definition::MethodType::kConstructor == child->fMethodType
|| Definition::MethodType::kDestructor == child->fMethodType) {
- this->populator(kConstructors).push_back(child);
+ this->populator(kConstructors).fMembers.push_back(child);
continue;
}
if (Definition::MethodType::kOperator == child->fMethodType) {
- this->populator(kOperators).push_back(child);
+ this->populator(kOperators).fMembers.push_back(child);
continue;
}
- this->populator(kMemberFunctions).push_back(child);
+ this->populator(kMemberFunctions).fMembers.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);
+ this->populator(kConstructors).fMembers.push_back(child);
+ continue;
+ }
+ for (auto item : child->fChildren) {
+ if (MarkType::kIn == item->fMarkType) {
+ string name(item->fContentStart, item->fContentEnd - item->fContentStart);
+ fPopulators[name].fMembers.push_back(child);
+ fPopulators[name].fShowClones = true;
+ break;
+ }
}
}
}
@@ -1331,7 +1340,7 @@ void MdOut::subtopicsOut() {
this->rowOut("---", "---");
for (auto item : { kClassesAndStructs, kConstants, kConstructors, kMemberFunctions,
kMembers, kOperators, kRelatedFunctions } ) {
- for (auto entry : this->populator(item)) {
+ for (auto entry : this->populator(item).fMembers) {
if (entry->csParent() == csParent) {
string description = fPopulators.find(item)->second.fDescription;
if (kConstructors == item) {
@@ -1344,7 +1353,8 @@ void MdOut::subtopicsOut() {
}
}
-void MdOut::subtopicOut(vector<const Definition*>& data) {
+void MdOut::subtopicOut(const TableContents& tableContents) {
+ const auto& data = tableContents.fMembers;
const Definition* csParent = this->csParent();
SkASSERT(csParent);
fRoot = csParent->asRoot();
@@ -1360,6 +1370,9 @@ void MdOut::subtopicOut(vector<const Definition*>& data) {
items[name] = entry;
}
for (auto entry : items) {
+ if (entry.second->fDeprecated) {
+ continue;
+ }
const Definition* oneLiner = nullptr;
for (auto child : entry.second->fChildren) {
if (MarkType::kLine == child->fMarkType) {
@@ -1367,8 +1380,30 @@ void MdOut::subtopicOut(vector<const Definition*>& data) {
break;
}
}
+ if (!oneLiner) {
+ SkDebugf("");
+ }
SkASSERT(oneLiner);
this->rowOut(entry.first.c_str(), string(oneLiner->fContentStart,
oneLiner->fContentEnd - oneLiner->fContentStart));
+ if (string::npos != entry.second->fName.find("SkRect::set")) {
+ SkDebugf("");
+ }
+ if (tableContents.fShowClones && entry.second->fCloned) {
+ int cloneNo = 2;
+ string builder = entry.second->fName;
+ if ("()" == builder.substr(builder.length() - 2)) {
+ builder = builder.substr(0, builder.length() - 2);
+ }
+ builder += '_';
+ do {
+ string match = builder + to_string(cloneNo);
+ auto child = csParent->findClone(match);
+ if (!child) {
+ break;
+ }
+ this->rowOut("", child->methodName());
+ } while (++cloneNo);
+ }
}
}
diff --git a/tools/bookmaker/selfCheck.cpp b/tools/bookmaker/selfCheck.cpp
index fd8ef59fa1..3392945a9f 100644
--- a/tools/bookmaker/selfCheck.cpp
+++ b/tools/bookmaker/selfCheck.cpp
@@ -7,11 +7,12 @@
#include "bookmaker.h"
+#ifdef SK_BUILD_FOR_WIN
+#include <windows.h>
+#endif
// Check that mutiple like-named methods are under one Subtopic
-// Check that all subtopics are in table of contents
-
// Check that SeeAlso reference each other
// Would be nice to check if other classes have 'create' methods that are included
@@ -33,27 +34,10 @@ public:
return fBmhParser.reportError<bool>("expected root topic");
}
fRoot = topicDef->asRoot();
- if (!this->checkMethodSummary()) {
- return false;
- }
- if (!this->checkMethodSubtopic()) {
- return false;
- }
- if (!this->checkSubtopicSummary()) {
- return false;
- }
- if (!this->checkConstructorsSummary()) {
- return false;
- }
- if (!this->checkOperatorsSummary()) {
- return false;
- }
if (!this->checkSeeAlso()) {
return false;
}
- if (!this->checkCreators()) {
- return false;
- }
+ // report functions that are not covered by related hierarchy
if (!this->checkRelatedFunctions()) {
return false;
}
@@ -62,164 +46,8 @@ public:
}
protected:
- // Check that all constructors are in a table of contents
- // should be 'creators' instead of constructors?
- bool checkConstructorsSummary() {
- for (auto& rootChild : fRoot->fChildren) {
- if (!rootChild->isStructOrClass()) {
- continue;
- }
- auto& cs = rootChild;
- auto constructors = this->findTopic("Constructors", Optional::kYes);
- if (constructors && MarkType::kSubtopic != constructors->fMarkType) {
- return constructors->reportError<bool>("expected #Subtopic Constructors");
- }
- vector<string> constructorEntries;
- if (constructors) {
- if (!this->collectEntries(constructors, &constructorEntries)) {
- return false;
- }
- }
- // mark corresponding methods as visited (may be more than one per entry)
- for (auto& csChild : cs->fChildren) {
- if (MarkType::kMethod != csChild->fMarkType) {
- // only check methods for now
- continue;
- }
- string name;
- if (!this->childName(csChild, &name)) {
- return false;
- }
- string returnType;
- if (Definition::MethodType::kConstructor != csChild->fMethodType &&
- Definition::MethodType::kDestructor != csChild->fMethodType) {
- string makeCheck = name.substr(0, 4);
- if ("Make" != makeCheck && "make" != makeCheck) {
- continue;
- }
- // for now, assume return type of interest is first word to start Sk
- string search(csChild->fStart, csChild->fContentStart - csChild->fStart);
- auto end = search.find(makeCheck);
- if (string::npos == end) {
- return csChild->reportError<bool>("expected Make in content");
- }
- search = search.substr(0, end);
- if (string::npos == search.find(cs->fName)) {
- // if return value doesn't match current struct or class, look in
- // returned struct / class instead
- auto sk = search.find("Sk");
- if (string::npos != sk) {
- // todo: build class name, find it, search for match in its overview
- continue;
- }
- }
- }
- if (constructorEntries.end() ==
- std::find(constructorEntries.begin(), constructorEntries.end(), name)) {
- return csChild->reportError<bool>("missing constructor in Constructors");
- }
- }
- }
- return true;
- }
-
- bool checkCreators() {
- return true;
- }
-
- bool checkMethodSubtopic() {
- return true;
- }
-
- // Check that summary contains all methods
- bool checkMethodSummary() {
- // look for struct or class in fChildren
- const Definition* cs = this->classOrStruct();
- if (!cs) {
- return true; // topics may not have included classes or structs
- }
- auto memberFunctions = this->findTopic("Member_Functions", Optional::kNo);
- if (MarkType::kSubtopic != memberFunctions->fMarkType) {
- return memberFunctions->reportError<bool>("expected #Subtopic Member_Functions");
- }
- vector<string> methodEntries; // build map of overview entries
- if (!this->collectEntries(memberFunctions, &methodEntries)) {
- return false;
- }
- // mark corresponding methods as visited (may be more than one per entry)
- 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;
- }
- string name;
- if (!this->childName(csChild, &name)) {
- return false;
- }
- if (methodEntries.end() ==
- std::find(methodEntries.begin(), methodEntries.end(), name)) {
- return csChild->reportError<bool>("missing method in Member_Functions");
- }
- }
- return true;
- }
-
- // Check that all operators are in a table of contents
- bool checkOperatorsSummary() {
- 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;
- }
- 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");
- }
- }
- 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) {
@@ -243,36 +71,28 @@ protected:
// 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();
- }
+ bool containsMarkTypeIn = csChild->fDeprecated; // no markup for deprecated
+ for (auto child : csChild->fChildren) {
+ if (MarkType::kIn == child->fMarkType) {
+ containsMarkTypeIn = true;
+ break;
+ }
+ }
+ if (!containsMarkTypeIn) {
+#ifdef SK_BUILD_FOR_WIN
+ /* SkDebugf works in both visual studio and git shell, but
+ in git shell output is not piped to grep.
+ printf does not generate output in visual studio, but
+ does in git shell and can be piped.
+ */
+ if (IsDebuggerPresent()) {
+ SkDebugf("No #In: %s\n", csChild->fName.c_str());
+ } else
+#endif
+ printf("No #In: %s\n", csChild->fName.c_str());
+ }
}
}
- if (trim.size() > 0) {
- return cs->reportError<bool>("extra method");
- }
return true;
}
@@ -280,81 +100,6 @@ protected:
return true;
}
- bool checkSubtopicSummary() {
- 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;
- }
- 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");
- }
- }
- return true;
- }
-
- bool childName(const Definition* def, string* name) {
- auto start = def->fName.find_last_of(':');
- start = string::npos == start ? 0 : start + 1;
- *name = def->fName.substr(start);
- if (def->fClone) {
- auto lastUnderline = name->find_last_of('_');
- if (string::npos == lastUnderline) {
- return def->reportError<bool>("expect _ in name");
- }
- if (lastUnderline + 1 >= name->length()) {
- return def->reportError<bool>("expect char after _ in name");
- }
- for (auto index = lastUnderline + 1; index < name->length(); ++index) {
- if (!isdigit((*name)[index])) {
- return def->reportError<bool>("expect digit after _ in name");
- }
- }
- *name = name->substr(0, lastUnderline);
- bool allLower = true;
- for (auto ch : *name) {
- allLower &= (bool) islower(ch);
- }
- if (allLower) {
- *name += "()";
- }
- }
- return true;
- }
-
const Definition* classOrStruct() {
for (auto& rootChild : fRoot->fChildren) {
if (rootChild->isStructOrClass()) {
@@ -364,102 +109,11 @@ protected:
return nullptr;
}
- static const Definition* overview_def(const Definition* parent) {
- Definition* overview = nullptr;
- if (parent) {
- for (auto& csChild : parent->fChildren) {
- if ("Overview" == csChild->fName) {
- if (overview) {
- return csChild->reportError<const Definition*>("expected only one Overview");
- }
- overview = csChild;
- }
- }
- }
- return overview;
- }
-
- 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 = parent ? overview_def(parent->fParent) : nullptr;
- if (overview && parentOverview) {
- return overview->reportError<const Definition*>("expected only one Overview 2");
- }
- overview = overview ? overview : parentOverview;
- if (!overview) {
- return parent->reportError<const Definition*>("missing #Topic Overview");
- }
- return overview;
- }
-
enum class Optional {
kNo,
kYes,
};
- const Definition* findTopic(string name, Optional optional) {
- 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_" + undashed; // legacy form for now
- topicKeyIter = fBmhParser.fTopicMap.find(topicKey);
- if (fBmhParser.fTopicMap.end() == topicKeyIter) {
- if (Optional::kNo == optional) {
- return fRoot->reportError<Definition*>("missing subtopic");
- }
- return nullptr;
- }
- }
- return topicKeyIter->second;
- }
-
- bool collectEntries(const Definition* entries, vector<string>* strings) {
- const Definition* table = nullptr;
- for (auto& child : entries->fChildren) {
- if (MarkType::kTable == child->fMarkType && child->fName == entries->fName) {
- table = child;
- break;
- }
- }
- if (!table) {
- return entries->reportError<bool>("missing #Table in Overview Subtopic");
- }
- bool expectLegend = true;
- string prior = " "; // expect entries to be alphabetical
- for (auto& row : table->fChildren) {
- if (MarkType::kLegend == row->fMarkType) {
- if (!expectLegend) {
- return row->reportError<bool>("expect #Legend only once");
- }
- // todo: check if legend format matches table's rows' format
- expectLegend = false;
- } else if (expectLegend) {
- return row->reportError<bool>("expect #Legend first");
- }
- if (MarkType::kRow != row->fMarkType) {
- continue; // let anything through for now; can tighten up in the future
- }
- // expect column 0 to point to function name
- Definition* column0 = row->fChildren[0];
- string name = string(column0->fContentStart,
- column0->fContentEnd - column0->fContentStart);
- if (prior > name) {
- return row->reportError<bool>("expect alphabetical order");
- }
- if (prior == name) {
- return row->reportError<bool>("expect unique names");
- }
- // todo: error if name is all lower case and doesn't end in ()
- strings->push_back(name);
- prior = name;
- }
- return true;
- }
-
private:
const BmhParser& fBmhParser;
RootDefinition* fRoot;
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index 0daa4602ad..efc79ca528 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -53,7 +53,6 @@ private:
INHERITED::resetCommon();
fMethod = nullptr;
fRoot = nullptr;
- fTableState = TableState::kNone;
fInCode = false;
fInConst = false;
fInFormula = false;
@@ -74,7 +73,7 @@ private:
const BmhParser& fBmhParser;
Definition* fMethod;
RootDefinition* fRoot;
- TableState fTableState;
+ int fLocalLine;
bool fInCode;
bool fInConst;
bool fInDescription;
@@ -136,10 +135,6 @@ bool SpellCheck::check(Definition* def) {
fLineCount = def->fLineCount;
string printable = def->printableName();
const char* textStart = def->fContentStart;
- if (MarkType::kParam != def->fMarkType && MarkType::kConst != def->fMarkType &&
- MarkType::kPrivate != def->fMarkType && TableState::kNone != fTableState) {
- fTableState = TableState::kNone;
- }
switch (def->fMarkType) {
case MarkType::kAlias:
break;
@@ -159,12 +154,6 @@ bool SpellCheck::check(Definition* def) {
break;
case MarkType::kConst: {
fInConst = true;
- if (TableState::kNone == fTableState) {
- fTableState = TableState::kRow;
- }
- if (TableState::kRow == fTableState) {
- fTableState = TableState::kColumn;
- }
this->wordCheck(def->fName);
const char* lineEnd = strchr(textStart, '\n');
this->wordCheck(lineEnd - textStart, textStart);
@@ -204,8 +193,12 @@ bool SpellCheck::check(Definition* def) {
break;
case MarkType::kImage:
break;
+ case MarkType::kIn:
+ break;
case MarkType::kLegend:
break;
+ case MarkType::kLine:
+ break;
case MarkType::kLink:
break;
case MarkType::kList:
@@ -225,7 +218,6 @@ bool SpellCheck::check(Definition* def) {
if (!def->isClone() && Definition::MethodType::kOperator != def->fMethodType) {
this->wordCheck(method_name);
}
- fTableState = TableState::kNone;
fMethod = def;
} break;
case MarkType::kNoExample:
@@ -233,12 +225,6 @@ bool SpellCheck::check(Definition* def) {
case MarkType::kOutdent:
break;
case MarkType::kParam: {
- if (TableState::kNone == fTableState) {
- fTableState = TableState::kRow;
- }
- if (TableState::kRow == fTableState) {
- fTableState = TableState::kColumn;
- }
TextParser paramParser(def->fFileName, def->fStart, def->fContentStart,
def->fLineCount);
paramParser.skipWhiteSpace();
@@ -254,6 +240,8 @@ bool SpellCheck::check(Definition* def) {
} break;
case MarkType::kPlatform:
break;
+ case MarkType::kPopulate:
+ break;
case MarkType::kPrivate:
break;
case MarkType::kReturn:
@@ -262,6 +250,8 @@ bool SpellCheck::check(Definition* def) {
break;
case MarkType::kSeeAlso:
break;
+ case MarkType::kSet:
+ break;
case MarkType::kStdOut: {
fInStdOut = true;
TextParser code(def);
@@ -336,8 +326,6 @@ bool SpellCheck::check(Definition* def) {
case MarkType::kConst:
fInConst = false;
case MarkType::kParam:
- SkASSERT(TableState::kColumn == fTableState);
- fTableState = TableState::kRow;
break;
case MarkType::kReturn:
case MarkType::kSeeAlso:
@@ -390,6 +378,7 @@ void SpellCheck::leafCheck(const char* start, const char* end) {
const char* wordStart = nullptr;
const char* wordEnd = nullptr;
const char* possibleEnd = nullptr;
+ fLocalLine = 0;
do {
if (wordStart && wordEnd) {
if (!allLower || (!inQuotes && '\"' != lastCh && !inParens
@@ -457,6 +446,9 @@ void SpellCheck::leafCheck(const char* start, const char* end) {
allLower = false;
case '-': // note that dash doesn't clear allLower
break;
+ case '\n':
+ ++fLocalLine;
+ // fall through
default:
wordEnd = chPtr;
break;
@@ -492,7 +484,8 @@ void SpellCheck::report(SkCommandLineFlags::StringArray report) {
continue;
}
if (iter.second.fCount == 1) {
- SkDebugf("%s(%d): %s\n", iter.second.fFile.c_str(), iter.second.fLine,
+ string fullName = this->ReportFilename(iter.second.fFile);
+ SkDebugf("%s(%d): %s\n", fullName.c_str(), iter.second.fLine,
iter.first.c_str());
}
}
@@ -562,7 +555,8 @@ void SpellCheck::report(SkCommandLineFlags::StringArray report) {
break;
}
if (check.compare(mispelled) == 0) {
- SkDebugf("%s(%d): %s\n", iter.second.fFile.c_str(), iter.second.fLine,
+ string fullName = this->ReportFilename(iter.second.fFile);
+ SkDebugf("%s(%d): %s\n", fullName.c_str(), iter.second.fLine,
iter.first.c_str());
if (report.count() == ++index) {
break;
@@ -651,9 +645,12 @@ void SpellCheck::wordCheck(const string& str) {
if (mappy.end() != iter) {
iter->second.fCount += 1;
} else {
+ if ("offscreen" == str) {
+ SkDebugf("");
+ }
CheckEntry* entry = &mappy[str];
entry->fFile = fFileName;
- entry->fLine = fLineCount;
+ entry->fLine = fLineCount + fLocalLine;
entry->fCount = 1;
}
}