• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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