aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-08-29 17:36:51 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-30 11:06:02 +0000
commit73fa972d0bd9de7cb801323495b5d1fabd31b24f (patch)
tree3a376a200b59bfd5c434eba345cf8e978a8f8ba6 /tools/bookmaker
parent1a763632d21636504d78910f7dea0aa708c6365f (diff)
work on path
Work on SkPath.h documentation; fixed self-consistency bugs identified by bookmaker. Fixed a couple of minor typos in SkPath.h itself. Also brought SkPaint and SkCanvas docs up to date. TBR=reed@google.com Docs-Preview: https://skia.org/?cl=39040 Bug: skia: 6898 Change-Id: Id89d4e2fa7fb6ee2e3cbec7ea762e06308b67d8b Reviewed-on: https://skia-review.googlesource.com/39040 Commit-Queue: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@google.com> Reviewed-by: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'tools/bookmaker')
-rw-r--r--tools/bookmaker/bookmaker.cpp302
-rw-r--r--tools/bookmaker/bookmaker.h18
-rw-r--r--tools/bookmaker/includeParser.cpp42
-rw-r--r--tools/bookmaker/includeWriter.cpp60
4 files changed, 305 insertions, 117 deletions
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index cbb34a2a4f..0c23c7720a 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -25,7 +25,9 @@ Text Encoding anchors in paragraph are echoed instead of being linked to anchor
consts like enum members need fully qualfied refs to make a valid link
enum comments should be disallowed unless after #Enum and before first #Const
... or, should look for enum comments in other places
-
+trouble with aliases, plurals
+ need to keep first letter of includeWriter @param / @return lowercase
+ Quad -> quad, Quads -> quads
*/
static string normalized_name(string name) {
@@ -92,7 +94,8 @@ void Definition::setCanonicalFiddle() {
fMethodType = Definition::MethodType::kNone;
size_t doubleColons = fName.find("::", 0);
SkASSERT(string::npos != doubleColons);
- string result = fName.substr(0, doubleColons) + "_";
+ string base = fName.substr(0, doubleColons);
+ string result = base + "_";
doubleColons += 2;
if (string::npos != fName.find('~', doubleColons)) {
fMethodType = Definition::MethodType::kDestructor;
@@ -118,56 +121,69 @@ void Definition::setCanonicalFiddle() {
} else {
SkASSERT(0); // todo: incomplete
}
- } else if (string::npos != fName.find("()", doubleColons)) {
- if (isupper(fName[doubleColons])) {
- fMethodType = Definition::MethodType::kConstructor;
- result += "empty_constructor";
- } else {
- result += fName.substr(doubleColons, fName.length() - doubleColons - 2);
- }
} else {
- size_t comma = fName.find(',', doubleColons);
- size_t openParen = fName.find('(', doubleColons);
- if (string::npos == comma && string::npos != openParen) {
- fMethodType = Definition::MethodType::kConstructor;
- result += isMove ? "move_" : "copy_";
- result += "constructor";
- } else if (string::npos == openParen) {
- result += fName.substr(doubleColons);
+ size_t parens = fName.find("()", doubleColons);
+ if (string::npos != parens) {
+ string methodName = fName.substr(doubleColons, parens - doubleColons);
+ do {
+ size_t nextDouble = methodName.find("::");
+ if (string::npos == nextDouble) {
+ break;
+ }
+ base = methodName.substr(0, nextDouble);
+ result += base + '_';
+ methodName = methodName.substr(nextDouble + 2);
+ doubleColons += nextDouble + 2;
+ } while (true);
+ if (base == methodName) {
+ fMethodType = Definition::MethodType::kConstructor;
+ result += "empty_constructor";
+ } else {
+ result += fName.substr(doubleColons, fName.length() - doubleColons - 2);
+ }
} else {
- fMethodType = Definition::MethodType::kConstructor;
- // name them by their param types, e.g. SkCanvas__int_int_const_SkSurfaceProps_star
- SkASSERT(string::npos != openParen);
- // TODO: move forward until parens are balanced and terminator =,)
- TextParser params("", &fName[openParen] + 1, &*fName.end(), 0);
- bool underline = false;
- while (!params.eof()) {
-// SkDEBUGCODE(const char* end = params.anyOf("(),=")); // unused for now
-// SkASSERT(end[0] != '('); // fixme: put off handling nested parentheseses
- if (params.startsWith("const") || params.startsWith("int")
- || params.startsWith("Sk")) {
- const char* wordStart = params.fChar;
- params.skipToNonAlphaNum();
- if (underline) {
- result += '_';
- } else {
- underline = true;
- }
- result += string(wordStart, params.fChar - wordStart);
- } else {
- params.skipToNonAlphaNum();
+ size_t openParen = fName.find('(', doubleColons);
+ if (string::npos == openParen) {
+ result += fName.substr(doubleColons);
+ } else {
+ size_t comma = fName.find(',', doubleColons);
+ if (string::npos == comma) {
+ result += isMove ? "move_" : "copy_";
}
- if (!params.eof() && '*' == params.peek()) {
- if (underline) {
- result += '_';
+ fMethodType = Definition::MethodType::kConstructor;
+ // name them by their param types,
+ // e.g. SkCanvas__int_int_const_SkSurfaceProps_star
+ // TODO: move forward until parens are balanced and terminator =,)
+ TextParser params("", &fName[openParen] + 1, &*fName.end(), 0);
+ bool underline = false;
+ while (!params.eof()) {
+ // SkDEBUGCODE(const char* end = params.anyOf("(),=")); // unused for now
+ // SkASSERT(end[0] != '('); // fixme: put off handling nested parentheseses
+ if (params.startsWith("const") || params.startsWith("int")
+ || params.startsWith("Sk")) {
+ const char* wordStart = params.fChar;
+ params.skipToNonAlphaNum();
+ if (underline) {
+ result += '_';
+ } else {
+ underline = true;
+ }
+ result += string(wordStart, params.fChar - wordStart);
} else {
- underline = true;
+ params.skipToNonAlphaNum();
+ }
+ if (!params.eof() && '*' == params.peek()) {
+ if (underline) {
+ result += '_';
+ } else {
+ underline = true;
+ }
+ result += "star";
+ params.next();
+ params.skipSpace();
}
- result += "star";
- params.next();
- params.skipSpace();
+ params.skipToAlpha();
}
- params.skipToAlpha();
}
}
}
@@ -391,13 +407,25 @@ bool Definition::checkMethod() const {
return true;
}
-bool Definition::crossCheck(const char* tokenID, const Definition& includeToken) const {
- const char* defStart = fStart;
- SkASSERT('#' == defStart[0]); // FIXME: needs to be per definition
- ++defStart;
- SkASSERT(!strncmp(defStart, tokenID, strlen(tokenID)));
- defStart += strlen(tokenID);
- return crossCheckInside(defStart, fContentStart, includeToken);
+bool Definition::crossCheck2(const Definition& includeToken) const {
+ TextParser parser(fFileName, fStart, fContentStart, fLineCount);
+ parser.skipExact("#");
+ bool isMethod = parser.skipName("Method");
+ const char* contentEnd;
+ if (isMethod) {
+ contentEnd = fContentStart;
+ } else if (parser.skipName("DefinedBy")) {
+ contentEnd = fContentEnd;
+ while (parser.fChar < contentEnd && ' ' >= contentEnd[-1]) {
+ --contentEnd;
+ }
+ if (parser.fChar < contentEnd - 1 && ')' == contentEnd[-1] && '(' == contentEnd[-2]) {
+ contentEnd -= 2;
+ }
+ } else {
+ return parser.reportError<bool>("unexpected crosscheck marktype");
+ }
+ return crossCheckInside(parser.fChar, contentEnd, includeToken);
}
bool Definition::crossCheck(const Definition& includeToken) const {
@@ -414,6 +442,9 @@ bool Definition::crossCheckInside(const char* start, const char* end,
if (inc.startsWith("friend")) {
inc.skipWord("friend");
}
+ if (inc.startsWith("SK_API")) {
+ inc.skipWord("SK_API");
+ }
do {
bool defEof;
bool incEof;
@@ -763,6 +794,13 @@ const Definition* RootDefinition::find(const string& ref) const {
if (leafIter != fLeaves.end()) {
return &leafIter->second;
}
+ if (string::npos == ref.find("()")) {
+ string withParens = ref + "()";
+ const auto parensIter = fLeaves.find(withParens);
+ if (parensIter != fLeaves.end()) {
+ return &parensIter->second;
+ }
+ }
const auto branchIter = fBranches.find(ref);
if (branchIter != fBranches.end()) {
const RootDefinition* rootDef = branchIter->second;
@@ -1006,7 +1044,7 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
fMarkup.emplace_front(markType, defStart, fLineCount, fParent);
definition = &fMarkup.front();
definition->fName = typeNameBuilder[0];
- definition->fFiddle = normalized_name(typeNameBuilder[0]);
+ definition->fFiddle = fParent->fFiddle;
definition->fContentStart = fChar;
definition->fContentEnd = this->trimmedBracketEnd(fMC, OneLine::kYes);
this->skipToEndBracket(fMC);
@@ -1139,6 +1177,54 @@ bool BmhParser::addDefinition(const char* defStart, bool hasEnd, MarkType markTy
return true;
}
+void BmhParser::reportDuplicates(const Definition& def, const string& dup) const {
+ if (MarkType::kExample == def.fMarkType && dup == def.fFiddle) {
+ TextParser reporter(&def);
+ reporter.reportError("duplicate example name");
+ }
+ for (auto& child : def.fChildren ) {
+ reportDuplicates(*child, dup);
+ }
+}
+
+static void find_examples(const Definition& def, vector<string>* exampleNames) {
+ if (MarkType::kExample == def.fMarkType) {
+ exampleNames->push_back(def.fFiddle);
+ }
+ for (auto& child : def.fChildren ) {
+ find_examples(*child, exampleNames);
+ }
+}
+
+bool BmhParser::checkExamples() const {
+ vector<string> exampleNames;
+ for (const auto& topic : fTopicMap) {
+ if (topic.second->fParent) {
+ continue;
+ }
+ find_examples(*topic.second, &exampleNames);
+ }
+ std::sort(exampleNames.begin(), exampleNames.end());
+ string* last = nullptr;
+ string reported;
+ bool checkOK = true;
+ for (auto& nameIter : exampleNames) {
+ if (last && *last == nameIter && reported != *last) {
+ reported = *last;
+ SkDebugf("%s\n", reported.c_str());
+ for (const auto& topic : fTopicMap) {
+ if (topic.second->fParent) {
+ continue;
+ }
+ this->reportDuplicates(*topic.second, reported);
+ }
+ checkOK = false;
+ }
+ last = &nameIter;
+ }
+ return checkOK;
+}
+
bool BmhParser::childOf(MarkType markType) const {
auto childError = [this](MarkType markType) -> bool {
string errStr = "expected ";
@@ -1162,26 +1248,32 @@ bool BmhParser::childOf(MarkType markType) const {
}
string BmhParser::className(MarkType markType) {
+ const char* end = this->lineEnd();
+ const char* mc = this->strnchr(fMC, end);
+ string classID;
+ TextParser::Save savePlace(this);
+ this->skipSpace();
+ const char* wordStart = fChar;
+ this->skipToNonAlphaNum();
+ const char* wordEnd = fChar;
+ classID = string(wordStart, wordEnd - wordStart);
+ if (!mc) {
+ savePlace.restore();
+ }
string builder;
const Definition* parent = this->parentSpace();
- if (parent && (parent != fParent || MarkType::kClass != markType)) {
+ if (parent && parent->fName != classID) {
builder += parent->fName;
}
- const char* end = this->lineEnd();
- const char* mc = this->strnchr(fMC, end);
if (mc) {
- this->skipSpace();
- const char* wordStart = fChar;
- this->skipToNonAlphaNum();
- const char* wordEnd = fChar;
if (mc + 1 < fEnd && fMC == mc[1]) { // if ##
if (markType != fParent->fMarkType) {
return this->reportError<string>("unbalanced method");
}
- if (builder.length() > 0 && wordEnd > wordStart) {
+ if (builder.length() > 0 && classID.size() > 0) {
if (builder != fParent->fName) {
builder += "::";
- builder += string(wordStart, wordEnd - wordStart);
+ builder += classID;
if (builder != fParent->fName) {
return this->reportError<string>("name mismatch");
}
@@ -1241,6 +1333,49 @@ bool BmhParser::collectExternals() {
return true;
}
+static bool dump_examples(FILE* fiddleOut, const Definition& def, bool* continuation) {
+ if (MarkType::kExample == def.fMarkType) {
+ string result;
+ if (!def.exampleToScript(&result)) {
+ return false;
+ }
+ if (result.length() > 0) {
+ if (*continuation) {
+ fprintf(fiddleOut, ",\n");
+ } else {
+ *continuation = true;
+ }
+ fprintf(fiddleOut, "%s", result.c_str());
+ }
+ return true;
+ }
+ for (auto& child : def.fChildren ) {
+ if (!dump_examples(fiddleOut, *child, continuation)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BmhParser::dumpExamples(const char* fiddleJsonFileName) const {
+ FILE* fiddleOut = fopen(fiddleJsonFileName, "wb");
+ if (!fiddleOut) {
+ SkDebugf("could not open output file %s\n", fiddleJsonFileName);
+ return false;
+ }
+ fprintf(fiddleOut, "{\n");
+ bool continuation = false;
+ for (const auto& topic : fTopicMap) {
+ if (topic.second->fParent) {
+ continue;
+ }
+ dump_examples(fiddleOut, *topic.second, &continuation);
+ }
+ fprintf(fiddleOut, "\n}\n");
+ fclose(fiddleOut);
+ return true;
+}
+
int BmhParser::endHashCount() const {
const char* end = fLine + this->lineLength();
int count = 0;
@@ -1976,30 +2111,6 @@ DEFINE_bool2(spellcheck, s, false, "Spell-check. (Requires -b)");
DEFINE_bool2(tokens, t, false, "Output include tokens. (Requires -i)");
DEFINE_bool2(crosscheck, x, false, "Check bmh against includes. (Requires -b -i)");
-static bool dump_examples(FILE* fiddleOut, const Definition& def, bool* continuation) {
- if (MarkType::kExample == def.fMarkType) {
- string result;
- if (!def.exampleToScript(&result)) {
- return false;
- }
- if (result.length() > 0) {
- if (*continuation) {
- fprintf(fiddleOut, ",\n");
- } else {
- *continuation = true;
- }
- fprintf(fiddleOut, "%s", result.c_str());
- }
- return true;
- }
- for (auto& child : def.fChildren ) {
- if (!dump_examples(fiddleOut, *child, continuation)) {
- return false;
- }
- }
- return true;
-}
-
static int count_children(const Definition& def, MarkType markType) {
int count = 0;
if (markType == def.fMarkType) {
@@ -2145,23 +2256,14 @@ int main(int argc, char** const argv) {
int examples = 0;
int methods = 0;
int topics = 0;
- FILE* fiddleOut;
if (!done && !FLAGS_examples.isEmpty()) {
- fiddleOut = fopen(FLAGS_examples[0], "wb");
- if (!fiddleOut) {
- SkDebugf("could not open output file %s\n", FLAGS_examples[0]);
+ // check to see if examples have duplicate names
+ if (!bmhParser.checkExamples()) {
return -1;
}
- fprintf(fiddleOut, "{\n");
- bool continuation = false;
- for (const auto& topic : bmhParser.fTopicMap) {
- if (topic.second->fParent) {
- continue;
- }
- dump_examples(fiddleOut, *topic.second, &continuation);
+ if (!bmhParser.dumpExamples(FLAGS_examples[0])) {
+ return -1;
}
- fprintf(fiddleOut, "\n}\n");
- fclose(fiddleOut);
}
for (const auto& topic : bmhParser.fTopicMap) {
if (topic.second->fParent) {
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index fae41c4ddd..0f0693fd77 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -40,6 +40,7 @@ using std::vector;
enum class KeyWord {
kNone,
+ kSK_API,
kBool,
kChar,
kClass,
@@ -148,6 +149,7 @@ enum class Bracket {
kSlashSlash,
kPound,
kColon,
+ kDebugCode, // parens get special treatment so SkDEBUGCODE( isn't treated as method
};
enum class Punctuation { // catch-all for misc symbols tracked in C
@@ -760,7 +762,7 @@ public:
bool checkMethod() const;
void setCanonicalFiddle();
- bool crossCheck(const char* tokenName, const Definition& includeToken) const;
+ bool crossCheck2(const Definition& includeToken) const;
bool crossCheck(const Definition& includeToken) const;
bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
bool exampleToScript(string* result) const;
@@ -1287,6 +1289,8 @@ public:
bool addDefinition(const char* defStart, bool hasEnd, MarkType markType,
const vector<string>& typeNameBuilder);
+ bool checkExamples() const;
+ bool dumpExamples(const char* fiddleJsonFileName) const;
bool childOf(MarkType markType) const;
string className(MarkType markType);
bool collectExternals();
@@ -1316,6 +1320,7 @@ public:
}
bool popParentStack(Definition* definition);
+ void reportDuplicates(const Definition& def, const string& dup) const;
void reset() override {
INHERITED::resetCommon();
@@ -1540,6 +1545,7 @@ public:
fRootTopic = nullptr;
fInBrace = nullptr;
fIncludeWord = nullptr;
+ fLastObject = nullptr;
fPrev = '\0';
fInChar = false;
fInCharCommentString = false;
@@ -1602,6 +1608,7 @@ protected:
unordered_map<string, Definition> fIUnionMap;
Definition* fRootTopic;
Definition* fInBrace;
+ Definition* fLastObject;
const char* fIncludeWord;
char fPrev;
bool fInChar;
@@ -1646,6 +1653,11 @@ public:
list<Definition>::iterator fDefEnd;
};
+ struct ParentPair {
+ const Definition* fParent;
+ const ParentPair* fPrev;
+ };
+
IncludeWriter() : IncludeParser() {}
~IncludeWriter() override {}
@@ -1670,7 +1682,7 @@ public:
const int start, const int run, int lastWrite, const char last,
const char* data);
void methodOut(const Definition* method, const Definition& child);
- bool populate(Definition* def, RootDefinition* root);
+ bool populate(Definition* def, ParentPair* parentPair, RootDefinition* root);
bool populate(BmhParser& bmhParser);
void reset() override {
@@ -1680,6 +1692,7 @@ public:
fEnumDef = nullptr;
fMethodDef = nullptr;
fStructDef = nullptr;
+ fAttrDeprecated = nullptr;
fAnonymousEnumCount = 1;
fInStruct = false;
}
@@ -1700,6 +1713,7 @@ private:
const Definition* fEnumDef;
const Definition* fMethodDef;
const Definition* fStructDef;
+ const Definition* fAttrDeprecated;
const char* fContinuation; // used to construct paren-qualified method name
int fAnonymousEnumCount;
int fEnumItemValueTab;
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 6aed93737f..21a47d6e8a 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -25,6 +25,7 @@ struct IncludeKey {
const IncludeKey kKeyWords[] = {
{ "", KeyWord::kNone, KeyProperty::kNone },
+ { "SK_API", KeyWord::kSK_API, KeyProperty::kModifier },
{ "bool", KeyWord::kBool, KeyProperty::kNumber },
{ "char", KeyWord::kChar, KeyProperty::kNumber },
{ "class", KeyWord::kClass, KeyProperty::kObject },
@@ -236,7 +237,6 @@ bool IncludeParser::crossCheck(BmhParser& bmhParser) {
if (this->internalName(token)) {
continue;
}
- const char* methodID = bmhParser.fMaps[(int) token.fMarkType].fName;
if (!def) {
string paramName = className + "::";
paramName += string(token.fContentStart,
@@ -304,11 +304,27 @@ bool IncludeParser::crossCheck(BmhParser& bmhParser) {
}
}
if (!def) {
+ if ("SK_ATTR_DEPRECATED" == token.fName) {
+ break;
+ }
+ if (0 == token.fName.find("SkDEBUGCODE")) {
+ break;
+ }
+ }
+ if (!def) {
+ // simple method names inside nested classes have a bug and are missing trailing parens
+ string withParens = fullName + "()"; // FIXME: this shouldn't be necessary
+ def = root->find(withParens);
+ }
+ if (!def) {
SkDebugf("method missing from bmh: %s\n", fullName.c_str());
break;
}
- if (def->crossCheck(methodID, token)) {
+ if (def->crossCheck2(token)) {
def->fVisited = true;
+ if (MarkType::kDefinedBy == def->fMarkType) {
+ def->fParent->fVisited = true;
+ }
} else {
SkDebugf("method differs from bmh: %s\n", fullName.c_str());
}
@@ -912,11 +928,13 @@ bool IncludeParser::parseClass(Definition* includeDef, IsStruct isStruct) {
iter = std::next(iter);
++lastPublic;
}
+ fLastObject = nullptr;
while (childIter != includeDef->fChildren.end() && (*childIter)->fParentIndex < lastPublic) {
Definition* child = *childIter;
if (!this->parseObject(child, markupDef)) {
return false;
}
+ fLastObject = child;
childIter = std::next(childIter);
}
while (childIter != includeDef->fChildren.end()) {
@@ -1292,10 +1310,18 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
case Definition::Type::kBracket:
switch (child->fBracket) {
case Bracket::kParen:
+ if (fLastObject) {
+ TextParser checkDeprecated(child->fFileName, fLastObject->fTerminator + 1,
+ child->fStart, fLastObject->fLineCount);
+ checkDeprecated.skipWhiteSpace();
+ if (checkDeprecated.startsWith("SK_ATTR_DEPRECATED")) {
+ break;
+ }
+ }
if (!this->parseMethod(child, markupDef)) {
return this->reportError<bool>("failed to parse method");
}
- break;
+ break;
case Bracket::kSlashSlash:
case Bracket::kSlashStar:
// comments are picked up by parsing objects first
@@ -1336,6 +1362,9 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
case Bracket::kAngle:
// pick up templated function pieces when method is found
break;
+ case Bracket::kDebugCode:
+ // todo: handle this
+ break;
default:
return this->reportError<bool>("unhandled bracket");
}
@@ -1457,6 +1486,11 @@ bool IncludeParser::parseChar() {
case '(':
case '[':
case '{': {
+ if (fIncludeWord && '(' == test && fChar - fIncludeWord >= 10 &&
+ !strncmp("SkDEBUGCODE", fIncludeWord, 10)) {
+ this->pushBracket(Bracket::kDebugCode);
+ break;
+ }
if (fInCharCommentString) {
break;
}
@@ -1555,6 +1589,8 @@ bool IncludeParser::parseChar() {
} else {
fInFunction = '}' != test;
}
+ } else if (')' == test && Bracket::kDebugCode == this->topBracket()) {
+ this->popBracket();
} else {
return reportError<bool>("malformed close bracket");
}
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 81fb3cc255..af2fb89fb8 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -268,6 +268,8 @@ void IncludeWriter::enumMembersOut(const RootDefinition* root, Definition& child
commentStart = privateDef->fContentStart;
commentLen = (int) (privateDef->fContentEnd - privateDef->fContentStart);
}
+ // 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);
if (!currentEnumItem->fShort) {
this->writeCommentHeader();
@@ -508,6 +510,7 @@ void IncludeWriter::methodOut(const Definition* method, const Definition& child)
}
this->indentToColumn(column);
int partLen = (int) (partEnd - partStart);
+ // FIXME : detect this earlier; assert if #Return is empty
SkASSERT(partLen > 0 && partLen < 200);
fIndent = column;
this->rewriteBlock(partLen, partStart);
@@ -673,6 +676,8 @@ void IncludeWriter::structSizeMembers(Definition& child) {
inMethod = false;
} else if (Punctuation::kLeftBrace == token.fPunctuation) {
inMethod = false;
+ } else if (Punctuation::kSemicolon == token.fPunctuation) {
+ inMethod = false;
} else {
SkASSERT(0); // incomplete
}
@@ -735,7 +740,8 @@ void IncludeWriter::structSizeMembers(Definition& child) {
}
}
-bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
+bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefinition* root) {
+ ParentPair pair = { def, prevPair };
// write bulk of original include up to class, method, enum, etc., excepting preceding comment
// find associated bmh object
// write any associated comments in Doxygen form
@@ -762,7 +768,8 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
}
if (fContinuation) {
if (Definition::Type::kKeyWord == child.fType) {
- if (KeyWord::kFriend == child.fKeyWord || KeyWord::kBool == child.fKeyWord) {
+ if (KeyWord::kFriend == child.fKeyWord || KeyWord::kBool == child.fKeyWord ||
+ KeyWord::kSK_API == child.fKeyWord) {
continue;
}
}
@@ -875,14 +882,27 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
continue;
}
this->methodOut(method, child);
+ if (fAttrDeprecated) {
+ fStart = fAttrDeprecated->fContentStart;
+ fAttrDeprecated = nullptr;
+ }
continue;
}
if (Definition::Type::kKeyWord == child.fType) {
const Definition* structDef = nullptr;
switch (child.fKeyWord) {
case KeyWord::kStruct:
+ case KeyWord::kClass:
// if struct contains members, compute their name and comment tabs
- inStruct = fInStruct = child.fChildren.size() > 0;
+ if (child.fChildren.size() > 0) {
+ const ParentPair* testPair = &pair;
+ while ((testPair = testPair->fPrev)) {
+ if (KeyWord::kClass == testPair->fParent->fKeyWord) {
+ inStruct = fInStruct = true;
+ break;
+ }
+ }
+ }
if (fInStruct) {
fIndent += 4;
fStructDef = root->find(child.fName);
@@ -892,11 +912,10 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
this->structSizeMembers(child);
fIndent -= 4;
}
- case KeyWord::kClass:
if (child.fChildren.size() > 0) {
const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
child.fContentStart;
- this->writeBlock((int) (bodyEnd - fStart), fStart);
+ this->writeBlockTrim((int) (bodyEnd - fStart), fStart);
fStart = child.fContentStart;
if (child.fName == root->fName) {
if (Definition* parent = root->fParent) {
@@ -942,6 +961,7 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
break;
}
}
+ // FIXME: trigger error earlier if inner #Struct or #Class is missing #Code
SkASSERT(nextBlock); // FIXME: check enum for correct order earlier
const char* commentStart = codeBlock->fTerminator;
const char* commentEnd = nextBlock->fStart;
@@ -962,6 +982,7 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
case KeyWord::kStatic:
case KeyWord::kInt:
case KeyWord::kUint32_t:
+ case KeyWord::kUnsigned:
case KeyWord::kSize_t:
case KeyWord::kFloat:
case KeyWord::kBool:
@@ -974,6 +995,8 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
case KeyWord::kPrivate:
case KeyWord::kProtected:
case KeyWord::kFriend:
+ case KeyWord::kInline:
+ case KeyWord::kSK_API:
case KeyWord::kTypedef:
break;
default:
@@ -986,7 +1009,7 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
this->writeBlock((int) (fStart - child.fStart), child.fStart);
this->lf(2);
fIndent += 4;
- if (!this->populate(&child, const_cast<Definition*>(structDef)->asRoot())) {
+ if (!this->populate(&child, &pair, const_cast<Definition*>(structDef)->asRoot())) {
return false;
}
// output any remaining definitions at current indent level
@@ -1001,10 +1024,10 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
fDeferComment = nullptr;
} else {
if (fInEnum && KeyWord::kClass == child.fChildren[0]->fKeyWord) {
- if (!this->populate(child.fChildren[0], root)) {
+ if (!this->populate(child.fChildren[0], &pair, root)) {
return false;
}
- } else if (!this->populate(&child, root)) {
+ } else if (!this->populate(&child, &pair, root)) {
return false;
}
}
@@ -1023,9 +1046,12 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
fDeferComment = nullptr;
fInEnum = false;
continue;
- }
+ }
+ if (fAttrDeprecated) {
+ continue;
+ }
fDeferComment = nullptr;
- if (!this->populate(&child, root)) {
+ if (!this->populate(&child, &pair, root)) {
return false;
}
continue;
@@ -1039,6 +1065,12 @@ bool IncludeWriter::populate(Definition* def, RootDefinition* root) {
if (child.fMemberStart) {
memberStart = &child;
}
+ const char attrDeprecated[] = "SK_ATTR_DEPRECATED";
+ const size_t attrDeprecatedLen = sizeof(attrDeprecated) - 1;
+ if (attrDeprecatedLen == child.fContentEnd - child.fContentStart &&
+ !strncmp(attrDeprecated, child.fStart, attrDeprecatedLen)) {
+ fAttrDeprecated = &child;
+ }
continue;
}
if (Definition::Type::kPunctuation == child.fType) {
@@ -1086,7 +1118,7 @@ bool IncludeWriter::populate(BmhParser& bmhParser) {
root->clearVisited();
fStart = includeMapper.second.fContentStart;
fEnd = includeMapper.second.fContentEnd;
- allPassed &= this->populate(&includeMapper.second, root);
+ allPassed &= this->populate(&includeMapper.second, nullptr, root);
this->writeBlock((int) (fEnd - fStart), fStart);
fIndent = 0;
this->lfcr();
@@ -1409,7 +1441,7 @@ IncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data) {
case '\'': // possessive apostrophe isn't treated as delimiting punctation
case '=':
case '!': // assumed not to be punctuation, but a programming symbol
- case '&': case '>': case '<': case '{': case '}': case '/': case '*':
+ case '&': case '>': case '<': case '{': case '}': case '/': case '*': case '[': case ']':
word = Word::kMixed;
embeddedSymbol = true;
break;
@@ -1442,6 +1474,10 @@ IncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data) {
}
hasSymbol |= embeddedSymbol;
break;
+ case '+':
+ // hackery to allow C++
+ SkASSERT('C' == last || '+' == last); // FIXME: don't allow + outside of #Formula
+ break;
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':