1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef definition_DEFINED 9 #define definition_DEFINED 10 11 #include "textParser.h" 12 13 class RootDefinition; 14 class TextParser; 15 16 class Definition : public NonAssignable { 17 public: 18 enum Type { 19 kNone, 20 kWord, 21 kMark, 22 kKeyWord, 23 kBracket, 24 kPunctuation, 25 kFileType, 26 }; 27 28 enum class MethodType { 29 kNone, 30 kConstructor, 31 kDestructor, 32 kOperator, 33 }; 34 35 enum class Operator { 36 kUnknown, 37 kAdd, 38 kAddTo, 39 kArray, 40 kCast, 41 kCopy, 42 kDelete, 43 kDereference, 44 kEqual, 45 kMinus, 46 kMove, 47 kMultiply, 48 kMultiplyBy, 49 kNew, 50 kNotEqual, 51 kSubtract, 52 kSubtractFrom, 53 }; 54 55 enum class Format { 56 kIncludeReturn, 57 kOmitReturn, 58 }; 59 60 enum class Details { 61 kNone, 62 kSoonToBe_Deprecated, 63 kTestingOnly_Experiment, 64 kDoNotUse_Experiment, 65 kNotReady_Experiment, 66 }; 67 68 enum class DetailsType { 69 kPhrase, 70 kSentence, 71 }; 72 Definition()73 Definition() {} 74 Definition(const char * start,const char * end,int line,Definition * parent,char mc)75 Definition(const char* start, const char* end, int line, Definition* parent, char mc) 76 : fStart(start) 77 , fContentStart(start) 78 , fContentEnd(end) 79 , fParent(parent) 80 , fLineCount(line) 81 , fType(Type::kWord) 82 , fMC(mc) { 83 if (parent) { 84 SkASSERT(parent->fFileName.length() > 0); 85 fFileName = parent->fFileName; 86 } 87 this->setParentIndex(); 88 } 89 Definition(MarkType markType,const char * start,int line,Definition * parent,char mc)90 Definition(MarkType markType, const char* start, int line, Definition* parent, char mc) 91 : Definition(markType, start, nullptr, line, parent, mc) { 92 } 93 Definition(MarkType markType,const char * start,const char * end,int line,Definition * parent,char mc)94 Definition(MarkType markType, const char* start, const char* end, int line, Definition* parent, char mc) 95 : Definition(start, end, line, parent, mc) { 96 fMarkType = markType; 97 fType = Type::kMark; 98 } 99 Definition(Bracket bracket,const char * start,int lineCount,Definition * parent,char mc)100 Definition(Bracket bracket, const char* start, int lineCount, Definition* parent, char mc) 101 : Definition(start, nullptr, lineCount, parent, mc) { 102 fBracket = bracket; 103 fType = Type::kBracket; 104 } 105 Definition(KeyWord keyWord,const char * start,const char * end,int lineCount,Definition * parent,char mc)106 Definition(KeyWord keyWord, const char* start, const char* end, int lineCount, 107 Definition* parent, char mc) 108 : Definition(start, end, lineCount, parent, mc) { 109 fKeyWord = keyWord; 110 fType = Type::kKeyWord; 111 } 112 Definition(Punctuation punctuation,const char * start,int lineCount,Definition * parent,char mc)113 Definition(Punctuation punctuation, const char* start, int lineCount, Definition* parent, char mc) 114 : Definition(start, nullptr, lineCount, parent, mc) { 115 fPunctuation = punctuation; 116 fType = Type::kPunctuation; 117 } 118 ~Definition()119 virtual ~Definition() {} 120 asRoot()121 virtual RootDefinition* asRoot() { SkASSERT(0); return nullptr; } 122 bool boilerplateIfDef(); 123 boilerplateEndIf()124 bool boilerplateEndIf() { 125 return true; 126 } 127 128 bool checkMethod() const; 129 bool crossCheck2(const Definition& includeToken) const; 130 bool crossCheck(const Definition& includeToken) const; 131 bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const; 132 csParent()133 Definition* csParent() { 134 Definition* test = fParent; 135 while (test) { 136 if (MarkType::kStruct == test->fMarkType || MarkType::kClass == test->fMarkType) { 137 return test; 138 } 139 test = test->fParent; 140 } 141 return nullptr; 142 } 143 144 string fiddleName() const; 145 string fileName() const; 146 const Definition* findClone(string match) const; 147 string formatFunction(Format format) const; 148 const Definition* hasChild(MarkType markType) const; 149 bool hasMatch(string name) const; 150 Definition* hasParam(string ref); isClone()151 bool isClone() const { return fClone; } 152 iRootParent()153 const Definition* iRootParent() const { 154 const Definition* test = fParent; 155 while (test) { 156 if (KeyWord::kClass == test->fKeyWord || KeyWord::kStruct == test->fKeyWord) { 157 return test; 158 } 159 test = test->fParent; 160 } 161 return nullptr; 162 } 163 isRoot()164 virtual bool isRoot() const { return false; } 165 bool isStructOrClass() const; 166 length()167 int length() const { 168 return (int) (fContentEnd - fContentStart); 169 } 170 171 const char* methodEnd() const; 172 bool methodHasReturn(string name, TextParser* methodParser) const; 173 string methodName() const; 174 bool nextMethodParam(TextParser* methodParser, const char** nextEndPtr, 175 string* paramName) const; 176 static string NormalizedName(string name); 177 bool paramsMatch(string fullRef, string name) const; 178 bool parseOperator(size_t doubleColons, string& result); 179 printableName()180 string printableName() const { 181 string result(fName); 182 std::replace(result.begin(), result.end(), '_', ' '); 183 return result; 184 } 185 reportError(const char * errorStr)186 template <typename T> T reportError(const char* errorStr) const { 187 TextParser tp(this); 188 tp.reportError(errorStr); 189 return T(); 190 } 191 rootParent()192 virtual RootDefinition* rootParent() { SkASSERT(0); return nullptr; } rootParent()193 virtual const RootDefinition* rootParent() const { SkASSERT(0); return nullptr; } 194 void setCanonicalFiddle(); 195 setParentIndex()196 void setParentIndex() { 197 fParentIndex = fParent ? (int) fParent->fTokens.size() : -1; 198 } 199 200 static bool SkipImplementationWords(TextParser& inc); 201 simpleName()202 string simpleName() { 203 size_t doubleColon = fName.rfind("::"); 204 return string::npos == doubleColon ? fName : fName.substr(doubleColon + 2); 205 } 206 subtopicParent()207 const Definition* subtopicParent() const { 208 Definition* test = fParent; 209 while (test) { 210 if (MarkType::kTopic == test->fMarkType || MarkType::kSubtopic == test->fMarkType) { 211 return test; 212 } 213 test = test->fParent; 214 } 215 return nullptr; 216 } 217 topicParent()218 const Definition* topicParent() const { 219 Definition* test = fParent; 220 while (test) { 221 if (MarkType::kTopic == test->fMarkType) { 222 return test; 223 } 224 test = test->fParent; 225 } 226 return nullptr; 227 } 228 229 void trimEnd(); 230 231 string fText; // if text is constructed instead of in a file, it's put here 232 const char* fStart = nullptr; // .. in original text file, or the start of fText 233 const char* fContentStart; // start past optional markup name 234 string fName; 235 string fFiddle; // if its a constructor or operator, fiddle name goes here 236 string fCode; // suitable for autogeneration of #Code blocks in bmh 237 const char* fContentEnd = nullptr; // the end of the contained text 238 const char* fTerminator = nullptr; // the end of the markup, normally ##\n or \n 239 Definition* fParent = nullptr; 240 list<Definition> fTokens; 241 vector<Definition*> fChildren; 242 string fHash; // generated by fiddle 243 string fFileName; 244 mutable string fWrapper; // used by Example to wrap into proper function 245 size_t fLineCount = 0; 246 int fParentIndex = 0; 247 MarkType fMarkType = MarkType::kNone; 248 KeyWord fKeyWord = KeyWord::kNone; 249 Bracket fBracket = Bracket::kNone; 250 Punctuation fPunctuation = Punctuation::kNone; 251 MethodType fMethodType = MethodType::kNone; 252 Operator fOperator = Operator::kUnknown; 253 Type fType = Type::kNone; 254 char fMC = '#'; 255 bool fClone = false; 256 bool fCloned = false; 257 bool fOperatorConst = false; 258 bool fPrivate = false; 259 Details fDetails = Details::kNone; 260 bool fMemberStart = false; 261 bool fAnonymous = false; 262 bool fUndocumented = false; // include symbol comment has deprecated, private, experimental 263 mutable bool fVisited = false; 264 }; 265 266 class RootDefinition : public Definition { 267 public: 268 enum class AllowParens { 269 kNo, 270 kYes, 271 }; 272 273 struct SubtopicContents { SubtopicContentsSubtopicContents274 SubtopicContents() 275 : fShowClones(false) { 276 } 277 278 vector<Definition*> fMembers; 279 bool fShowClones; 280 }; 281 RootDefinition()282 RootDefinition() { 283 } 284 RootDefinition(MarkType markType,const char * start,int line,Definition * parent,char mc)285 RootDefinition(MarkType markType, const char* start, int line, Definition* parent, char mc) 286 : Definition(markType, start, line, parent, mc) { 287 if (MarkType::kSubtopic != markType && MarkType::kTopic != markType) { 288 if (parent) { 289 fNames.fName = parent->fName; 290 fNames.fParent = &parent->asRoot()->fNames; 291 } 292 } 293 } 294 RootDefinition(MarkType markType,const char * start,const char * end,int line,Definition * parent,char mc)295 RootDefinition(MarkType markType, const char* start, const char* end, int line, 296 Definition* parent, char mc) : Definition(markType, start, end, line, parent, mc) { 297 } 298 ~RootDefinition()299 ~RootDefinition() override { 300 for (auto& iter : fBranches) { 301 delete iter.second; 302 } 303 } 304 asRoot()305 RootDefinition* asRoot() override { return this; } 306 void clearVisited(); 307 bool dumpUnVisited(); 308 Definition* find(string ref, AllowParens ); isRoot()309 bool isRoot() const override { return true; } 310 populator(const char * key)311 SubtopicContents& populator(const char* key) { 312 return fPopulators[key]; 313 } 314 rootParent()315 RootDefinition* rootParent() override { return fRootParent; } rootParent()316 const RootDefinition* rootParent() const override { return fRootParent; } setRootParent(RootDefinition * rootParent)317 void setRootParent(RootDefinition* rootParent) { fRootParent = rootParent; } 318 319 unordered_map<string, RootDefinition*> fBranches; 320 unordered_map<string, Definition> fLeaves; 321 unordered_map<string, SubtopicContents> fPopulators; 322 NameMap fNames; 323 private: 324 RootDefinition* fRootParent = nullptr; 325 }; 326 327 #endif 328