diff options
author | Cary Clark <caryclark@skia.org> | 2017-09-19 17:39:32 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-19 22:04:19 +0000 |
commit | 9174bda24aef222beaff1d9d80ea80a063852c74 (patch) | |
tree | 7143dfc0f50303df1adf8f6fa9186f39bf2a1c18 /tools/bookmaker/includeParser.cpp | |
parent | fe69f9a50ac1a6a61c9dda9c28c97599131656ee (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.cpp | 604 |
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); |