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>
This commit is contained in:
parent
fe69f9a50a
commit
9174bda24a
@ -2258,6 +2258,7 @@ int main(int argc, char** const argv) {
|
||||
return -1;
|
||||
}
|
||||
if (!FLAGS_tokens.isEmpty()) {
|
||||
includeParser.fDebugOut = FLAGS_stdout;
|
||||
if (includeParser.dumpTokens(FLAGS_tokens[0])) {
|
||||
bmhParser.fWroteOut = true;
|
||||
}
|
||||
@ -2290,6 +2291,7 @@ int main(int argc, char** const argv) {
|
||||
}
|
||||
if (!done && !FLAGS_ref.isEmpty() && FLAGS_examples.isEmpty()) {
|
||||
MdOut mdOut(bmhParser);
|
||||
mdOut.fDebugOut = FLAGS_stdout;
|
||||
if (mdOut.buildReferences(FLAGS_bmh[0], FLAGS_ref[0])) {
|
||||
bmhParser.fWroteOut = true;
|
||||
}
|
||||
@ -2306,6 +2308,7 @@ int main(int argc, char** const argv) {
|
||||
if (!bmhParser.checkExamples()) {
|
||||
return -1;
|
||||
}
|
||||
bmhParser.fDebugOut = FLAGS_stdout;
|
||||
if (!bmhParser.dumpExamples(FLAGS_examples[0])) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -880,6 +880,12 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T> T reportError(const char* errorStr) const {
|
||||
TextParser tp(this);
|
||||
tp.reportError(errorStr);
|
||||
return T();
|
||||
}
|
||||
|
||||
virtual RootDefinition* rootParent() { SkASSERT(0); return nullptr; }
|
||||
|
||||
void setParentIndex() {
|
||||
@ -1034,7 +1040,7 @@ public:
|
||||
fLinefeeds = 0;
|
||||
fSpaces = 0;
|
||||
fColumn = 0;
|
||||
fPendingSpace = false;
|
||||
fPendingSpace = 0;
|
||||
}
|
||||
|
||||
bool parseFile(const char* file, const char* suffix);
|
||||
@ -1056,7 +1062,7 @@ public:
|
||||
fOut = nullptr;
|
||||
fMaxLF = 2;
|
||||
fPendingLF = 0;
|
||||
fPendingSpace = false;
|
||||
fPendingSpace = 0;
|
||||
nl();
|
||||
}
|
||||
|
||||
@ -1081,6 +1087,7 @@ public:
|
||||
--size;
|
||||
}
|
||||
if (size <= 0) {
|
||||
fLastChar = '\0';
|
||||
return false;
|
||||
}
|
||||
SkASSERT(size < 16000);
|
||||
@ -1088,7 +1095,7 @@ public:
|
||||
fMaxLF = 1;
|
||||
}
|
||||
if (this->leadingPunctuation(data, (size_t) size)) {
|
||||
fPendingSpace = false;
|
||||
fPendingSpace = 0;
|
||||
}
|
||||
writePending();
|
||||
if (fDebugOut) {
|
||||
@ -1100,6 +1107,7 @@ public:
|
||||
}
|
||||
fprintf(fOut, "%.*s", size, data);
|
||||
int added = 0;
|
||||
fLastChar = data[size - 1];
|
||||
while (size > 0 && '\n' != data[--size]) {
|
||||
++added;
|
||||
}
|
||||
@ -1126,36 +1134,39 @@ public:
|
||||
|
||||
// write a pending space, so that two consecutive calls
|
||||
// don't double write, and trailing spaces on lines aren't written
|
||||
void writeSpace() {
|
||||
void writeSpace(int count = 1) {
|
||||
SkASSERT(!fPendingLF);
|
||||
SkASSERT(!fLinefeeds);
|
||||
SkASSERT(fColumn > 0);
|
||||
SkASSERT(!fSpaces);
|
||||
fPendingSpace = true;
|
||||
fPendingSpace = count;
|
||||
}
|
||||
|
||||
void writeString(const char* str) {
|
||||
SkASSERT(strlen(str) > 0);
|
||||
const size_t len = strlen(str);
|
||||
SkASSERT(len > 0);
|
||||
SkASSERT(' ' < str[0]);
|
||||
SkASSERT(' ' < str[strlen(str) - 1]);
|
||||
fLastChar = str[len - 1];
|
||||
SkASSERT(' ' < fLastChar);
|
||||
SkASSERT(!strchr(str, '\n'));
|
||||
if (this->leadingPunctuation(str, strlen(str))) {
|
||||
fPendingSpace = false;
|
||||
fPendingSpace = 0;
|
||||
}
|
||||
writePending();
|
||||
if (fDebugOut) {
|
||||
if (!strncmp("SK_SUPPORT", str, 10)) {
|
||||
SkDebugf("");
|
||||
}
|
||||
SkDebugf("%s", str);
|
||||
}
|
||||
SkASSERT(!strchr(str, '\n'));
|
||||
fprintf(fOut, "%s", str);
|
||||
fColumn += strlen(str);
|
||||
fColumn += len;
|
||||
fSpaces = 0;
|
||||
fLinefeeds = 0;
|
||||
fMaxLF = 2;
|
||||
}
|
||||
|
||||
void writeString(const string& str) {
|
||||
this->writeString(str.c_str());
|
||||
}
|
||||
|
||||
void writePending() {
|
||||
fPendingLF = SkTMin(fPendingLF, fMaxLF);
|
||||
bool wroteLF = false;
|
||||
@ -1178,14 +1189,14 @@ public:
|
||||
fColumn = fIndent;
|
||||
fSpaces = fIndent;
|
||||
}
|
||||
if (fPendingSpace) {
|
||||
for (int index = 0; index < fPendingSpace; ++index) {
|
||||
if (fDebugOut) {
|
||||
SkDebugf(" ");
|
||||
}
|
||||
fprintf(fOut, " ");
|
||||
++fColumn;
|
||||
fPendingSpace = false;
|
||||
}
|
||||
fPendingSpace = 0;
|
||||
}
|
||||
|
||||
unordered_map<string, sk_sp<SkData>> fRawData;
|
||||
@ -1193,13 +1204,14 @@ public:
|
||||
Definition* fParent;
|
||||
FILE* fOut;
|
||||
int fLinefeeds; // number of linefeeds last written, zeroed on non-space
|
||||
int fMaxLF; // number of linefeeds allowed
|
||||
int fPendingLF; // number of linefeeds to write (can be suppressed)
|
||||
int fSpaces; // number of spaces (indent) last written, zeroed on non-space
|
||||
int fColumn; // current column; number of chars past last linefeed
|
||||
int fIndent; // desired indention
|
||||
bool fPendingSpace; // a space should preceed the next string or block
|
||||
bool fDebugOut; // set true to write to std out
|
||||
int fMaxLF; // number of linefeeds allowed
|
||||
int fPendingLF; // number of linefeeds to write (can be suppressed)
|
||||
int fSpaces; // number of spaces (indent) last written, zeroed on non-space
|
||||
int fColumn; // current column; number of chars past last linefeed
|
||||
int fIndent; // desired indention
|
||||
int fPendingSpace; // one or two spaces should preceed the next string or block
|
||||
char fLastChar; // last written
|
||||
bool fDebugOut; // set true to write to std out
|
||||
private:
|
||||
typedef TextParser INHERITED;
|
||||
};
|
||||
@ -1515,8 +1527,12 @@ public:
|
||||
bool crossCheck(BmhParser& );
|
||||
IClassDefinition* defineClass(const Definition& includeDef, const string& className);
|
||||
void dumpClassTokens(IClassDefinition& classDef);
|
||||
void dumpComment(Definition* token);
|
||||
void dumpComment(const Definition& );
|
||||
void dumpEnum(const Definition& );
|
||||
void dumpMethod(const Definition& );
|
||||
void dumpMember(const Definition& );
|
||||
bool dumpTokens(const string& directory);
|
||||
bool dumpTokens(const string& directory, const string& skClassName);
|
||||
bool findComments(const Definition& includeDef, Definition* markupDef);
|
||||
|
||||
Definition* findIncludeObject(const Definition& includeDef, MarkType markType,
|
||||
@ -1547,8 +1563,6 @@ public:
|
||||
|
||||
static KeyWord FindKey(const char* start, const char* end);
|
||||
bool internalName(const Definition& ) const;
|
||||
void keywordEnd();
|
||||
void keywordStart(const char* keyword);
|
||||
bool parseChar();
|
||||
bool parseComment(const string& filename, const char* start, const char* end, int lineCount,
|
||||
Definition* markupDef);
|
||||
@ -1636,6 +1650,103 @@ public:
|
||||
|
||||
void validate() const;
|
||||
|
||||
void writeDefinition(const Definition& def) {
|
||||
if (def.length() > 1) {
|
||||
this->writeBlock((int) (def.fContentEnd - def.fContentStart), def.fContentStart);
|
||||
this->lf(1);
|
||||
}
|
||||
}
|
||||
|
||||
void writeDefinition(const Definition& def, const string& name, int spaces) {
|
||||
this->writeBlock((int) (def.fContentEnd - def.fContentStart), def.fContentStart);
|
||||
this->writeSpace(spaces);
|
||||
this->writeString(name);
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeEndTag() {
|
||||
this->lf(1);
|
||||
this->writeString("##");
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeEndTag(const char* tagType) {
|
||||
this->lf(1);
|
||||
this->writeString(string("#") + tagType + " ##");
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeEndTag(const char* tagType, const char* tagID, int spaces = 1) {
|
||||
this->lf(1);
|
||||
this->writeString(string("#") + tagType + " " + tagID);
|
||||
this->writeSpace(spaces);
|
||||
this->writeString("##");
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeEndTag(const char* tagType, const string& tagID, int spaces = 1) {
|
||||
this->writeEndTag(tagType, tagID.c_str(), spaces);
|
||||
}
|
||||
|
||||
void writeTableHeader(const char* col1, size_t pad, const char* col2) {
|
||||
this->lf(1);
|
||||
this->writeString("#Table");
|
||||
this->lf(1);
|
||||
this->writeString("#Legend");
|
||||
this->lf(1);
|
||||
string legend = "# ";
|
||||
legend += col1;
|
||||
if (pad > strlen(col1)) {
|
||||
legend += string(pad - strlen(col1), ' ');
|
||||
}
|
||||
legend += " # ";
|
||||
legend += col2;
|
||||
legend += " ##";
|
||||
this->writeString(legend);
|
||||
this->lf(1);
|
||||
this->writeString("#Legend ##");
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeTableRow(size_t pad, const string& col1) {
|
||||
this->lf(1);
|
||||
string row = "# " + col1 + string(pad - col1.length(), ' ') + " # ##";
|
||||
this->writeString(row);
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeTableTrailer() {
|
||||
this->lf(1);
|
||||
this->writeString("#Table ##");
|
||||
this->lf(1);
|
||||
}
|
||||
|
||||
void writeTag(const char* tagType) {
|
||||
this->lf(1);
|
||||
this->writeString("#");
|
||||
this->writeString(tagType);
|
||||
}
|
||||
|
||||
void writeTagNoLF(const char* tagType, const char* tagID) {
|
||||
this->writeString("#");
|
||||
this->writeString(tagType);
|
||||
this->writeSpace();
|
||||
this->writeString(tagID);
|
||||
}
|
||||
|
||||
void writeTagNoLF(const char* tagType, const string& tagID) {
|
||||
this->writeTagNoLF(tagType, tagID.c_str());
|
||||
}
|
||||
|
||||
void writeTag(const char* tagType, const char* tagID) {
|
||||
this->lf(1);
|
||||
this->writeTagNoLF(tagType, tagID);
|
||||
}
|
||||
|
||||
void writeTag(const char* tagType, const string& tagID) {
|
||||
this->writeTag(tagType, tagID.c_str());
|
||||
}
|
||||
|
||||
protected:
|
||||
static void ValidateKeyWords();
|
||||
|
||||
|
@ -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());
|
||||
this->writeTableRow(maxLen, name.substr(0, funcLen));
|
||||
}
|
||||
fprintf(fOut, "#Table ##" "\n");
|
||||
fprintf(fOut, "#Subtopic ##" "\n");
|
||||
fprintf(fOut, "" "\n");
|
||||
fprintf(fOut, "#Topic ##" "\n");
|
||||
fprintf(fOut, "" "\n");
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user