1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  */
5 
6 #ifndef TOKEN_H
7 #define TOKEN_H
8 
9 #include <wx/arrstr.h>
10 #include <wx/string.h>
11 
12 #include <set>
13 #include <map>
14 
15 class Token;
16 class TokenTree;
17 
18 typedef std::set< int,    std::less<int>    > TokenIdxSet;
19 typedef std::set< size_t, std::less<size_t> > TokenFileSet;
20 
21 enum TokenScope
22 {
23     tsUndefined = 0,
24     tsPrivate,
25     tsProtected,
26     tsPublic
27 };
28 
29 enum TokenKind
30 {
31     // changed in order to reflect the priority
32 
33     /** namespace*/
34     tkNamespace        = 0x0001,
35 
36     /** class or struct */
37     tkClass            = 0x0002,
38 
39     /** enum */
40     tkEnum             = 0x0004,
41 
42     /** typedef, note typedefs are stored as classes inheriting from the typedef'd type, this takes
43      *  advantage of existing inheritance code
44      */
45     tkTypedef          = 0x0008,
46 
47     /** constructor class member function */
48     tkConstructor      = 0x0010,
49 
50     /** destructor class member function */
51     tkDestructor       = 0x0020,
52 
53     /** general function, not constructor nor destructor */
54     tkFunction         = 0x0040,
55 
56     /** variable */
57     tkVariable         = 0x0080,
58 
59     /** enumerator */
60     tkEnumerator       = 0x0100,
61 
62     /** macro definition, such as: #define AAA(x,y) f(x,y), where AAA is a token of tkMacroDef */
63     tkMacroDef         = 0x0200,
64 
65     /** the usage of the macro, for example: AAA(1,2) */
66     tkMacroUse         = 0x0400,
67 
68     // convenient masks
69     /** container like tokens, those tokens can have children tokens */
70     tkAnyContainer     = tkClass    | tkNamespace   | tkTypedef,
71 
72     /** any kind of functions */
73     tkAnyFunction      = tkFunction | tkConstructor | tkDestructor,
74 
75     /** undefined or just "all" */
76     tkUndefined        = 0xFFFF
77 };
78 /** a symbol found in the parsed files, it can be many kinds, such as a variable, a class and so on.
79  *  Once constructed, the Token should be always put in the TokenTree, and we can access the Token
80  *  by TokenIndex.
81  */
82 class Token
83 {
84 friend class TokenTree;
85 public:
86 
87     /** constructor
88      *  @param name token's name, this can be a search key in the tokentree
89      *  @param file the index of the source file where the token locates
90      *  @param ticket an integer number, once a new Token is allocated, this value will increase by
91      *  one, it is mainly used for duplicated Token checking when class browser tree get refreshed.
92      */
93     Token(const wxString& name, unsigned int file, unsigned int line, size_t ticket);
94 
95     /** destructor */
96     ~Token();
97 
98     /** add a child token
99      * @param childIdx int
100      * @return return true if success, in the case the childIdx < 0, this function will return false
101      */
102     bool AddChild(int childIdx);
103 
104     /** delete all the child tokens of the current token, not only remove the relation, but also
105      *  delete the Token instance.
106      * @return false if the TokenTree is invalid
107      */
108     bool DeleteAllChildren();
109 
110     /** check if the token has any child tokens.
111      * @return true if it does have some child.
112      */
HasChildren()113     bool HasChildren() const { return !m_Children.empty(); }
114 
115     /** @brief get a literal string presentation of the namespace.
116      *
117      * @return wxString
118      * if the token has the parent token, like a member variable class AAA {int m_BBB;}, then
119      * the string is "AAA::"
120      */
121     wxString GetNamespace() const;
122 
123     /** @brief check to see the current token is inherited from a specified token
124      *
125      * @param idx the specified token
126      * @return true if success
127      * loop the m_DirectAncestors to see it did contains the specified token, also we may check
128      * the specified token is an ancestor of the current ancestor, so recursive call is involved
129      */
130     bool InheritsFrom(int idx) const;
131 
132     /** a short simple string to show the token information, this usually generate for show
133      * the tip message when the user hover a mouse over the text in C::B editor.
134      */
135     wxString DisplayName() const;
136 
137     /** the token kind string, e.g. for a tkClass kind Token, we get a "class" string */
138     wxString GetTokenKindString() const;
139 
140     /** the access kind string, e.g. for a tsPrivate type Token, we get a "private" string */
141     wxString GetTokenScopeString() const;
142 
143     /** get a full path of the file which contains the current Token */
144     wxString GetFilename() const;
145 
146     /** get a full path of the file which contains the function implementation. Note usually only
147      *  function like token has this feature.
148      */
149     wxString GetImplFilename() const;
150 
151     /** remove all '\n' in the original function argument string */
152     wxString GetFormattedArgs() const;
153 
154     /** remove all default value of the function argument string, e.g. if we have such argument
155      *  "(int a = 10, float b = 3.14)"
156      *  then we get "(int a, float b)"
157      */
158     wxString GetStrippedArgs() const;
159 
160     /** get the ticket value of the current token */
GetTicket()161     size_t GetTicket() const { return m_Ticket; }
162 
163     /** see whether the current token belong to any files in the file set, both m_FileIdx and
164      * m_ImplFileIdx is considered
165      * @param files a file(index) set
166      * @return true if success
167      */
168     bool MatchesFiles(const TokenFileSet& files);
169 
170     /** get the TokenTree associated with the current Token
171      * @return TokenTree pointer
172      */
GetTree()173     TokenTree* GetTree() const { return m_TokenTree; }
174 
175     /** build in types are not valid ancestors for a type define token
176      * @param ancestor testing type string
177      * @return false if the testing type string is a build in type
178      */
179     bool IsValidAncestor(const wxString& ancestor);
180 
181     /** this is the full return value (if any): e.g. const wxString& */
182     wxString                     m_FullType;
183 
184     /** this is what the parser believes is the actual return value: e.g. wxString */
185     wxString                     m_BaseType;
186 
187     /** Token's name, it can be searched in the TokenTree */
188     wxString                     m_Name;
189 
190     /** If it is a function Token, then this value is function arguments,
191      *  e.g.   (int arg1 = 10, float arg2 = 9.0)
192      *  If it is an enumerator, then this is the assigned (inferred) value
193      */
194     wxString                     m_Args;
195 
196     /** stripped arguments e.g. (int arg1, float arg2) */
197     wxString                     m_BaseArgs;
198 
199     /** all ancestors comma-separated list, e.g. if a class declaration like below
200      *  class AAA :public BBB, public CCC
201      *  then the m_AncestorsString is "BBB,CCC", note that once m_Ancestors is constructed, this
202      *  variable will be cleared.
203      */
204     wxString                     m_AncestorsString;
205 
206     /** File index in TokenTree */
207     unsigned int                 m_FileIdx;
208 
209     /** Line index where the token was met, which is 1 based */
210     unsigned int                 m_Line;
211 
212     /** doxygen style comments */
213     wxString                     m_Doc;
214 
215     /** function implementation file index */
216     unsigned int                 m_ImplFileIdx;
217 
218     /** function implementation line index */
219     unsigned int                 m_ImplLine;
220 
221     /** if token is impl, opening brace line */
222     unsigned int                 m_ImplLineStart;
223 
224     /** if token is impl, closing brace line */
225     unsigned int                 m_ImplLineEnd;
226 
227     /** doxygen style comments in the Impl file */
228     wxString                     m_ImplDoc;
229 
230     /** public? private? protected? */
231     TokenScope                   m_Scope;
232 
233     /** See TokenKind class */
234     TokenKind                    m_TokenKind;
235 
236     /** is operator overload function? */
237     bool                         m_IsOperator;
238 
239     /** if true, means the token belong to a C::B project, it exists in the project's source/header
240      *  files, not from the system's headers or other include header files
241      */
242     bool                         m_IsLocal;
243 
244     /** local (automatic) variable */
245     bool                         m_IsTemp;
246 
247     /** the member method is const (yes/no) */
248     bool                         m_IsConst;
249 
250     /** the member method is noexcept (yes/no) */
251     bool                         m_IsNoExcept;
252 
253     /** Is anonymous token? (e.g. unnamed struct or union) */
254     bool                         m_IsAnonymous;
255 
256     /** current Token index in the tree, it is index of the std::vector<Token*>, so use the index,
257      *  we can first get a address of the Token, and after a dereference, we can get the Token
258      *  instance. Note that the tree is a dynamic object, which means Tokens can be added or removed
259      *  from the tree, so the slot of std::vector<Token*> is reused. So, same index does not point
260      *  to the same Token if TokenTree are updated or changed.
261      */
262     int                          m_Index;
263 
264     /** Parent Token index */
265     int                          m_ParentIndex;
266 
267     /** if it is a class kind token, then it contains all the member tokens */
268     TokenIdxSet                  m_Children;
269 
270     /** all the ancestors in the inheritance hierarchy */
271     TokenIdxSet                  m_Ancestors;
272 
273     /** the nearest ancestors */
274     TokenIdxSet                  m_DirectAncestors;
275 
276     /** all the descendants in the inheritance hierarchy */
277     TokenIdxSet                  m_Descendants;
278 
279     /** used for namespace aliases */
280     wxArrayString                m_Aliases;
281 
282     /** template argument list, comma separated list string */
283     wxString                     m_TemplateArgument;
284 
285     /** for a class template, this is the formal template argument list, but for a variable Token,
286      *  this is the actual template arguments.
287      */
288     wxArrayString                m_TemplateType;
289 
290     /** a string to string map from formal template argument to actual template argument */
291     std::map<wxString, wxString> m_TemplateMap;
292 
293     /** alias for templates, e.g. template T1 T2; */
294     wxString                     m_TemplateAlias;
295 
296     /** custom user-data (the classbrowser expects it to be a pointer to a cbProject), this field
297      *  is used when user can only show the tokens belong to the current C::B project in the
298      *  browser tree. m_UserData is updated in the worker threaded task: MarkFileAsLocalThreadedTask
299      */
300     void*                        m_UserData;
301 
302 protected:
303 
304     /** a pointer to TokenTree */
305     TokenTree*                   m_TokenTree;
306 
307     /** This is used in class browser to avoid duplication nodes in the class browser tree. Once a
308      *  Token is allocated from the heap, a new ticket number is assigned to the Token, so a new
309      *  node is only added to the class browser tree if a Token with new ticket is detected.
310      */
311     size_t                       m_Ticket;
312 };
313 
314 #endif // TOKEN_H
315