new batch of docs
new batch of docs
Docs-Preview: https://skia.org/?cl=141244
Bug: skia:
Change-Id: I5a285778baaee2734495374adeb7359d524e47e3
Reviewed-on: https://skia-review.googlesource.com/141244
Reviewed-by: Cary Clark <caryclark@skia.org>
Commit-Queue: Cary Clark <caryclark@skia.org>
Auto-Submit: Cary Clark <caryclark@skia.org>
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index 1b8e76e..c173c09 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -51,6 +51,8 @@
would rather keep links for body above #Literal, and/or make it a block and not a one-liner
add check to require #Const to contain #Code block if defining const or constexpr (enum consts have
#Code blocks inside the #Enum def)
+subclasses (e.g. Iter in SkPath) need to check for #Line and generate overview
+ subclass methods should also disallow #In
There are a number of formatting bugs with ad hoc patches where a substitution doesn't keep
the space before or after, or the linefeeds before or after. The rules are not very good either.
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 19ea86b..04b1c0f 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -42,6 +42,7 @@
kNone,
kSK_API,
kSK_BEGIN_REQUIRE_DENSE,
+ kAlignAs,
kBool,
kChar,
kClass,
@@ -1568,6 +1569,7 @@
fIncludeWord = nullptr;
}
+ bool inAlignAs() const;
void checkForMissingParams(const vector<string>& methodParams,
const vector<string>& foundParams);
bool checkForWord();
@@ -1580,11 +1582,13 @@
void dumpConst(const Definition& , string className);
void dumpDefine(const Definition& );
void dumpEnum(const Definition& , string name);
- bool dumpGlobals();
+ bool dumpGlobals(string* globalFileName, long int* globalTell);
void dumpMethod(const Definition& , string className);
void dumpMember(const Definition& );
bool dumpTokens();
- bool dumpTokens(string skClassName);
+ bool dumpTokens(string skClassName, string globalFileName, long int* globalTell);
+ void dumpTypedef(const Definition& , string className);
+
bool findComments(const Definition& includeDef, Definition* markupDef);
Definition* findIncludeObject(const Definition& includeDef, MarkType markType,
string typeName);
@@ -1593,6 +1597,7 @@
bool isClone(const Definition& token);
bool isConstructor(const Definition& token, string className);
bool isInternalName(const Definition& token);
+ bool isMember(const Definition& token) const;
bool isOperator(const Definition& token);
Definition* parentBracket(Definition* parent) const;
bool parseChar();
diff --git a/tools/bookmaker/definition.cpp b/tools/bookmaker/definition.cpp
index 4dfeda3..fa32b7a 100644
--- a/tools/bookmaker/definition.cpp
+++ b/tools/bookmaker/definition.cpp
@@ -339,7 +339,7 @@
// for now, just handle paint -- maybe fiddle will loosen naming restrictions
void Definition::setCanonicalFiddle() {
fMethodType = Definition::MethodType::kNone;
- size_t doubleColons = fName.find("::", 0);
+ size_t doubleColons = fName.rfind("::");
SkASSERT(string::npos != doubleColons);
string base = fName.substr(0, doubleColons);
string result = base + "_";
@@ -535,6 +535,7 @@
const char* descEnd = nullptr;
const Definition* defEnd = nullptr;
const Definition* priorDef = nullptr;
+ bool incomplete = false;
for (auto& child : fChildren) {
if (MarkType::kAnchor == child->fMarkType) {
continue;
@@ -552,6 +553,11 @@
if (MarkType::kFormula == child->fMarkType) {
continue;
}
+ if (MarkType::kLine == child->fMarkType) {
+ SkASSERT(child->fChildren.size() > 0);
+ TextParser childDesc(child->fChildren[0]);
+ incomplete |= childDesc.startsWith("incomplete");
+ }
if (MarkType::kList == child->fMarkType) {
priorDef = child;
continue;
@@ -577,7 +583,7 @@
priorDef = nullptr;
}
if (!descEnd) {
- return methodParser.reportError<bool>("missing description");
+ return incomplete ? true : methodParser.reportError<bool>("missing description");
}
TextParser description(fFileName, descStart, descEnd, fLineCount);
// expect first word capitalized and pluralized. expect a trailing period
@@ -586,7 +592,9 @@
description.reportWarning("expected capital");
} else if ('.' != descEnd[-1]) {
if (!defEnd || defEnd->fTerminator != descEnd) {
- description.reportWarning("expected period");
+ if (!incomplete) {
+ description.reportWarning("expected period");
+ }
}
} else {
if (!description.startsWith("For use by Android")) {
@@ -595,7 +603,9 @@
--description.fChar;
}
if ('s' != description.fChar[-1]) {
- description.reportWarning("expected plural");
+ if (!incomplete) {
+ description.reportWarning("expected plural");
+ }
}
}
}
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index d6594ea..eca7296 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -16,6 +16,7 @@
{ "", KeyWord::kNone, KeyProperty::kNone },
{ "SK_API", KeyWord::kSK_API, KeyProperty::kModifier },
{ "SK_BEGIN_REQUIRE_DENSE", KeyWord::kSK_BEGIN_REQUIRE_DENSE, KeyProperty::kModifier },
+ { "alignas", KeyWord::kAlignAs, KeyProperty::kModifier },
{ "bool", KeyWord::kBool, KeyProperty::kNumber },
{ "char", KeyWord::kChar, KeyProperty::kNumber },
{ "class", KeyWord::kClass, KeyProperty::kObject },
@@ -578,6 +579,9 @@
this->dumpMember(token);
continue;
break;
+ case MarkType::kTypedef:
+ this->dumpTypedef(token, classDef.fName);
+ break;
default:
SkASSERT(0);
}
@@ -878,9 +882,10 @@
this->lf(2);
}
-bool IncludeParser::dumpGlobals() {
- if (fIDefineMap.empty() && fIFunctionMap.empty() && fIEnumMap.empty() && fITemplateMap.empty()
- && fITypedefMap.empty() && fIUnionMap.empty()) {
+bool IncludeParser::dumpGlobals(string* globalFileName, long int* globalTell) {
+ bool hasGlobals = !fIDefineMap.empty() || !fIFunctionMap.empty() || !fIEnumMap.empty()
+ || !fITemplateMap.empty()|| !fITypedefMap.empty() || !fIUnionMap.empty();
+ if (!hasGlobals) {
return true;
}
size_t lastBSlash = fFileName.rfind('\\');
@@ -896,6 +901,7 @@
lastSlash += 1;
string globalsName = fFileName.substr(lastSlash, lastDotH - lastSlash);
string fileName = globalsName + "_Reference.bmh";
+ *globalFileName = fileName;
fOut = fopen(fileName.c_str(), "wb");
if (!fOut) {
SkDebugf("could not open output file %s\n", globalsName.c_str());
@@ -1007,9 +1013,10 @@
}
this->dumpCommonTail(*def);
}
+ *globalTell = ftell(fOut);
this->writeEndTag("Topic", topicName);
this->lfAlways(1);
- fclose(fOut);
+// fclose(fOut); // defer closing in case class needs to be also written here
SkDebugf("wrote %s\n", fileName.c_str());
return true;
}
@@ -1038,6 +1045,45 @@
|| 0 == token.fName.find("private_");
}
+bool IncludeParser::isMember(const Definition& token) const {
+ if ('f' == token.fStart[0] && isupper(token.fStart[1])) {
+ return true;
+ }
+ if (!islower(token.fStart[0])) {
+ return false;
+ }
+ // make an exception for SkTextBlob::RunBuffer, sole struct with members not in fXxxx format
+ if (string::npos != token.fFileName.find("SkTextBlob.h")) {
+ const Definition* structToken = token.fParent;
+ if (!structToken) {
+ return false;
+ }
+ if (KeyWord::kStruct != structToken->fKeyWord) {
+ structToken = token.fParent->fParent;
+ if (!structToken) {
+ return false;
+ }
+ if (KeyWord::kStruct != structToken->fKeyWord) {
+ return false;
+ }
+ }
+ SkASSERT(structToken->fTokens.size() > 0);
+ const Definition& child = structToken->fTokens.front();
+ string structName(child.fContentStart, child.length());
+ if ("RunBuffer" != structName) {
+ return false;
+ }
+ string tokenName(token.fContentStart, token.length());
+ string allowed[] = { "glyphs", "pos", "utf8text", "clusters" };
+ for (auto allow : allowed) {
+ if (allow == tokenName) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool IncludeParser::isOperator(const Definition& token) {
return "operator" == token.fName.substr(0, 8);
}
@@ -1083,34 +1129,48 @@
}
bool IncludeParser::dumpTokens() {
- if (!this->dumpGlobals()) {
+ string globalFileName;
+ long int globalTell = 0;
+ if (!this->dumpGlobals(&globalFileName, &globalTell)) {
return false;
}
for (const auto& member : fIClassMap) {
if (string::npos != member.first.find("::")) {
continue;
}
- if (!this->dumpTokens(member.first)) {
+ if (!this->dumpTokens(member.first, globalFileName, &globalTell)) {
return false;
}
}
+ if (globalTell) {
+ fclose(fOut);
+ }
return true;
}
// dump equivalent markup
-bool IncludeParser::dumpTokens(string skClassName) {
+bool IncludeParser::dumpTokens(string skClassName, string globalFileName, long int* globalTell) {
string fileName = skClassName + "_Reference.bmh";
- fOut = fopen(fileName.c_str(), "wb");
- if (!fOut) {
- SkDebugf("could not open output file %s\n", fileName.c_str());
- return false;
+ if (globalFileName != fileName) {
+ fOut = fopen(fileName.c_str(), "wb");
+ if (!fOut) {
+ SkDebugf("could not open output file %s\n", fileName.c_str());
+ return false;
+ }
+ } else {
+ fseek(fOut, *globalTell, SEEK_SET);
+ this->lf(2);
+ this->writeBlockSeparator();
+ *globalTell = 0;
}
string prefixName = skClassName.substr(0, 2);
string topicName = skClassName.length() > 2 && isupper(skClassName[2]) &&
("Sk" == prefixName || "Gr" == prefixName) ? skClassName.substr(2) : skClassName;
- this->writeTagNoLF("Topic", topicName);
- this->writeEndTag("Alias", topicName + "_Reference");
- this->lf(2);
+ if (globalFileName != fileName) {
+ this->writeTagNoLF("Topic", topicName);
+ this->writeEndTag("Alias", topicName + "_Reference");
+ this->lf(2);
+ }
auto& classMap = fIClassMap[skClassName];
SkASSERT(KeyWord::kClass == classMap.fKeyWord || KeyWord::kStruct == classMap.fKeyWord);
const char* containerType = KeyWord::kClass == classMap.fKeyWord ? "Class" : "Struct";
@@ -1258,6 +1318,15 @@
return true;
}
+void IncludeParser::dumpTypedef(const Definition& token, string className) {
+ this->writeTag("Typedef");
+ this->writeSpace();
+ this->writeString(token.fName);
+ this->writeTagTable("Line", "incomplete");
+ this->lf(2);
+ this->dumpComment(token);
+}
+
bool IncludeParser::findComments(const Definition& includeDef, Definition* markupDef) {
// add comment preceding class, if any
const Definition* parent = includeDef.fParent;
@@ -1341,6 +1410,32 @@
return parent ? parent->fBracket : Bracket::kNone;
}
+bool IncludeParser::inAlignAs() const {
+ if (fParent->fTokens.size() < 2) {
+ return false;
+ }
+ auto reverseIter = fParent->fTokens.end();
+ bool checkForBracket = true;
+ while (fParent->fTokens.begin() != reverseIter) {
+ std::advance(reverseIter, -1);
+ if (checkForBracket) {
+ if (Definition::Type::kBracket != reverseIter->fType) {
+ return false;
+ }
+ if (Bracket::kParen != reverseIter->fBracket) {
+ return false;
+ }
+ checkForBracket = false;
+ continue;
+ }
+ if (Definition::Type::kKeyWord != reverseIter->fType) {
+ return false;
+ }
+ return KeyWord::kAlignAs == reverseIter->fKeyWord;
+ }
+ return false;
+}
+
// caller just returns, so report error here
bool IncludeParser::parseClass(Definition* includeDef, IsStruct isStruct) {
SkASSERT(includeDef->fTokens.size() > 0);
@@ -1350,6 +1445,14 @@
// todo : documentation is ignoring this for now
iter = std::next(iter);
}
+ bool hasAlignAs = iter->fKeyWord == KeyWord::kAlignAs;
+ if (hasAlignAs) {
+ iter = std::next(iter);
+ if (Definition::Type::kBracket != iter->fType || Bracket::kParen != iter->fBracket) {
+ return includeDef->reportError<bool>("expected alignas argument");
+ }
+ iter = std::next(iter);
+ }
string nameStr(iter->fStart, iter->fContentEnd - iter->fStart);
includeDef->fName = nameStr;
iter = std::next(iter);
@@ -1378,7 +1481,18 @@
// if (1 != includeDef->fChildren.size()) {
// return false; // fix me: SkCanvasClipVisitor isn't correctly parsed
// }
- includeDef = includeDef->fChildren.front();
+ auto includeDefIter = includeDef->fChildren.begin();
+ if (hasAlignAs) {
+ SkASSERT(includeDef->fChildren.end() != includeDefIter);
+ SkASSERT(Bracket::kParen == (*includeDefIter)->fBracket);
+ std::advance(includeDefIter, 1);
+ }
+ if (includeDef->fChildren.end() != includeDefIter
+ && Bracket::kAngle == (*includeDefIter)->fBracket) {
+ std::advance(includeDefIter, 1);
+ }
+ includeDef = *includeDefIter;
+ SkASSERT(Bracket::kBrace == includeDef->fBracket);
iter = includeDef->fTokens.begin();
// skip until public
int publicIndex = 0;
@@ -1402,7 +1516,7 @@
const char* privateName = kKeyWords[(int) KeyWord::kPrivate].fName;
size_t privateLen = strlen(privateName);
auto childIter = includeDef->fChildren.begin();
- while ((*childIter)->fPrivate) {
+ while (includeDef->fChildren.end() != childIter && (*childIter)->fPrivate) {
std::advance(childIter, 1);
}
while (childIter != includeDef->fChildren.end()) {
@@ -1861,9 +1975,6 @@
tokenIter = operatorCheck;
}
string nameStr(tokenIter->fStart, nameEnd - tokenIter->fStart);
- if (string::npos != nameStr.find("sizeof")) {
- SkDebugf("");
- }
if (addConst) {
nameStr += "_const";
}
@@ -2070,7 +2181,7 @@
fAttrDeprecated = &*tokenIter;
break;
}
- if ('f' == previousToken.fStart[0] && isupper(previousToken.fStart[1])) {
+ if (this->isMember(*tokenIter)) {
break;
}
if (Bracket::kPound == child->fParent->fBracket &&
@@ -2391,7 +2502,7 @@
if (match == this->topBracket()) {
this->popBracket();
if (!fInFunction) {
- fInFunction = ')' == test;
+ fInFunction = ')' == test && !this->inAlignAs();
} else {
fInFunction = '}' != test;
}
@@ -2587,7 +2698,7 @@
fParent->fTokens.begin() != tokenIter; ) {
--tokenIter;
if (tokenIter->fLineCount == fLineCount) {
- if ('f' == tokenIter->fStart[0] && isupper(tokenIter->fStart[1])) {
+ if (this->isMember(*tokenIter)) {
if (namedIter != fParent->fTokens.end()) {
return reportError<bool>("found two named member tokens");
}
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 922f220..d0981ec 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -1218,6 +1218,7 @@
case KeyWord::kSize_t:
case KeyWord::kFloat:
case KeyWord::kBool:
+ case KeyWord::kChar:
case KeyWord::kVoid:
if (!typeStart) {
typeStart = &token;
@@ -1781,6 +1782,7 @@
memberStart = &child;
}
break;
+ case KeyWord::kAlignAs:
case KeyWord::kPublic:
case KeyWord::kPrivate:
case KeyWord::kProtected:
@@ -2691,6 +2693,7 @@
// find end of copyright header
fChar = fStart;
+ this->skipWhiteSpace();
if (!this->skipExact(
"/*\n"
" * Copyright ")) {
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 4fdc206..c3a985c 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -2121,7 +2121,7 @@
void MdOut::subtopicOut(string name) {
const Definition* topicParent = fSubtopic ? fSubtopic->topicParent() : nullptr;
- Definition* csParent = this->csParent();
+ Definition* csParent = fRoot && fRoot->isStructOrClass() ? fRoot : this->csParent();
if (!csParent) {
auto csIter = std::find_if(topicParent->fChildren.begin(), topicParent->fChildren.end(),
[](const Definition* def){ return MarkType::kEnum == def->fMarkType
diff --git a/tools/bookmaker/spellCheck.cpp b/tools/bookmaker/spellCheck.cpp
index 39621db..5b1ab1d 100644
--- a/tools/bookmaker/spellCheck.cpp
+++ b/tools/bookmaker/spellCheck.cpp
@@ -22,6 +22,8 @@
words in external not seen
look for x-bit but allow x bits
+
+don't treat 'pos' or 'glyphs' as spell-checkable as in 'RunBuffer.pos' or 'RunBuffer.glyphs'
*/
struct CheckEntry {
@@ -469,6 +471,11 @@
allLower = false;
case '-': // note that dash doesn't clear allLower
break;
+ case '!':
+ if (!inQuotes) {
+ wordEnd = chPtr;
+ }
+ break;
case '\n':
++fLocalLine;
// fall through
@@ -663,9 +670,6 @@
}
iter->second.fCount += 1;
} else {
- if ("e" == str) {
- SkDebugf("");
- }
CheckEntry* entry = &mappy[str];
entry->fFile = fFileName;
entry->fLine = fLineCount + fLocalLine;