allow bookmaker methods to auto-populate
Adds
#Populate
as markup inside #Method, replacing
the method's description and #Param
and #Return. If present, this info
is retrieved from the include when
writing the web markdown and the
generated include.
TBR=caryclark@google.com
Docs-Preview: https://skia.org/?cl=162820
Bug: skia:
Change-Id: I5df16f227b86651d463e03ddd33849bb127891c0
Reviewed-on: https://skia-review.googlesource.com/c/162820
Commit-Queue: Cary Clark <caryclark@skia.org>
Auto-Submit: Cary Clark <caryclark@skia.org>
Reviewed-by: Cary Clark <caryclark@google.com>
Reviewed-by: Cary Clark <caryclark@skia.org>
diff --git a/docs/SkRect_Reference.bmh b/docs/SkRect_Reference.bmh
index d6dc20d..7571937 100644
--- a/docs/SkRect_Reference.bmh
+++ b/docs/SkRect_Reference.bmh
@@ -246,12 +246,7 @@
#In Constructors
#Line # constructs from ISize returning (0, 0, width, height) ##
-Returns constructed IRect set to (0, 0, size.width(), size.height()).
-Does not validate input; size.width() or size.height() may be negative.
-
-#Param size integer values for Rect width and height ##
-
-#Return bounds (0, 0, size.width(), size.height()) ##
+#Populate
#Example
SkRect rect1 = SkRect::MakeSize({2, 35});
diff --git a/site/user/api/SkColor_Reference.md b/site/user/api/SkColor_Reference.md
index 8a79b54..9ecda8d 100644
--- a/site/user/api/SkColor_Reference.md
+++ b/site/user/api/SkColor_Reference.md
@@ -321,8 +321,8 @@
---
<pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
-constexpr <a href='#SkAlpha'>SkAlpha</a> <a href='#SK_AlphaOPAQUE'>SK_AlphaOPAQUE</a> = 0xFF;
constexpr <a href='#SkAlpha'>SkAlpha</a> <a href='#SK_AlphaTRANSPARENT'>SK_AlphaTRANSPARENT</a> = 0x00;
+constexpr <a href='#SkAlpha'>SkAlpha</a> <a href='#SK_AlphaOPAQUE'>SK_AlphaOPAQUE</a> = 0xFF;
</pre>
<a href='#Alpha'>Alpha</a> constants are conveniences to represent fully transparent and fully
@@ -372,17 +372,17 @@
<pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorGREEN'>SK_ColorGREEN</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorLTGRAY'>SK_ColorLTGRAY</a>;
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorRED'>SK_ColorRED</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorGRAY'>SK_ColorGRAY</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorYELLOW'>SK_ColorYELLOW</a>;
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorBLACK'>SK_ColorBLACK</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorDKGRAY'>SK_ColorDKGRAY</a>;
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorTRANSPARENT'>SK_ColorTRANSPARENT</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorCYAN'>SK_ColorCYAN</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorDKGRAY'>SK_ColorDKGRAY</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorLTGRAY'>SK_ColorLTGRAY</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorGRAY'>SK_ColorGRAY</a>;
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorWHITE'>SK_ColorWHITE</a>;
-constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorMAGENTA'>SK_ColorMAGENTA</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorYELLOW'>SK_ColorYELLOW</a>;
constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorBLUE'>SK_ColorBLUE</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorCYAN'>SK_ColorCYAN</a>;
+constexpr <a href='#SkColor'>SkColor</a> <a href='#SK_ColorMAGENTA'>SK_ColorMAGENTA</a>;
</pre>
<a href='#Color'>Color</a> names are provided as conveniences, but are not otherwise special.
diff --git a/site/user/api/SkMatrix_Reference.md b/site/user/api/SkMatrix_Reference.md
index bb0feaf..a94b565 100644
--- a/site/user/api/SkMatrix_Reference.md
+++ b/site/user/api/SkMatrix_Reference.md
@@ -790,15 +790,15 @@
---
<pre style="padding: 1em 1em 1em 1em;width: 62.5em; background-color: #f0f0f0">
- static constexpr int <a href='#SkMatrix_kMPersp2'>kMPersp2</a> = 8;
- static constexpr int <a href='#SkMatrix_kMPersp0'>kMPersp0</a> = 6;
static constexpr int <a href='#SkMatrix_kMPersp1'>kMPersp1</a> = 7;
- static constexpr int <a href='#SkMatrix_kMSkewX'>kMSkewX</a> = 1;
+ static constexpr int <a href='#SkMatrix_kMPersp2'>kMPersp2</a> = 8;
+ static constexpr int <a href='#SkMatrix_kMSkewY'>kMSkewY</a> = 3;
static constexpr int <a href='#SkMatrix_kMTransX'>kMTransX</a> = 2;
static constexpr int <a href='#SkMatrix_kMScaleX'>kMScaleX</a> = 0;
- static constexpr int <a href='#SkMatrix_kMSkewY'>kMSkewY</a> = 3;
- static constexpr int <a href='#SkMatrix_kMScaleY'>kMScaleY</a> = 4;
+ static constexpr int <a href='#SkMatrix_kMSkewX'>kMSkewX</a> = 1;
static constexpr int <a href='#SkMatrix_kMTransY'>kMTransY</a> = 5;
+ static constexpr int <a href='#SkMatrix_kMScaleY'>kMScaleY</a> = 4;
+ static constexpr int <a href='#SkMatrix_kMPersp0'>kMPersp0</a> = 6;
</pre>
<a href='#Matrix'>Matrix</a> organizes its values in row order. These members correspond to
diff --git a/site/user/api/SkRect_Reference.md b/site/user/api/SkRect_Reference.md
index b4d170e..4129b38 100644
--- a/site/user/api/SkRect_Reference.md
+++ b/site/user/api/SkRect_Reference.md
@@ -402,13 +402,13 @@
static <a href='#SkRect'>SkRect</a> <a href='#SkRect_Make'>Make</a>(const <a href='undocumented#SkISize'>SkISize</a>& size)
</pre>
-Returns constructed <a href='SkIRect_Reference#IRect'>IRect</a> set to (0, 0, <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_width'>width</a>(), <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_height'>height</a>()).
+Returns constructed <a href='SkIRect_Reference#SkIRect'>SkIRect</a> set to (0, 0, <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_width'>width</a>(), <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_height'>height</a>()).
Does not validate input; <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_width'>width</a>() or <a href='#SkRect_Make_size'>size</a>.<a href='#SkRect_height'>height</a>() may be negative.
### Parameters
<table> <tr> <td><a name='SkRect_Make_size'><code><strong>size</strong></code></a></td>
- <td>integer values for <a href='#Rect'>Rect</a> width and height</td>
+ <td>integer values for <a href='#SkRect'>SkRect</a> width and height</td>
</tr>
</table>
diff --git a/tools/bookmaker/bookmaker.cpp b/tools/bookmaker/bookmaker.cpp
index a4968ef..7f0b9f9 100644
--- a/tools/bookmaker/bookmaker.cpp
+++ b/tools/bookmaker/bookmaker.cpp
@@ -147,7 +147,7 @@
, { "", MarkType::kPhraseParam, R_Y, E_N, 0 }
, { "", MarkType::kPhraseRef, R_N, E_N, 0 }
, { "Platform", MarkType::kPlatform, R_N, E_N, M(Example) | M(NoExample) }
-, { "Populate", MarkType::kPopulate, R_N, E_N, M(Code) }
+, { "Populate", MarkType::kPopulate, R_N, E_N, M(Code) | M(Method) }
, { "Private", MarkType::kPrivate, R_N, E_N, M_CSST | M_MDCM | M_E }
, { "Return", MarkType::kReturn, R_Y, E_N, M(Method) }
, { "", MarkType::kRow, R_Y, E_N, M(Table) | M(List) }
diff --git a/tools/bookmaker/bookmaker.h b/tools/bookmaker/bookmaker.h
index 160b715..950bad7 100644
--- a/tools/bookmaker/bookmaker.h
+++ b/tools/bookmaker/bookmaker.h
@@ -959,7 +959,7 @@
string formatFunction(Format format) const;
const Definition* hasChild(MarkType markType) const;
bool hasMatch(string name) const;
- const Definition* hasParam(string ref) const;
+ Definition* hasParam(string ref);
string incompleteMessage(DetailsType ) const;
bool isClone() const { return fClone; }
@@ -1765,6 +1765,7 @@
Definition* findIncludeObject(const Definition& includeDef, MarkType markType,
string typeName);
static KeyWord FindKey(const char* start, const char* end);
+ Definition* findMethod(const Definition& bmhDef);
Bracket grandParentBracket() const;
const Definition* include(string ) const;
bool isClone(const Definition& token);
@@ -2439,17 +2440,19 @@
Definition* checkParentsForMatch(Definition* test, string ref) const;
void childrenOut(Definition* def, const char* contentStart);
Definition* csParent();
- const Definition* findParamType();
+ Definition* findParamType();
string getMemberTypeName(const Definition* def, string* memberType);
static bool HasDetails(const Definition* def);
void htmlOut(string );
- const Definition* isDefined(const TextParser& , string ref, BmhParser::Resolvable );
- const Definition* isDefinedByParent(RootDefinition* root, string ref);
+ Definition* isDefined(const TextParser& , string ref, BmhParser::Resolvable );
+ Definition* isDefinedByParent(RootDefinition* root, string ref);
string linkName(const Definition* ) const;
- string linkRef(string leadingSpaces, const Definition*, string ref, BmhParser::Resolvable );
+ string linkRef(string leadingSpaces, Definition*, string ref, BmhParser::Resolvable );
void markTypeOut(Definition* , const Definition** prior);
void mdHeaderOut(int depth) { mdHeaderOutLF(depth, 2); }
void mdHeaderOutLF(int depth, int lf);
+ void parameterHeaderOut(TextParser& paramParser, const Definition** prior, Definition* def);
+ void parameterTrailerOut();
bool parseFromFile(const char* path) override { return true; }
void populateOne(Definition* def,
unordered_map<string, RootDefinition::SubtopicContents>& populator);
@@ -2498,6 +2501,7 @@
}
void resolveOut(const char* start, const char* end, BmhParser::Resolvable );
+ void returnHeaderOut(const Definition** prior, Definition* def);
void rowOut(string col1, const Definition* col2);
void rowOut(const char * name, string description, bool literalName);
diff --git a/tools/bookmaker/definition.cpp b/tools/bookmaker/definition.cpp
index 4f841e4..52620f8 100644
--- a/tools/bookmaker/definition.cpp
+++ b/tools/bookmaker/definition.cpp
@@ -467,9 +467,11 @@
bool expectReturn = this->methodHasReturn(name, &methodParser);
bool foundReturn = false;
bool foundException = false;
+ bool foundPopulate = false;
for (auto& child : fChildren) {
foundException |= MarkType::kDeprecated == child->fMarkType
|| MarkType::kExperimental == child->fMarkType;
+ foundPopulate |= MarkType::kPopulate == child->fMarkType;
if (MarkType::kReturn != child->fMarkType) {
if (MarkType::kParam == child->fMarkType) {
child->fVisited = false;
@@ -484,7 +486,7 @@
}
foundReturn = true;
}
- if (expectReturn && !foundReturn && !foundException) {
+ if (expectReturn && !foundReturn && !foundException && !foundPopulate) {
return methodParser.reportError<bool>("missing #Return marker");
}
const char* paren = methodParser.strnchr('(', methodParser.fEnd);
@@ -518,7 +520,7 @@
foundParam = true;
}
- if (!foundParam && !foundException) {
+ if (!foundParam && !foundException && !foundPopulate) {
return methodParser.reportError<bool>("no #Param found");
}
if (')' == nextEnd[0]) {
@@ -587,7 +589,8 @@
priorDef = nullptr;
}
if (!descEnd) {
- return incomplete ? true : methodParser.reportError<bool>("missing description");
+ return incomplete || foundPopulate ? true :
+ methodParser.reportError<bool>("missing description");
}
TextParser description(fFileName, descStart, descEnd, fLineCount);
// expect first word capitalized and pluralized. expect a trailing period
@@ -891,7 +894,7 @@
return nullptr;
}
-const Definition* Definition::hasParam(string ref) const {
+Definition* Definition::hasParam(string ref) {
SkASSERT(MarkType::kMethod == fMarkType);
for (auto iter : fChildren) {
if (MarkType::kParam != iter->fMarkType) {
@@ -900,7 +903,18 @@
if (iter->fName == ref) {
return &*iter;
}
-
+ }
+ for (auto& iter : fTokens) {
+ if (MarkType::kComment != iter.fMarkType) {
+ continue;
+ }
+ TextParser parser(&iter);
+ if (!parser.skipExact("@param ")) {
+ continue;
+ }
+ if (parser.skipExact(ref.c_str())) {
+ return &iter;
+ }
}
return nullptr;
}
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index ad77119..0716bc7 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -1844,6 +1844,21 @@
return &markupDef;
}
+Definition* IncludeParser::findMethod(const Definition& bmhDef) {
+ auto doubleColon = bmhDef.fName.find("::");
+ SkASSERT(string::npos != doubleColon); // more work to do to support global refs
+ string className = bmhDef.fName.substr(0, doubleColon);
+ const auto& iClass = fIClassMap.find(className);
+ SkASSERT(fIClassMap.end() != iClass);
+ string methodName = bmhDef.fName.substr(doubleColon + 2);
+ auto& iTokens = iClass->second.fTokens;
+ const auto& iMethod = std::find_if(iTokens.begin(), iTokens.end(),
+ [methodName](Definition& token) {
+ return MarkType::kMethod == token.fMarkType && methodName == token.fName; } );
+ SkASSERT(iTokens.end() != iMethod);
+ return &*iMethod;
+}
+
Definition* IncludeParser::parentBracket(Definition* parent) const {
while (parent && Definition::Type::kBracket != parent->fType) {
parent = parent->fParent;
diff --git a/tools/bookmaker/includeWriter.cpp b/tools/bookmaker/includeWriter.cpp
index 383a6a5..768ccf6 100644
--- a/tools/bookmaker/includeWriter.cpp
+++ b/tools/bookmaker/includeWriter.cpp
@@ -890,46 +890,67 @@
this->indentIn(IndentKind::kMethodOut);
fIndentNext = false;
}
- this->writeCommentHeader();
- fIndent += 4;
- this->descriptionOut(method, SkipFirstLine::kNo, Phrase::kNo);
- // compute indention column
- size_t column = 0;
- bool hasParmReturn = false;
- for (auto methodPart : method->fChildren) {
- if (MarkType::kParam == methodPart->fMarkType) {
- column = SkTMax(column, methodPart->fName.length());
- hasParmReturn = true;
- } else if (MarkType::kReturn == methodPart->fMarkType) {
- hasParmReturn = true;
+ if (method->fChildren.end() != std::find_if(method->fChildren.begin(), method->fChildren.end(),
+ [](const Definition* def) { return MarkType::kPopulate == def->fMarkType; } )) {
+ int commentIndex = child.fParentIndex;
+ auto iter = child.fParent->fTokens.begin();
+ std::advance(iter, commentIndex);
+ SkDEBUGCODE(bool sawMethod = false);
+ while (--commentIndex >= 0) {
+ std::advance(iter, -1);
+ if (Bracket::kSlashStar == iter->fBracket) {
+ SkASSERT(sawMethod);
+ break;
+ }
+ SkASSERT(!sawMethod);
+ SkDEBUGCODE(sawMethod = MarkType::kMethod == iter->fMarkType);
}
- }
- if (hasParmReturn) {
this->lf(2);
- column += fIndent + sizeof("@return ");
- int saveIndent = fIndent;
+ this->writeString("/");
+ this->writeBlock(iter->length(), iter->fContentStart);
+ this->lfcr();
+ } else {
+ this->writeCommentHeader();
+ fIndent += 4;
+ this->descriptionOut(method, SkipFirstLine::kNo, Phrase::kNo);
+ // compute indention column
+ size_t column = 0;
+ bool hasParmReturn = false;
for (auto methodPart : method->fChildren) {
if (MarkType::kParam == methodPart->fMarkType) {
- this->writeString("@param");
- this->writeSpace();
- this->writeString(methodPart->fName.c_str());
+ column = SkTMax(column, methodPart->fName.length());
+ hasParmReturn = true;
} else if (MarkType::kReturn == methodPart->fMarkType) {
- this->writeString("@return");
- } else {
- continue;
+ hasParmReturn = true;
}
- this->indentToColumn(column);
- fIndent = column;
- this->descriptionOut(methodPart, SkipFirstLine::kNo, Phrase::kYes);
- fIndent = saveIndent;
+ }
+ if (hasParmReturn) {
+ this->lf(2);
+ column += fIndent + sizeof("@return ");
+ int saveIndent = fIndent;
+ for (auto methodPart : method->fChildren) {
+ if (MarkType::kParam == methodPart->fMarkType) {
+ this->writeString("@param");
+ this->writeSpace();
+ this->writeString(methodPart->fName.c_str());
+ } else if (MarkType::kReturn == methodPart->fMarkType) {
+ this->writeString("@return");
+ } else {
+ continue;
+ }
+ this->indentToColumn(column);
+ fIndent = column;
+ this->descriptionOut(methodPart, SkipFirstLine::kNo, Phrase::kYes);
+ fIndent = saveIndent;
+ this->lfcr();
+ }
+ } else {
this->lfcr();
}
- } else {
+ fIndent -= 4;
this->lfcr();
+ this->writeCommentTrailer(OneLine::kNo);
}
- fIndent -= 4;
- this->lfcr();
- this->writeCommentTrailer(OneLine::kNo);
fBmhMethod = nullptr;
fMethodDef = nullptr;
fEnumDef = nullptr;
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 0f322b0..7cca263 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -440,7 +440,7 @@
if (BmhParser::Resolvable::kCode == resolvable) {
fixup_const_function_name(&ref);
}
- if (const Definition* def = this->isDefined(t, ref, resolvable)) {
+ if (Definition* def = this->isDefined(t, ref, resolvable)) {
if (MarkType::kExternal == def->fMarkType) {
(void) this->anchorRef("undocumented#" + ref, ""); // for anchor validate
add_ref(leadingSpaces, ref, &result);
@@ -465,7 +465,7 @@
// otherwise flag as error
int suffix = '2';
bool foundMatch = false;
- const Definition* altDef = def;
+ Definition* altDef = def;
while (altDef && suffix <= '9') {
if ((foundMatch = altDef->paramsMatch(fullRef, ref))) {
def = altDef;
@@ -523,7 +523,7 @@
}
t.next();
ref = string(start, t.fChar - start);
- if (const Definition* def = this->isDefined(t, ref, BmhParser::Resolvable::kYes)) {
+ if (Definition* def = this->isDefined(t, ref, BmhParser::Resolvable::kYes)) {
SkASSERT(def->fFiddle.length());
result += linkRef(leadingSpaces, def, ref, resolvable);
continue;
@@ -554,7 +554,7 @@
// TODO:
// look for all lowercase w/o trailing parens as mistaken method matches
// will also need to see if Example Description matches var in example
- const Definition* def = nullptr;
+ Definition* def = nullptr;
if (fMethod && (def = fMethod->hasParam(ref))) {
result += linkRef(leadingSpaces, def, ref, resolvable);
fLastParam = def;
@@ -567,7 +567,7 @@
// || '.' != t.backup(ref.c_str())
&& ('k' != ref[0] && string::npos == ref.find("_Private"))) {
if ('.' == wordStart[0] && (distFromParam >= 1 && distFromParam <= 16)) {
- const Definition* paramType = this->findParamType();
+ Definition* paramType = this->findParamType();
if (paramType) {
string fullName = paramType->fName + "::" + ref;
if (paramType->hasMatch(fullName)) {
@@ -970,7 +970,7 @@
return csParent;
}
-const Definition* MdOut::findParamType() {
+Definition* MdOut::findParamType() {
SkASSERT(fMethod);
TextParser parser(fMethod->fFileName, fMethod->fStart, fMethod->fContentStart,
fMethod->fLineCount);
@@ -985,7 +985,7 @@
SkASSERT(!parser.eof());
string name = string(word, parser.fChar - word);
if (fLastParam->fName == name) {
- const Definition* paramType = this->isDefined(parser, lastFull,
+ Definition* paramType = this->isDefined(parser, lastFull,
BmhParser::Resolvable::kOut);
return paramType;
}
@@ -1044,11 +1044,11 @@
FPRINTF("%s", s.c_str());
}
-const Definition* MdOut::isDefinedByParent(RootDefinition* root, string ref) {
+Definition* MdOut::isDefinedByParent(RootDefinition* root, string ref) {
if (ref == root->fName) {
return root;
}
- if (const Definition* definition = root->find(ref, RootDefinition::AllowParens::kYes)) {
+ if (Definition* definition = root->find(ref, RootDefinition::AllowParens::kYes)) {
return definition;
}
Definition* test = root;
@@ -1068,7 +1068,7 @@
if (ref == leaf.first) {
return leaf.second;
}
- const Definition* definition = leaf.second->find(ref,
+ Definition* definition = leaf.second->find(ref,
RootDefinition::AllowParens::kYes);
if (definition) {
return definition;
@@ -1096,7 +1096,7 @@
return nullptr;
}
-const Definition* MdOut::isDefined(const TextParser& parser, string ref,
+Definition* MdOut::isDefined(const TextParser& parser, string ref,
BmhParser::Resolvable resolvable) {
auto rootIter = fBmhParser.fClassMap.find(ref);
if (rootIter != fBmhParser.fClassMap.end()) {
@@ -1126,15 +1126,15 @@
if (defineIter != fBmhParser.fDefineMap.end()) {
return &defineIter->second;
}
- for (const auto& external : fBmhParser.fExternals) {
+ for (auto& external : fBmhParser.fExternals) {
if (external.fName == ref) {
return &external;
}
}
- if (const Definition* definition = this->isDefinedByParent(fRoot, ref)) {
+ if (Definition* definition = this->isDefinedByParent(fRoot, ref)) {
return definition;
}
- if (const Definition* definition = this->isDefinedByParent(fSubtopic, ref)) {
+ if (Definition* definition = this->isDefinedByParent(fSubtopic, ref)) {
return definition;
}
size_t doubleColon = ref.find("::");
@@ -1143,7 +1143,7 @@
auto classIter = fBmhParser.fClassMap.find(className);
if (classIter != fBmhParser.fClassMap.end()) {
RootDefinition& classDef = classIter->second;
- const Definition* result = classDef.find(ref, RootDefinition::AllowParens::kYes);
+ Definition* result = classDef.find(ref, RootDefinition::AllowParens::kYes);
if (result) {
return result;
}
@@ -1202,14 +1202,14 @@
string className(ref, 0, pos);
auto classIter = fBmhParser.fClassMap.find(className);
if (classIter != fBmhParser.fClassMap.end()) {
- if (const Definition* definition = classIter->second.find(ref,
+ if (Definition* definition = classIter->second.find(ref,
RootDefinition::AllowParens::kYes)) {
return definition;
}
}
auto enumIter = fBmhParser.fEnumMap.find(className);
if (enumIter != fBmhParser.fEnumMap.end()) {
- if (const Definition* definition = enumIter->second.find(ref,
+ if (Definition* definition = enumIter->second.find(ref,
RootDefinition::AllowParens::kYes)) {
return definition;
}
@@ -1242,13 +1242,20 @@
// for now, hard-code to html links
// def should not include SkXXX_
-string MdOut::linkRef(string leadingSpaces, const Definition* def,
+string MdOut::linkRef(string leadingSpaces, Definition* def,
string ref, BmhParser::Resolvable resolvable) {
string buildup;
string refName;
const string* str = &def->fFiddle;
- SkASSERT(str->length() > 0);
string classPart = *str;
+ bool fromInclude = "" == classPart;
+ if (fromInclude) {
+ const Definition* parent = def->csParent();
+ SkASSERT(parent);
+ classPart = parent->fName;
+ refName = classPart + '_' + def->fParent->fName + '_' + ref;
+ }
+ SkASSERT(classPart.length() > 0);
bool globalEnumMember = false;
if (MarkType::kAlias == def->fMarkType) {
def = def->fParent;
@@ -1265,18 +1272,22 @@
} else if (MarkType::kTopic == def->fMarkType) {
refName = def->fName;
} else {
- if ('k' == (*str)[0] && string::npos != str->find("_Sk")) {
+ if ('k' == classPart[0] && string::npos != classPart.find("_Sk")) {
globalEnumMember = true;
} else {
- SkASSERT("Sk" == str->substr(0, 2) || "SK" == str->substr(0, 2)
+ SkASSERT("Sk" == classPart.substr(0, 2) || "SK" == classPart.substr(0, 2)
// FIXME: kitchen sink catch below, need to do better
|| string::npos != def->fFileName.find("undocumented"));
- size_t under = str->find('_');
- classPart = string::npos != under ? str->substr(0, under) : *str;
+ size_t under = classPart.find('_');
+ if (string::npos != under) {
+ classPart = classPart.substr(0, under);
+ }
}
- refName = def->fFiddle;
+ if (!fromInclude) {
+ refName = def->fFiddle;
+ }
}
- bool classMatch = fRoot->fFileName == def->fFileName;
+ bool classMatch = fRoot->fFileName == def->fFileName || fromInclude;
SkASSERT(fRoot);
SkASSERT(fRoot->fFileName.length());
if (!classMatch) {
@@ -1751,41 +1762,13 @@
case MarkType::kOutdent:
break;
case MarkType::kParam: {
- if (TableState::kNone == fTableState) {
- SkASSERT(!*prior || MarkType::kParam != (*prior)->fMarkType);
- this->mdHeaderOut(3);
- this->htmlOut(
- "Parameters\n"
- "\n"
- "<table>"
- );
- this->lf(1);
- fTableState = TableState::kRow;
- }
- if (TableState::kRow == fTableState) {
- FPRINTF(" <tr>");
- this->lf(1);
- fTableState = TableState::kColumn;
- }
TextParser paramParser(def->fFileName, def->fStart, def->fContentStart,
def->fLineCount);
paramParser.skipWhiteSpace();
SkASSERT(paramParser.startsWith("#Param"));
paramParser.next(); // skip hash
paramParser.skipToNonName(); // skip Param
- paramParser.skipSpace();
- const char* paramName = paramParser.fChar;
- paramParser.skipToSpace();
- string paramNameStr(paramName, (int) (paramParser.fChar - paramName));
- if (!this->checkParamReturnBody(def)) {
- *prior = def;
- return;
- }
- string refNameStr = def->fParent->fFiddle + "_" + paramNameStr;
- this->htmlOut(" <td>" + anchorDef(refNameStr,
- "<code><strong>" + paramNameStr + "</strong></code>") + "</td>");
- this->lfAlways(1);
- FPRINTF(" <td>");
+ this->parameterHeaderOut(paramParser, prior, def);
} break;
case MarkType::kPhraseDef:
// skip text and children
@@ -1851,58 +1834,101 @@
break;
case MarkType::kPopulate: {
Definition* parent = def->fParent;
- SkASSERT(parent && MarkType::kCode == parent->fMarkType);
- auto inDef = std::find_if(parent->fChildren.begin(), parent->fChildren.end(),
- [](const Definition* child) { return MarkType::kIn == child->fMarkType; });
- if (parent->fChildren.end() != inDef) {
- auto filterDef = std::find_if(parent->fChildren.begin(), parent->fChildren.end(),
- [](const Definition* child) { return MarkType::kFilter == child->fMarkType; });
- SkASSERT(parent->fChildren.end() != filterDef);
- string codeBlock = fIncludeParser.filteredBlock(
- string((*inDef)->fContentStart, (*inDef)->length()),
- string((*filterDef)->fContentStart, (*filterDef)->length()));
- this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
- this->resolvable(parent));
- break;
- }
- // find include matching code parent
- Definition* grand = parent->fParent;
- SkASSERT(grand);
- if (MarkType::kClass == grand->fMarkType
- || MarkType::kStruct == grand->fMarkType
- || MarkType::kEnum == grand->fMarkType
- || MarkType::kEnumClass == grand->fMarkType
- || MarkType::kTypedef == grand->fMarkType
- || MarkType::kDefine == grand->fMarkType) {
- string codeBlock = fIncludeParser.codeBlock(*grand, fInProgress);
- this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
- this->resolvable(parent));
- } else if (MarkType::kTopic == grand->fMarkType) {
- // use bmh file name to find include file name
- size_t start = grand->fFileName.rfind("Sk");
- SkASSERT(start != string::npos);
- size_t end = grand->fFileName.rfind("_Reference");
- SkASSERT(end != string::npos && end > start);
- string incName(grand->fFileName.substr(start, end - start));
- const Definition* includeDef = fIncludeParser.include(incName + ".h");
- SkASSERT(includeDef);
- string codeBlock;
- this->addCodeBlock(includeDef, codeBlock);
- this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
- this->resolvable(parent));
+ SkASSERT(parent);
+ if (MarkType::kCode == parent->fMarkType) {
+ auto inDef = std::find_if(parent->fChildren.begin(), parent->fChildren.end(),
+ [](const Definition* child) { return MarkType::kIn == child->fMarkType; });
+ if (parent->fChildren.end() != inDef) {
+ auto filterDef = std::find_if(parent->fChildren.begin(),
+ parent->fChildren.end(), [](const Definition* child) {
+ return MarkType::kFilter == child->fMarkType; });
+ SkASSERT(parent->fChildren.end() != filterDef);
+ string codeBlock = fIncludeParser.filteredBlock(
+ string((*inDef)->fContentStart, (*inDef)->length()),
+ string((*filterDef)->fContentStart, (*filterDef)->length()));
+ this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
+ this->resolvable(parent));
+ break;
+ }
+ // find include matching code parent
+ Definition* grand = parent->fParent;
+ SkASSERT(grand);
+ if (MarkType::kClass == grand->fMarkType
+ || MarkType::kStruct == grand->fMarkType
+ || MarkType::kEnum == grand->fMarkType
+ || MarkType::kEnumClass == grand->fMarkType
+ || MarkType::kTypedef == grand->fMarkType
+ || MarkType::kDefine == grand->fMarkType) {
+ string codeBlock = fIncludeParser.codeBlock(*grand, fInProgress);
+ this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
+ this->resolvable(parent));
+ } else if (MarkType::kTopic == grand->fMarkType) {
+ // use bmh file name to find include file name
+ size_t start = grand->fFileName.rfind("Sk");
+ SkASSERT(start != string::npos);
+ size_t end = grand->fFileName.rfind("_Reference");
+ SkASSERT(end != string::npos && end > start);
+ string incName(grand->fFileName.substr(start, end - start));
+ const Definition* includeDef = fIncludeParser.include(incName + ".h");
+ SkASSERT(includeDef);
+ string codeBlock;
+ this->addCodeBlock(includeDef, codeBlock);
+ this->resolveOut(codeBlock.c_str(), codeBlock.c_str() + codeBlock.length(),
+ this->resolvable(parent));
+ } else {
+ SkASSERT(MarkType::kSubtopic == grand->fMarkType);
+ auto inTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
+ [](Definition* child){return MarkType::kIn == child->fMarkType;});
+ SkASSERT(grand->fChildren.end() != inTag);
+ auto filterTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
+ [](Definition* child){return MarkType::kFilter == child->fMarkType;});
+ SkASSERT(grand->fChildren.end() != filterTag);
+ string inContents((*inTag)->fContentStart, (*inTag)->length());
+ string filterContents((*filterTag)->fContentStart, (*filterTag)->length());
+ string filteredBlock = fIncludeParser.filteredBlock(inContents, filterContents);
+ this->resolveOut(filteredBlock.c_str(), filteredBlock.c_str()
+ + filteredBlock.length(), this->resolvable(parent));
+ }
} else {
- SkASSERT(MarkType::kSubtopic == grand->fMarkType);
- auto inTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
- [](Definition* child){return MarkType::kIn == child->fMarkType;});
- SkASSERT(grand->fChildren.end() != inTag);
- auto filterTag = std::find_if(grand->fChildren.begin(), grand->fChildren.end(),
- [](Definition* child){return MarkType::kFilter == child->fMarkType;});
- SkASSERT(grand->fChildren.end() != filterTag);
- string inContents((*inTag)->fContentStart, (*inTag)->length());
- string filterContents((*filterTag)->fContentStart, (*filterTag)->length());
- string filteredBlock = fIncludeParser.filteredBlock(inContents, filterContents);
- this->resolveOut(filteredBlock.c_str(), filteredBlock.c_str()
- + filteredBlock.length(), this->resolvable(parent));
+ SkASSERT(MarkType::kMethod == parent->fMarkType);
+ // retrieve parameters, return, description from include
+ Definition* iMethod = fIncludeParser.findMethod(*parent);
+ SkDebugf("");
+ bool wroteParam = false;
+ fMethod = iMethod;
+ for (auto& entry : iMethod->fTokens) {
+ if (MarkType::kComment != entry.fMarkType) {
+ continue;
+ }
+ TextParser parser(&entry);
+ if (parser.skipExact("@param ")) { // write parameters, if any
+ this->parameterHeaderOut(parser, prior, def);
+ this->resolveOut(parser.fChar, parser.fEnd, BmhParser::Resolvable::kYes);
+ this->parameterTrailerOut();
+ wroteParam = true;
+ continue;
+ }
+ if (wroteParam) {
+ this->writePending();
+ FPRINTF("</table>");
+ this->lf(2);
+ fTableState = TableState::kNone;
+ wroteParam = false;
+ }
+ if (parser.skipExact("@return ")) { // write return, if any
+ this->returnHeaderOut(prior, def);
+ this->resolveOut(parser.fChar, parser.fEnd, BmhParser::Resolvable::kYes);
+ this->lf(2);
+ continue;
+ }
+ if (1 == entry.length() && '/' == entry.fContentStart[0]) {
+ continue;
+ }
+ this->resolveOut(entry.fContentStart, entry.fContentEnd,
+ BmhParser::Resolvable::kYes); // write description
+ this->lf(1);
+ }
+ fMethod = nullptr;
}
} break;
case MarkType::kPrivate:
@@ -1912,13 +1938,7 @@
this->lf(2);
break;
case MarkType::kReturn:
- this->mdHeaderOut(3);
- FPRINTF("Return Value");
- if (!this->checkParamReturnBody(def)) {
- *prior = def;
- return;
- }
- this->lf(2);
+ this->returnHeaderOut(prior, def);
break;
case MarkType::kRow:
if (fInList) {
@@ -2142,13 +2162,7 @@
lookForOneLiner = false;
}
case MarkType::kParam:
- SkASSERT(TableState::kColumn == fTableState);
- fTableState = TableState::kRow;
- this->writePending();
- FPRINTF("</td>");
- this->lfAlways(1);
- FPRINTF(" </tr>");
- this->lfAlways(1);
+ this->parameterTrailerOut();
break;
case MarkType::kReturn:
case MarkType::kSeeAlso:
@@ -2195,6 +2209,48 @@
FPRINTF(" ");
}
+void MdOut::parameterHeaderOut(TextParser& paramParser, const Definition** prior, Definition* def) {
+ if (TableState::kNone == fTableState) {
+ SkASSERT(!*prior || MarkType::kParam != (*prior)->fMarkType);
+ this->mdHeaderOut(3);
+ this->htmlOut(
+ "Parameters\n"
+ "\n"
+ "<table>"
+ );
+ this->lf(1);
+ fTableState = TableState::kRow;
+ }
+ if (TableState::kRow == fTableState) {
+ FPRINTF(" <tr>");
+ this->lf(1);
+ fTableState = TableState::kColumn;
+ }
+ paramParser.skipSpace();
+ const char* paramName = paramParser.fChar;
+ paramParser.skipToSpace();
+ string paramNameStr(paramName, (int) (paramParser.fChar - paramName));
+ if (MarkType::kPopulate != def->fMarkType && !this->checkParamReturnBody(def)) {
+ *prior = def;
+ return;
+ }
+ string refNameStr = def->fParent->fFiddle + "_" + paramNameStr;
+ this->htmlOut(" <td>" + this->anchorDef(refNameStr,
+ "<code><strong>" + paramNameStr + "</strong></code>") + "</td>");
+ this->lfAlways(1);
+ FPRINTF(" <td>");
+}
+
+void MdOut::parameterTrailerOut() {
+ SkASSERT(TableState::kColumn == fTableState);
+ fTableState = TableState::kRow;
+ this->writePending();
+ FPRINTF("</td>");
+ this->lfAlways(1);
+ FPRINTF(" </tr>");
+ this->lfAlways(1);
+}
+
void MdOut::populateOne(Definition* def,
unordered_map<string, RootDefinition::SubtopicContents>& populator) {
if (MarkType::kConst == def->fMarkType) {
@@ -2370,6 +2426,16 @@
}
}
+void MdOut::returnHeaderOut(const Definition** prior, Definition* def) {
+ this->mdHeaderOut(3);
+ FPRINTF("Return Value");
+ if (MarkType::kPopulate != def->fMarkType && !this->checkParamReturnBody(def)) {
+ *prior = def;
+ return;
+ }
+ this->lf(2);
+}
+
void MdOut::rowOut(string col1, const Definition* col2) {
FPRINTF("%s", fOddRow ? kTR_Dark.c_str() : " <tr>");
this->lfAlways(1);