aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/bookmaker/includeParser.cpp
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2017-09-19 17:39:32 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-09-19 22:04:19 +0000
commit9174bda24aef222beaff1d9d80ea80a063852c74 (patch)
tree7143dfc0f50303df1adf8f6fa9186f39bf2a1c18 /tools/bookmaker/includeParser.cpp
parentfe69f9a50ac1a6a61c9dda9c28c97599131656ee (diff)
work on generation of rect, bitmap, matrix markup
TBR=caryclark@google.com Bug: skia:6898 Change-Id: I501d87341afa2f8d548b4d02415375032a46e96e Reviewed-on: https://skia-review.googlesource.com/47420 Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'tools/bookmaker/includeParser.cpp')
-rw-r--r--tools/bookmaker/includeParser.cpp604
1 files changed, 394 insertions, 210 deletions
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 1000a037e7..ee2b95a134 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -105,9 +105,7 @@ void IncludeParser::checkForMissingParams(const vector<string>& methodParams,
}
}
if (!found) {
- this->keywordStart("Param");
- fprintf(fOut, "%s ", methodParam.c_str());
- this->keywordEnd();
+ this->writeEndTag("Param", methodParam, 2);
}
}
for (auto& foundParam : foundParams) {
@@ -450,90 +448,38 @@ void IncludeParser::dumpClassTokens(IClassDefinition& classDef) {
continue;
}
if (MarkType::kMember != token.fMarkType) {
- fprintf(fOut, "%s",
- "# ------------------------------------------------------------------------------\n");
- fprintf(fOut, "" "\n");
+ this->writeString(
+ "# ------------------------------------------------------------------------------");
+ this->lf(2);
}
switch (token.fMarkType) {
case MarkType::kEnum:
- fprintf(fOut, "#Enum %s" "\n",
- token.fName.c_str());
- fprintf(fOut, "" "\n");
- fprintf(fOut, "#Code" "\n");
- fprintf(fOut, " enum %s {" "\n",
- token.fName.c_str());
- for (auto& child : token.fChildren) {
- fprintf(fOut, " %s %.*s" "\n",
- child->fName.c_str(), child->length(), child->fContentStart);
- }
- fprintf(fOut, " };" "\n");
- fprintf(fOut, "##" "\n");
- fprintf(fOut, "" "\n");
- this->dumpComment(&token);
- for (auto& child : token.fChildren) {
- fprintf(fOut, "#Const %s", child->fName.c_str());
- TextParser val(child);
- if (!val.eof()) {
- if ('=' == val.fStart[0] || ',' == val.fStart[0]) {
- val.next();
- val.skipSpace();
- const char* valEnd = val.anyOf(",\n");
- if (!valEnd) {
- valEnd = val.fEnd;
- }
- fprintf(fOut, " %.*s", (int) (valEnd - val.fStart), val.fStart);
- } else {
- fprintf(fOut, " %.*s",
- (int) (child->fContentEnd - child->fContentStart),
- child->fContentStart);
- }
- }
- fprintf(fOut, "" "\n");
- for (auto& token : child->fTokens) {
- if (MarkType::kComment == token.fMarkType) {
- this->dumpComment(&token);
- }
- }
- fprintf(fOut, "##" "\n");
- }
- fprintf(fOut, "" "\n");
+ this->dumpEnum(token);
break;
case MarkType::kMethod:
- fprintf(fOut, "#Method %.*s" "\n",
- token.length(), token.fStart);
- lfAlways(1);
- this->dumpComment(&token);
+ this->dumpMethod(token);
break;
case MarkType::kMember:
- this->keywordStart("Member");
- fprintf(fOut, "%.*s %s ", (int) (token.fContentEnd - token.fContentStart),
- token.fContentStart, token.fName.c_str());
- lfAlways(1);
- for (auto child : token.fChildren) {
- fprintf(fOut, "%.*s", (int) (child->fContentEnd - child->fContentStart),
- child->fContentStart);
- lfAlways(1);
- }
- this->keywordEnd();
+ this->dumpMember(token);
continue;
break;
default:
SkASSERT(0);
}
this->lf(2);
- fprintf(fOut, "#Example" "\n");
- fprintf(fOut, "##" "\n");
- fprintf(fOut, "" "\n");
- fprintf(fOut, "#ToDo incomplete ##" "\n");
- fprintf(fOut, "" "\n");
- fprintf(fOut, "##" "\n");
- fprintf(fOut, "" "\n");
+ this->writeTag("Example");
+ this->writeEndTag();
+ this->lf(2);
+ this->writeEndTag("ToDo", "incomplete");
+ this->lf(2);
+ this->writeEndTag();
+ this->lf(2);
}
}
-void IncludeParser::dumpComment(Definition* token) {
- fLineCount = token->fLineCount;
- fChar = fLine = token->fContentStart;
- fEnd = token->fContentEnd;
+void IncludeParser::dumpComment(const Definition& token) {
+ fLineCount = token.fLineCount;
+ fChar = fLine = token.fContentStart;
+ fEnd = token.fContentEnd;
bool sawParam = false;
bool multiline = false;
bool sawReturn = false;
@@ -542,11 +488,11 @@ void IncludeParser::dumpComment(Definition* token) {
vector<string> methodParams;
vector<string> foundParams;
Definition methodName;
- TextParser methodParser(token->fFileName, token->fContentStart, token->fContentEnd,
- token->fLineCount);
- if (MarkType::kMethod == token->fMarkType) {
- methodName.fName = string(token->fContentStart,
- (int) (token->fContentEnd - token->fContentStart));
+ TextParser methodParser(token.fFileName, token.fContentStart, token.fContentEnd,
+ token.fLineCount);
+ if (MarkType::kMethod == token.fMarkType) {
+ methodName.fName = string(token.fContentStart,
+ (int) (token.fContentEnd - token.fContentStart));
methodHasReturn = !methodParser.startsWith("void ")
&& !methodParser.strnchr('~', methodParser.fEnd);
const char* paren = methodParser.strnchr('(', methodParser.fEnd);
@@ -561,8 +507,14 @@ void IncludeParser::dumpComment(Definition* token) {
methodParams.push_back(paramName);
} while (')' != nextEnd[0]);
}
- for (const auto& child : token->fTokens) {
+ for (const auto& child : token.fTokens) {
+ if (Definition::Type::kMark == child.fType && MarkType::kMember == child.fMarkType) {
+ break;
+ }
if (Definition::Type::kMark == child.fType && MarkType::kComment == child.fMarkType) {
+ if (child.fPrivate) {
+ break;
+ }
if ('@' == child.fContentStart[0]) {
TextParser parser(&child);
do {
@@ -585,9 +537,9 @@ void IncludeParser::dumpComment(Definition* token) {
}
if (sawParam) {
if (multiline) {
- this->lfAlways(1);
+ this->lf(1);
}
- this->keywordEnd();
+ this->writeEndTag();
} else {
if (sawComment) {
this->nl();
@@ -595,10 +547,10 @@ void IncludeParser::dumpComment(Definition* token) {
this->lf(2);
}
foundParams.emplace_back(piece);
- this->keywordStart("Param");
- fprintf(fOut, "%s ", piece.c_str());
- fprintf(fOut, "%.*s", (int) (parser.fEnd - parser.fChar), parser.fChar);
- this->lfAlways(1);
+ this->writeTag("Param", piece);
+ this->writeSpace(2);
+ this->writeBlock(parser.fEnd - parser.fChar, parser.fChar);
+ this->lf(1);
sawParam = true;
sawComment = false;
} while (parmName.length());
@@ -610,43 +562,59 @@ void IncludeParser::dumpComment(Definition* token) {
}
if (sawParam) {
if (multiline) {
- this->lfAlways(1);
+ this->lf(1);
}
- this->keywordEnd();
+ this->writeEndTag();
}
this->checkForMissingParams(methodParams, foundParams);
sawParam = false;
sawComment = false;
multiline = false;
this->lf(2);
- this->keywordStart("Return");
- fprintf(fOut, "%.*s ", (int) (parser.fEnd - parser.fChar),
- parser.fChar);
- this->lfAlways(1);
+ this->writeTag("Return");
+ this->writeSpace(2);
+ this->writeBlock(parser.fEnd - parser.fChar, parser.fChar);
+ this->lf(1);
sawReturn = true;
parser.skipTo(parser.fEnd);
} else {
this->reportError("unexpected doxygen directive");
}
} while (!parser.eof());
- } else {
- if (sawComment) {
- this->nl();
+ } else if (child.length() > 1) {
+ const char* start = child.fContentStart;
+ ptrdiff_t length = child.fContentEnd - start;
+ SkASSERT(length >= 0);
+ while (length && '/' == start[0]) {
+ start += 1;
+ --length;
}
- this->lf(1);
- fprintf(fOut, "%.*s ", child.length(), child.fContentStart);
- sawComment = true;
- if (sawParam || sawReturn) {
- multiline = true;
+ while (length && '/' == start[length - 1]) {
+ length -= 1;
+ if (length && '*' == start[length - 1]) {
+ length -= 1;
+ }
+ }
+ if (length) {
+ this->lfAlways(sawComment || sawParam || sawReturn ? 1 : 2);
+ if (sawParam || sawReturn) {
+ this->indentToColumn(8);
+ }
+ this->writeBlock(length, start);
+ this->writeSpace();
+ sawComment = true;
+ if (sawParam || sawReturn) {
+ multiline = true;
+ }
}
}
}
}
if (sawParam || sawReturn) {
if (multiline) {
- this->lfAlways(1);
+ this->lf(1);
}
- this->keywordEnd();
+ this->writeEndTag();
}
if (!sawReturn) {
if (!sawParam) {
@@ -665,15 +633,145 @@ void IncludeParser::dumpComment(Definition* token) {
this->nl();
}
this->lf(2);
- this->keywordStart("Return");
- this->keywordEnd();
+ this->writeEndTag("Return");
}
}
}
- // dump equivalent markup
+void IncludeParser::dumpEnum(const Definition& token) {
+ this->writeTag("Enum", token.fName);
+ this->lf(2);
+ this->writeString("#Code");
+ this->lfAlways(1);
+ this->indentToColumn(4);
+ this->writeString("enum");
+ this->writeSpace();
+ if ("_anonymous" != token.fName.substr(0, 10)) {
+ this->writeString(token.fName);
+ this->writeSpace();
+ }
+ this->writeString("{");
+ this->lfAlways(1);
+ for (auto& child : token.fChildren) {
+ this->indentToColumn(8);
+ this->writeString(child->fName);
+ if (child->length()) {
+ this->writeSpace();
+ this->writeBlock(child->length(), child->fContentStart);
+ }
+ if (',' != fLastChar) {
+ this->writeString(",");
+ }
+ this->lfAlways(1);
+ }
+ this->indentToColumn(4);
+ this->writeString("};");
+ this->lf(1);
+ this->writeString("##");
+ this->lf(2);
+ this->dumpComment(token);
+ for (auto& child : token.fChildren) {
+ // start here;
+ // get comments before
+ // or after const values
+ this->writeString("#Const");
+ this->writeSpace();
+ this->writeString(child->fName);
+ TextParser val(child);
+ if (!val.eof()) {
+ if ('=' == val.fStart[0] || ',' == val.fStart[0]) {
+ val.next();
+ val.skipSpace();
+ const char* valEnd = val.anyOf(",\n");
+ if (!valEnd) {
+ valEnd = val.fEnd;
+ }
+ this->writeSpace();
+ this->writeBlock(valEnd - val.fStart, val.fStart);
+ } else {
+ this->writeSpace();
+ this->writeDefinition(*child);
+ }
+ }
+ this->lf(1);
+ for (auto comment : child->fChildren) {
+ if (MarkType::kComment == comment->fMarkType) {
+ TextParser parser(comment);
+ parser.skipExact("*");
+ parser.skipExact("*");
+ while (!parser.eof() && parser.skipWhiteSpace()) {
+ parser.skipExact("*");
+ parser.skipWhiteSpace();
+ const char* start = parser.fChar;
+ parser.skipToEndBracket('\n');
+ this->lf(1);
+ this->writeBlock(parser.fChar - start, start);
+ }
+ }
+ }
+ this->writeEndTag();
+ }
+ this->lf(2);
+}
+
+void IncludeParser::dumpMethod(const Definition& token) {
+ this->writeString("#Method");
+ this->writeSpace();
+ if ("SK_TO_STRING_NONVIRT" == token.fName) {
+ this->writeString("void toString(SkString* str) const;");
+ this->lf(2);
+ this->writeEndTag("DefinedBy", "SK_TO_STRING_NONVIRT()");
+ this->lf(2);
+ this->writeTag("Private");
+ this->lf(1);
+ this->writeString("macro expands to: void toString(SkString* str) const;");
+ this->writeEndTag();
+ this->lf(2);
+ const char desc[] =
+ "Creates string representation. The representation is read by\n"
+ "internal debugging tools. The interface and implementation may be\n"
+ "suppressed by defining SK_IGNORE_TO_STRING.";
+ this->writeBlock(sizeof(desc) - 1, desc);
+ this->lf(2);
+ this->writeTag("Param", "str");
+ this->writeSpace(2);
+ this->writeString("storage for string representation");
+ this->writeSpace();
+ this->writeString("##");
+ this->lf(2);
+ return;
+ }
+ this->writeBlock(token.length(), token.fStart);
+ this->lf(1);
+ this->dumpComment(token);
+}
+
+void IncludeParser::dumpMember(const Definition& token) {
+ this->writeTag("Member");
+ this->writeSpace();
+ this->writeDefinition(token, token.fName, 2);
+ lf(1);
+ for (auto child : token.fChildren) {
+ this->writeDefinition(*child);
+ }
+ this->writeEndTag();
+ lf(2);
+}
+
bool IncludeParser::dumpTokens(const string& dir) {
- string skClassName = this->className();
+ for (const auto& member : fIClassMap) {
+ if (string::npos != member.first.find("::")) {
+ continue;
+ }
+ if (!this->dumpTokens(dir, member.first)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+ // dump equivalent markup
+bool IncludeParser::dumpTokens(const string& dir, const string& skClassName) {
string fileName = dir;
if (dir.length() && '/' != dir[dir.length() - 1]) {
fileName += '/';
@@ -687,19 +785,20 @@ bool IncludeParser::dumpTokens(const string& dir) {
string prefixName = skClassName.substr(0, 2);
string topicName = skClassName.length() > 2 && isupper(skClassName[2]) &&
("Sk" == prefixName || "Gr" == prefixName) ? skClassName.substr(2) : skClassName;
- fprintf(fOut, "#Topic %s", topicName.c_str());
- this->lfAlways(2);
- fprintf(fOut, "#Class %s", skClassName.c_str());
- this->lfAlways(2);
+ this->writeTagNoLF("Topic", topicName);
+ this->writeTag("Alias", topicName + "_Reference");
+ this->lf(2);
auto& classMap = fIClassMap[skClassName];
+ const char* containerType = kKeyWords[(int) classMap.fKeyWord].fName;
+ this->writeTag(containerType, skClassName);
+ this->lf(2);
auto& tokens = classMap.fTokens;
for (auto& token : tokens) {
if (Definition::Type::kMark != token.fType || MarkType::kComment != token.fMarkType) {
continue;
}
- fprintf(fOut, "%.*s", (int) (token.fContentEnd - token.fContentStart),
- token.fContentStart);
- this->lfAlways(1);
+ this->writeDefinition(token);
+ this->lf(1);
}
this->lf(2);
string className(skClassName.substr(2));
@@ -713,96 +812,129 @@ bool IncludeParser::dumpTokens(const string& dir) {
maxLen = SkTMax(maxLen, structName.length());
sortedClasses.emplace_back(structName);
}
- fprintf(fOut, "#Topic Overview");
- this->lfAlways(2);
- fprintf(fOut, "#Subtopic %s_Structs", className.c_str());
- this->lfAlways(1);
- fprintf(fOut, "#Table");
- this->lfAlways(1);
- fprintf(fOut, "#Legend");
- this->lfAlways(1);
- fprintf(fOut, "# %-*s # description ##", (int) maxLen, "struct");
- this->lfAlways(1);
- fprintf(fOut, "#Legend ##");
- this->lfAlways(1);
- fprintf(fOut, "#Table ##");
- this->lfAlways(1);
- for (auto& name : sortedClasses) {
- fprintf(fOut, "# %-*s # ##", (int) maxLen, name.c_str());
- this->lfAlways(1);
+ this->writeTag("Topic", "Overview");
+ this->lf(2);
+ this->writeTag("Subtopic", "Subtopics");
+ this->writeEndTag("ToDo", "manually add subtopics");
+ this->writeTableHeader("topics", 0, "description");
+ this->writeTableTrailer();
+ this->writeEndTag();
+ this->lf(2);
+ if (maxLen) {
+ this->writeTag("Subtopic", "Structs");
+ this->writeTableHeader("description", maxLen, "struct");
+ for (auto& name : sortedClasses) {
+ this->writeTableRow(maxLen, name);
+ }
+ this->writeTableTrailer();
+ this->writeEndTag("Subtopic");
+ this->lf(2);
}
- fprintf(fOut, "#Subtopic ##");
- this->lfAlways(2);
- fprintf(fOut, "#Subtopic %s_Member_Functions", className.c_str());
- this->lfAlways(1);
- fprintf(fOut, "#Table");
- this->lfAlways(1);
- fprintf(fOut, "#Legend");
- this->lfAlways(1);
maxLen = 0;
+ size_t constructorMax = 0;
+ size_t operatorMax = 0;
vector<string> sortedNames;
+ vector<string> constructorNames;
+ vector<string> operatorNames;
for (const auto& token : classMap.fTokens) {
if (Definition::Type::kMark != token.fType || MarkType::kMethod != token.fMarkType) {
continue;
}
- const string& name = token.fName;
+ string name = token.fName;
if (name.substr(0, 7) == "android" || string::npos != name.find("nternal_")) {
continue;
}
+ if ((name.substr(0, 2) == "Sk" && 2 == name.find(className)) || '~' == name[0]) {
+ name = string(token.fContentStart, (int) (token.fContentEnd - token.fContentStart));
+ constructorMax = SkTMax(constructorMax, name.length());
+ constructorNames.emplace_back(name);
+ continue;
+ }
+ if (name.substr(0, 8) == "operator") {
+ name = string(token.fContentStart, (int) (token.fContentEnd - token.fContentStart));
+ operatorMax = SkTMax(operatorMax, name.length());
+ operatorNames.emplace_back(name);
+ continue;
+ }
if (name[name.length() - 2] == '_' && isdigit(name[name.length() - 1])) {
continue;
}
+ if ("SK_TO_STRING_NONVIRT" == name) {
+ name = "toString";
+ }
size_t paren = name.find('(');
size_t funcLen = string::npos == paren ? name.length() : paren;
maxLen = SkTMax(maxLen, funcLen);
sortedNames.emplace_back(name);
}
+ if (constructorMax) {
+ std::sort(constructorNames.begin(), constructorNames.end());
+ this->writeTag("Subtopic", "Constructors");
+ this->writeTableHeader("description", constructorMax, "function");
+ for (auto& name : constructorNames) {
+ this->writeTableRow(constructorMax, name);
+ }
+ this->writeTableTrailer();
+ this->writeEndTag("Subtopic");
+ this->lf(2);
+ }
+ if (operatorMax) {
+ std::sort(operatorNames.begin(), operatorNames.end());
+ this->writeTag("Subtopic", "Operators");
+ this->writeTableHeader("description", operatorMax, "function");
+ for (auto& name : operatorNames) {
+ this->writeTableRow(operatorMax, name);
+ }
+ this->writeTableTrailer();
+ this->writeEndTag("Subtopic");
+ this->lf(2);
+ }
std::sort(sortedNames.begin(), sortedNames.end());
- fprintf(fOut, "# %-*s # description ##" "\n",
- (int) maxLen, "function");
- fprintf(fOut, "#Legend ##" "\n");
+ this->writeTag("Subtopic", "Member_Functions");
+ this->writeTableHeader("description", maxLen, "function");
for (auto& name : sortedNames) {
size_t paren = name.find('(');
size_t funcLen = string::npos == paren ? name.length() : paren;
- fprintf(fOut, "# %-*s # ##" "\n",
- (int) maxLen, name.substr(0, funcLen).c_str());
- }
- fprintf(fOut, "#Table ##" "\n");
- fprintf(fOut, "#Subtopic ##" "\n");
- fprintf(fOut, "" "\n");
- fprintf(fOut, "#Topic ##" "\n");
- fprintf(fOut, "" "\n");
+ this->writeTableRow(maxLen, name.substr(0, funcLen));
+ }
+ this->writeTableTrailer();
+ this->writeEndTag("Subtopic");
+ this->lf(2);
+ this->writeEndTag("Topic");
+ this->lf(2);
for (auto& oneClass : fIClassMap) {
if (skClassName + "::" != oneClass.first.substr(0, skClassName.length() + 2)) {
continue;
}
string innerName = oneClass.first.substr(skClassName.length() + 2);
- fprintf(fOut, "%s",
+ this->writeString(
"# ------------------------------------------------------------------------------");
- this->lfAlways(2);
- fprintf(fOut, "#Struct %s", innerName.c_str());
- this->lfAlways(2);
+ this->lf(2);
+ const char* containerType = kKeyWords[(int) oneClass.second.fKeyWord].fName;
+ this->writeTag(containerType, innerName);
+ this->lf(2);
+ this->writeTag("Code");
+ this->writeEndTag("ToDo", "fill this in manually");
+ this->writeEndTag();
+ this->lf(2);
for (auto& token : oneClass.second.fTokens) {
if (Definition::Type::kMark != token.fType || MarkType::kComment != token.fMarkType) {
continue;
}
- fprintf(fOut, "%.*s", (int) (token.fContentEnd - token.fContentStart),
- token.fContentStart);
- this->lfAlways(1);
+ this->writeDefinition(token);
}
this->lf(2);
this->dumpClassTokens(oneClass.second);
this->lf(2);
- fprintf(fOut, "#Struct %s ##", innerName.c_str());
- this->lfAlways(2);
+ this->writeEndTag(containerType, innerName);
+ this->lf(2);
}
this->dumpClassTokens(classMap);
- fprintf(fOut, "#Class %s ##" "\n",
- skClassName.c_str());
- fprintf(fOut, "" "\n");
- fprintf(fOut, "#Topic %s ##" "\n",
- topicName.c_str());
+ this->writeEndTag(containerType, skClassName);
+ this->lf(2);
+ this->writeEndTag("Topic", topicName);
+ this->lfAlways(1);
fclose(fOut);
SkDebugf("wrote %s\n", fileName.c_str());
return true;
@@ -859,9 +991,6 @@ bool IncludeParser::internalName(const Definition& token) const {
// caller calls reportError, so just return false here
bool IncludeParser::parseClass(Definition* includeDef, IsStruct isStruct) {
SkASSERT(includeDef->fTokens.size() > 0);
- if (includeDef->fTokens.size() == 1) {
- return true; // forward declaration only
- }
// parse class header
auto iter = includeDef->fTokens.begin();
if (!strncmp(iter->fStart, "SK_API", iter->fContentEnd - iter->fStart)) {
@@ -870,24 +999,28 @@ bool IncludeParser::parseClass(Definition* includeDef, IsStruct isStruct) {
}
string nameStr(iter->fStart, iter->fContentEnd - iter->fStart);
includeDef->fName = nameStr;
+ iter = std::next(iter);
+ if (iter == includeDef->fTokens.end()) {
+ return true; // forward declaration only
+ }
do {
if (iter == includeDef->fTokens.end()) {
- return false;
+ return includeDef->reportError<bool>("unexpected end");
}
if ('{' == iter->fStart[0] && Definition::Type::kPunctuation == iter->fType) {
break;
}
} while (static_cast<void>(iter = std::next(iter)), true);
if (Punctuation::kLeftBrace != iter->fPunctuation) {
- return false;
+ return iter->reportError<bool>("expected left brace");
}
IClassDefinition* markupDef = this->defineClass(*includeDef, nameStr);
if (!markupDef) {
- return false;
+ return iter->reportError<bool>("expected markup definition");
}
markupDef->fStart = iter->fStart;
if (!this->findComments(*includeDef, markupDef)) {
- return false;
+ return iter->reportError<bool>("find comments failed");
}
// if (1 != includeDef->fChildren.size()) {
// return false; // fix me: SkCanvasClipVisitor isn't correctly parsed
@@ -1018,9 +1151,9 @@ bool IncludeParser::parseEnum(Definition* child, Definition* markupDef) {
}
TextParser parser(child);
parser.skipToEndBracket('{');
+ parser.next();
const char* dataEnd;
do {
- parser.next();
parser.skipWhiteSpace();
if ('}' == parser.peek()) {
break;
@@ -1058,33 +1191,57 @@ bool IncludeParser::parseEnum(Definition* child, Definition* markupDef) {
if ('}' == memberStart[0]) {
break;
}
+ // if there's comment on same the line as member def, output first as if it was before
+
parser.skipToNonAlphaNum();
string memberName(memberStart, parser.fChar);
- parser.skipWhiteSpace();
+ if (parser.eof() || !parser.skipWhiteSpace()) {
+ return this->reportError<bool>("enum member must end with comma 1");
+ }
const char* dataStart = parser.fChar;
- SkASSERT('=' == dataStart[0] || ',' == dataStart[0] || '}' == dataStart[0]
- || '/' == dataStart[0]);
- dataEnd = parser.anyOf(",}");
+ if ('=' == parser.peek()) {
+ parser.skipToEndBracket(',');
+ }
+ if (parser.eof() || ',' != parser.peek()) {
+ return this->reportError<bool>("enum member must end with comma 2");
+ }
+ dataEnd = parser.fChar;
+ const char* start = parser.anyOf("/\n");
+ SkASSERT(start);
+ parser.skipTo(start);
+ if ('/' == parser.next()) {
+ char slashStar = parser.next();
+ if ('/' == slashStar || '*' == slashStar) {
+ TextParser::Save save(&parser);
+ char doxCheck = parser.next();
+ if ((slashStar != doxCheck && '!' != doxCheck) || '<' != parser.next()) {
+ save.restore();
+ }
+ }
+ parser.skipWhiteSpace();
+ const char* commentStart = parser.fChar;
+ if ('/' == slashStar) {
+ parser.skipToEndBracket('\n');
+ } else {
+ parser.skipToEndBracket("*/");
+ }
+ SkASSERT(!parser.eof());
+ const char* commentEnd = parser.fChar;
+ markupChild->fTokens.emplace_back(MarkType::kComment, commentStart, commentEnd,
+ parser.fLineCount, markupChild);
+ comment = &markupChild->fTokens.back();
+ comment->fTerminator = commentEnd;
+ }
markupChild->fTokens.emplace_back(MarkType::kMember, dataStart, dataEnd, parser.fLineCount,
markupChild);
Definition* member = &markupChild->fTokens.back();
member->fName = memberName;
if (comment) {
member->fChildren.push_back(comment);
+ comment->fPrivate = true;
}
markupChild->fChildren.push_back(member);
- parser.skipToEndBracket(dataEnd[0]);
- } while (',' == dataEnd[0]);
- for (size_t index = 1; index < child->fChildren.size(); ++index) {
- const Definition* follower = child->fChildren[index];
- if (Definition::Type::kKeyWord == follower->fType) {
- markupChild->fTokens.emplace_back(MarkType::kMember, follower->fContentStart,
- follower->fContentEnd, follower->fLineCount, markupChild);
- Definition* member = &markupChild->fTokens.back();
- member->fName = follower->fName;
- markupChild->fChildren.push_back(member);
- }
- }
+ } while (true);
IClassDefinition& classDef = fIClassMap[markupDef->fName];
SkASSERT(classDef.fStart);
string uniqueName = this->uniqueName(classDef.fEnums, nameStr);
@@ -1125,6 +1282,7 @@ bool IncludeParser::parseMember(Definition* child, Definition* markupDef) {
IClassDefinition& classDef = fIClassMap[markupDef->fName];
string uniqueName = this->uniqueName(classDef.fMethods, nameStr);
markupChild->fName = uniqueName;
+ markupChild->fTerminator = markupChild->fContentEnd;
classDef.fMembers[uniqueName] = markupChild;
if (child->fParentIndex >= 2) {
auto comment = child->fParent->fTokens.begin();
@@ -1162,6 +1320,9 @@ bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) {
std::advance(tokenIter, child->fParentIndex);
tokenIter = std::prev(tokenIter);
string nameStr(tokenIter->fStart, tokenIter->fContentEnd - tokenIter->fStart);
+ if (0 == nameStr.find("SK_ATTR_DEPRECATED")) {
+ SkDebugf("");
+ }
while (tokenIter != child->fParent->fTokens.begin()) {
auto testIter = std::prev(tokenIter);
switch (testIter->fType) {
@@ -1231,6 +1392,17 @@ bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) {
while (end > start && ' ' >= end[-1]) {
--end;
}
+ if (!markupDef) {
+ auto parentIter = child->fParent->fTokens.begin();
+ SkASSERT(child->fParentIndex > 0);
+ std::advance(parentIter, child->fParentIndex - 1);
+ Definition* methodName = &*parentIter;
+ TextParser name(methodName);
+ if (name.skipToEndBracket(':') && name.startsWith("::")) {
+ return true; // expect this is inline class definition outside of class
+ }
+ SkASSERT(0); // code incomplete
+ }
markupDef->fTokens.emplace_back(MarkType::kMethod, start, end, tokenIter->fLineCount,
markupDef);
Definition* markupChild = &markupDef->fTokens.back();
@@ -1246,16 +1418,6 @@ bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) {
return true;
}
-void IncludeParser::keywordEnd() {
- fprintf(fOut, "##");
- this->lfAlways(1);
-}
-
-void IncludeParser::keywordStart(const char* keyword) {
- this->lf(1);
- fprintf(fOut, "#%s ", keyword);
-}
-
bool IncludeParser::parseObjects(Definition* parent, Definition* markupDef) {
for (auto& child : parent->fChildren) {
if (!this->parseObject(child, markupDef)) {
@@ -1275,36 +1437,36 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
switch (child->fKeyWord) {
case KeyWord::kClass:
if (!this->parseClass(child, IsStruct::kNo)) {
- return this->reportError<bool>("failed to parse class");
+ return false;
}
break;
case KeyWord::kEnum:
if (!this->parseEnum(child, markupDef)) {
- return this->reportError<bool>("failed to parse enum");
+ return child->reportError<bool>("failed to parse enum");
}
break;
case KeyWord::kStruct:
if (!this->parseClass(child, IsStruct::kYes)) {
- return this->reportError<bool>("failed to parse struct");
+ return child->reportError<bool>("failed to parse struct");
}
break;
case KeyWord::kTemplate:
if (!this->parseTemplate()) {
- return this->reportError<bool>("failed to parse template");
+ return child->reportError<bool>("failed to parse template");
}
break;
case KeyWord::kTypedef:
if (!this->parseTypedef()) {
- return this->reportError<bool>("failed to parse typedef");
+ return child->reportError<bool>("failed to parse typedef");
}
break;
case KeyWord::kUnion:
if (!this->parseUnion()) {
- return this->reportError<bool>("failed to parse union");
+ return child->reportError<bool>("failed to parse union");
}
break;
default:
- return this->reportError<bool>("unhandled keyword");
+ return child->reportError<bool>("unhandled keyword");
}
break;
case Definition::Type::kBracket:
@@ -1313,13 +1475,24 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
if (fLastObject) {
TextParser checkDeprecated(child->fFileName, fLastObject->fTerminator + 1,
child->fStart, fLastObject->fLineCount);
- checkDeprecated.skipWhiteSpace();
+ if (!checkDeprecated.eof()) {
+ checkDeprecated.skipWhiteSpace();
+ if (checkDeprecated.startsWith("SK_ATTR_DEPRECATED")) {
+ break;
+ }
+ }
+ }
+ {
+ auto tokenIter = child->fParent->fTokens.begin();
+ std::advance(tokenIter, child->fParentIndex);
+ tokenIter = std::prev(tokenIter);
+ TextParser checkDeprecated(&*tokenIter);
if (checkDeprecated.startsWith("SK_ATTR_DEPRECATED")) {
break;
}
}
if (!this->parseMethod(child, markupDef)) {
- return this->reportError<bool>("failed to parse method");
+ return child->reportError<bool>("failed to parse method");
}
break;
case Bracket::kSlashSlash:
@@ -1356,7 +1529,7 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
break;
default:
preproError:
- return this->reportError<bool>("unhandled preprocessor");
+ return child->reportError<bool>("unhandled preprocessor");
}
break;
case Bracket::kAngle:
@@ -1365,20 +1538,28 @@ bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
case Bracket::kDebugCode:
// todo: handle this
break;
+ case Bracket::kSquare: {
+ // check to see if parent is operator, the only case we handle so far
+ auto prev = child->fParent->fTokens.begin();
+ std::advance(prev, child->fParentIndex - 1);
+ if (KeyWord::kOperator != prev->fKeyWord) {
+ return child->reportError<bool>("expected operator overload");
+ }
+ } break;
default:
- return this->reportError<bool>("unhandled bracket");
+ return child->reportError<bool>("unhandled bracket");
}
break;
case Definition::Type::kWord:
if (MarkType::kMember != child->fMarkType) {
- return this->reportError<bool>("unhandled word type");
+ return child->reportError<bool>("unhandled word type");
}
if (!this->parseMember(child, markupDef)) {
- return this->reportError<bool>("unparsable member");
+ return child->reportError<bool>("unparsable member");
}
break;
default:
- return this->reportError<bool>("unhandled type");
+ return child->reportError<bool>("unhandled type");
break;
}
return true;
@@ -1679,6 +1860,9 @@ bool IncludeParser::parseChar() {
}
Definition* member = &*namedIter;
member->fMarkType = MarkType::kMember;
+ if (!member->fTerminator) {
+ member->fTerminator = member->fContentEnd;
+ }
fParent->fChildren.push_back(member);
for (auto nameType = baseIter; nameType != namedIter; ++nameType) {
member->fChildren.push_back(&*nameType);