diff options
Diffstat (limited to 'tools/bookmaker/includeParser.h')
-rw-r--r-- | tools/bookmaker/includeParser.h | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/tools/bookmaker/includeParser.h b/tools/bookmaker/includeParser.h new file mode 100644 index 0000000000..cd01687f5d --- /dev/null +++ b/tools/bookmaker/includeParser.h @@ -0,0 +1,452 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef includeParser_DEFINED +#define includeParser_DEFINED + +#include "SkString.h" + +#include "parserCommon.h" + +class BmhParser; + +struct IClassDefinition : public Definition { + unordered_map<string, Definition*> fConsts; + unordered_map<string, Definition*> fDefines; + unordered_map<string, Definition*> fEnums; + unordered_map<string, Definition*> fMembers; + unordered_map<string, Definition*> fMethods; + unordered_map<string, Definition*> fStructs; + unordered_map<string, Definition*> fTypedefs; +}; + +class IncludeParser : public ParserCommon { +public: + enum class IsStruct { + kNo, + kYes, + }; + + enum class Elided { + kNo, + kYes, + }; + + struct CheckCode { + enum class State { + kNone, + kClassDeclaration, + kConstructor, + kForwardDeclaration, + kMethod, + }; + + void reset() { + fInDebugCode = nullptr; + fPrivateBrace = 0; + fBraceCount = 0; + fIndent = 0; + fDoubleReturn = 0; + fState = State::kNone; + fPrivateProtected = false; + fTypedefReturn = false; + fSkipAPI = false; + fSkipInline = false; + fSkipWarnUnused = false; + fWriteReturn = false; + } + + const char* fInDebugCode; + int fPrivateBrace; + int fBraceCount; + int fIndent; + int fDoubleReturn; + State fState; + bool fPrivateProtected; + bool fTypedefReturn; + bool fSkipAPI; + bool fSkipInline; + bool fSkipWarnUnused; + bool fWriteReturn; + }; + + IncludeParser() : ParserCommon() + , fMaps { + { &fIConstMap, MarkType::kConst } + , { &fIDefineMap, MarkType::kDefine } + , { &fIEnumMap, MarkType::kEnum } + , { &fIEnumMap, MarkType::kEnumClass } + , { &fIStructMap, MarkType::kStruct } + , { &fITemplateMap, MarkType::kTemplate } + , { &fITypedefMap, MarkType::kTypedef } + , { &fIUnionMap, MarkType::kUnion } + } + { + this->reset(); + } + + ~IncludeParser() override {} + + void addKeyword(KeyWord keyWord); + + void addPunctuation(Punctuation punctuation) { + fParent->fTokens.emplace_back(punctuation, fChar, fLineCount, fParent, '\0'); + } + + void addWord() { + fParent->fTokens.emplace_back(fIncludeWord, fChar, fLineCount, fParent, '\0'); + fIncludeWord = nullptr; + } + + bool advanceInclude(TextParser& i); + bool inAlignAs() const; + void checkForMissingParams(const vector<string>& methodParams, + const vector<string>& foundParams); + bool checkForWord(); + string className() const; + + string codeBlock(const Definition& def, bool inProgress) const { + return codeBlock(def.fMarkType, def.fName, inProgress); + } + + string codeBlock(MarkType markType, string name, bool inProgress) const { + if (MarkType::kClass == markType || MarkType::kStruct == markType) { + auto map = fIClassMap.find(name); + SkASSERT(fIClassMap.end() != map || inProgress); + return fIClassMap.end() != map ? map->second.fCode : ""; + } + if (MarkType::kConst == markType) { + auto map = fIConstMap.find(name); + SkASSERT(fIConstMap.end() != map); + return map->second->fCode; + } + if (MarkType::kDefine == markType) { + auto map = fIDefineMap.find(name); + SkASSERT(fIDefineMap.end() != map); + return map->second->fCode; + } + if (MarkType::kEnum == markType || MarkType::kEnumClass == markType) { + auto map = fIEnumMap.find(name); + SkASSERT(fIEnumMap.end() != map); + return map->second->fCode; + } + if (MarkType::kTypedef == markType) { + auto map = fITypedefMap.find(name); + SkASSERT(fITypedefMap.end() != map); + return map->second->fCode; + } + SkASSERT(0); + return ""; + } + + void codeBlockAppend(string& result, char ch) const; + void codeBlockSpaces(string& result, int indent) const; + + bool crossCheck(BmhParser& ); + IClassDefinition* defineClass(const Definition& includeDef, string className); + void dumpClassTokens(IClassDefinition& classDef); + void dumpComment(const Definition& ); + void dumpCommonTail(const Definition& ); + void dumpConst(const Definition& , string className); + void dumpDefine(const Definition& ); + void dumpEnum(const Definition& , string name); + bool dumpGlobals(string* globalFileName, long int* globalTell); + void dumpMethod(const Definition& , string className); + void dumpMember(const Definition& ); + bool dumpTokens(); + bool dumpTokens(string skClassName, string globalFileName, long int* globalTell); + void dumpTypedef(const Definition& , string className); + + string elidedCodeBlock(const Definition& ); + string filteredBlock(string inContents, string filterContents); + bool findComments(const Definition& includeDef, Definition* markupDef); + 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); + bool isConstructor(const Definition& token, string className); + bool isInternalName(const Definition& token); + bool isMember(const Definition& token) const; + bool isOperator(const Definition& token); + Definition* parentBracket(Definition* parent) const; + bool parseChar(); + bool parseComment(string filename, const char* start, const char* end, int lineCount, + Definition* markupDef); + bool parseClass(Definition* def, IsStruct); + bool parseConst(Definition* child, Definition* markupDef); + bool parseDefine(Definition* child, Definition* markupDef); + bool parseEnum(Definition* child, Definition* markupDef); + + bool parseFromFile(const char* path) override { + this->reset(); + if (!INHERITED::parseSetup(path)) { + return false; + } + string name(path); + return this->parseInclude(name); + } + + bool parseInclude(string name); + bool parseMember(Definition* child, Definition* markupDef); + bool parseMethod(Definition* child, Definition* markupDef); + bool parseObject(Definition* child, Definition* markupDef); + bool parseObjects(Definition* parent, Definition* markupDef); + bool parseTemplate(Definition* child, Definition* markupDef); + bool parseTypedef(Definition* child, Definition* markupDef); + bool parseUsing(); + bool parseUnion(); + + void popBracket() { + if (Definition::Type::kKeyWord == fParent->fType + && KeyWord::kTypename == fParent->fKeyWord) { + this->popObject(); + } + SkASSERT(Definition::Type::kBracket == fParent->fType); + this->popObject(); + Bracket bracket = this->topBracket(); + this->setBracketShortCuts(bracket); + } + + void pushBracket(Bracket bracket) { + this->setBracketShortCuts(bracket); + fParent->fTokens.emplace_back(bracket, fChar, fLineCount, fParent, '\0'); + Definition* container = &fParent->fTokens.back(); + this->addDefinition(container); + } + + bool references(const SkString& file) const; + + static void RemoveFile(const char* docs, const char* includes); + static void RemoveOneFile(const char* docs, const char* includesFileOrPath); + + void reset() override { + INHERITED::resetCommon(); + fRootTopic = nullptr; + fConstExpr = nullptr; + fInBrace = nullptr; + fIncludeWord = nullptr; + fLastObject = nullptr; + fPriorEnum = nullptr; + fPriorObject = nullptr; + fPrev = '\0'; + fInChar = false; + fInCharCommentString = false; + fInComment = false; + fInDefine = false; + fInEnum = false; + fInFunction = false; + fInString = false; + fFailed = false; + } + + void setBracketShortCuts(Bracket bracket) { + fInComment = Bracket::kSlashSlash == bracket || Bracket::kSlashStar == bracket; + fInString = Bracket::kString == bracket; + fInChar = Bracket::kChar == bracket; + fInCharCommentString = fInChar || fInComment || fInString; + } + + Bracket topBracket() const; + + template <typename T> + string uniqueName(const unordered_map<string, T>& m, string typeName) { + string base(typeName.size() > 0 ? typeName : "_anonymous"); + string name(base); + int anonCount = 1; + do { + auto iter = m.find(name); + if (iter == m.end()) { + return name; + } + name = base + '_'; + name += to_string(++anonCount); + } while (true); + // should never get here + return string(); + } + + void validate() const; + void writeCodeBlock(); + string writeCodeBlock(const Definition&, MarkType ); + string writeCodeBlock(TextParser& i, MarkType , int indent); + + 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, 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, string tagID, int spaces = 1) { + this->writeEndTag(tagType, tagID.c_str(), spaces); + } + + void writeIncompleteTag(const char* tagType, string tagID, int spaces = 1) { + this->writeString(string("#") + tagType + " " + tagID); + this->writeSpace(spaces); + this->writeString("incomplete"); + this->writeSpace(); + this->writeString("##"); + this->lf(1); + } + + void writeIncompleteTag(const char* tagType) { + this->writeString(string("#") + tagType + " incomplete ##"); + this->lf(1); + } + + 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, string col1) { + this->lf(1); + string row = "# " + col1 + string(pad - col1.length(), ' ') + " # ##"; + this->writeString(row); + this->lf(1); + } + + void writeTableRow(size_t pad1, string col1, size_t pad2, string col2) { + this->lf(1); + string row = "# " + col1 + string(pad1 - col1.length(), ' ') + " # " + + col2 + string(pad2 - col2.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, 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, string tagID) { + this->writeTag(tagType, tagID.c_str()); + } + + void writeTagTable(string tagType, string body) { + this->writeTag(tagType.c_str()); + this->writeSpace(1); + this->writeString("#"); + this->writeSpace(1); + this->writeString(body); + this->writeSpace(1); + this->writeString("##"); + } + +protected: + static void ValidateKeyWords(); + + struct DefinitionMap { + unordered_map<string, Definition*>* fInclude; + MarkType fMarkType; + }; + + vector<DefinitionMap> fMaps; + unordered_map<string, Definition> fIncludeMap; + list<Definition> fGlobals; + unordered_map<string, IClassDefinition> fIClassMap; + unordered_map<string, Definition*> fIConstMap; + unordered_map<string, Definition*> fIDefineMap; + unordered_map<string, Definition*> fIEnumMap; + unordered_map<string, Definition*> fIFunctionMap; + unordered_map<string, Definition*> fIStructMap; + unordered_map<string, Definition*> fITemplateMap; + unordered_map<string, Definition*> fITypedefMap; + unordered_map<string, Definition*> fIUnionMap; + CheckCode fCheck; + Definition* fRootTopic; + Definition* fConstExpr; + Definition* fInBrace; + Definition* fLastObject; + Definition* fPriorEnum; + Definition* fPriorObject; + int fPriorIndex; + const char* fIncludeWord; + Elided fElided; + char fPrev; + bool fInChar; + bool fInCharCommentString; + bool fInComment; + bool fInDefine; + bool fInEnum; + bool fInFunction; + bool fInString; + bool fFailed; + + typedef ParserCommon INHERITED; +}; + +#endif |