blob: dcd834616d34c5810eaad45b4a9157bcf8e75ae5 [file] [log] [blame]
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "bmhParser.h"
// replace #Method description, #Param, #Return with #Populate
// if description, params, return are free of phrase refs
bool HackParser::hackFiles() {
string filename(fFileName);
size_t len = filename.length() - 1;
while (len > 0 && (isalnum(filename[len]) || '_' == filename[len] || '.' == filename[len])) {
--len;
}
filename = filename.substr(len + 1);
if (filename.substr(0, 2) != "Sk") {
return true;
}
size_t under = filename.find('_');
SkASSERT(under);
string className = filename.substr(0, under);
fOut = fopen(filename.c_str(), "wb");
if (!fOut) {
SkDebugf("could not open output file %s\n", filename.c_str());
return false;
}
auto mapEntry = fBmhParser.fClassMap.find(className);
if (fBmhParser.fClassMap.end() == mapEntry) {
remove(filename.c_str());
return true;
}
const Definition* classMarkup = &mapEntry->second;
const Definition* root = classMarkup->fParent;
SkASSERT(root);
SkASSERT(root->fTerminator);
SkASSERT('\n' == root->fTerminator[0]);
SkASSERT(!root->fParent);
fStart = root->fStart;
fChar = fStart;
fEnd = root->fTerminator;
this->replaceWithPop(root);
FPRINTF("%.*s", (int) (fEnd - fChar), fChar);
if ('\n' != fEnd[-1]) {
FPRINTF("\n");
}
fclose(fOut);
if (ParserCommon::WrittenFileDiffers(filename, root->fFileName)) {
SkDebugf("wrote %s\n", filename.c_str());
} else {
remove(filename.c_str());
}
return true;
}
// returns true if topic has method
void HackParser::replaceWithPop(const Definition* root) {
for (auto child : root->fChildren) {
if (MarkType::kClass == child->fMarkType || MarkType::kStruct == child->fMarkType
|| MarkType::kSubtopic == child->fMarkType) {
this->replaceWithPop(child);
}
if (MarkType::kMethod != child->fMarkType) {
continue;
}
auto& grans = child->fChildren;
if (grans.end() != std::find_if(grans.begin(), grans.end(),
[](const Definition* def) {
return MarkType::kPopulate == def->fMarkType
|| MarkType::kPhraseRef == def->fMarkType
|| MarkType::kFormula == def->fMarkType
|| MarkType::kAnchor == def->fMarkType
|| MarkType::kList == def->fMarkType
|| MarkType::kTable == def->fMarkType;
} )) {
continue;
}
// write #Populate in place of description, #Param(s), #Return (if present)
const char* keep = child->fContentStart;
const char* next = nullptr;
for (auto gran : grans) {
if (MarkType::kIn == gran->fMarkType || MarkType::kLine == gran->fMarkType) {
keep = gran->fTerminator;
continue;
}
if (MarkType::kExample == gran->fMarkType
|| MarkType::kNoExample == gran->fMarkType) {
next = gran->fStart;
break;
}
if (MarkType::kParam == gran->fMarkType
|| MarkType::kReturn == gran->fMarkType
|| MarkType::kToDo == gran->fMarkType
|| MarkType::kComment == gran->fMarkType) {
continue;
}
SkDebugf(""); // convenient place to set a breakpoint
}
SkASSERT(next);
FPRINTF("%.*s", (int) (keep - fChar), fChar);
if ('\n' != keep[-1]) {
FPRINTF("\n");
}
FPRINTF("#Populate\n\n");
fChar = next;
}
}