1 | /* |
2 | * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) |
3 | * |
4 | * This program is free software: you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation, either version 3 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | */ |
17 | #ifndef PARSER_UTILS_H |
18 | #define PARSER_UTILS_H |
19 | #include <QMap> |
20 | #include <QObject> |
21 | #include <QSet> |
22 | #include <QVector> |
23 | #include <memory> |
24 | |
25 | enum class ParserLanguage { |
26 | C, |
27 | CPlusPlus |
28 | }; |
29 | |
30 | struct CodeSnippet { |
31 | QString caption; //Name |
32 | QString prefix; //Prefix used in code suggestion |
33 | QString code; //Code body |
34 | QString desc; //Description |
35 | int section; //Section in the menu |
36 | }; |
37 | |
38 | using PCodeSnippet = std::shared_ptr<CodeSnippet>; |
39 | |
40 | // preprocess/ macro define |
41 | struct Define { |
42 | QString name; |
43 | QString args; |
44 | QString value; |
45 | QString filename; |
46 | bool hardCoded;// if true, don't free memory (points to hard defines) |
47 | QStringList argList; // args list to format values |
48 | QList<bool> argUsed; |
49 | QString formatValue; // format template to format values |
50 | }; |
51 | |
52 | using PDefine = std::shared_ptr<Define>; |
53 | |
54 | using DefineMap = QHash<QString,PDefine>; |
55 | using PDefineMap = std::shared_ptr<DefineMap>; |
56 | |
57 | enum class SkipType { |
58 | skItself, // skip itself |
59 | skToSemicolon, // skip to ; |
60 | skToColon, // skip to : |
61 | skToRightParenthesis, // skip to ) |
62 | skToLeftBrace,// Skip to { |
63 | skToRightBrace, // skip to } |
64 | skNone // It's a keyword but don't process here |
65 | }; |
66 | |
67 | |
68 | enum StatementKind { |
69 | skUnknown, |
70 | skPreprocessor, |
71 | skEnumType, |
72 | skEnumClassType, |
73 | skEnum, |
74 | skTypedef, |
75 | skClass, |
76 | skFunction, |
77 | skOperator, |
78 | skConstructor, |
79 | skDestructor, |
80 | skVariable, |
81 | skParameter, |
82 | skNamespace, |
83 | skNamespaceAlias, |
84 | skBlock, |
85 | skUserCodeSnippet, // user code template |
86 | skKeyword, // keywords |
87 | skGlobalVariable, |
88 | skLocalVariable, |
89 | skAlias |
90 | }; |
91 | |
92 | using StatementKindSet = QSet<StatementKind>; |
93 | |
94 | enum class StatementScope { |
95 | ssGlobal, |
96 | ssLocal, |
97 | ssClassLocal |
98 | }; |
99 | |
100 | enum class StatementClassScope { |
101 | scsNone, |
102 | scsPrivate, |
103 | scsProtected, |
104 | scsPublic |
105 | }; |
106 | |
107 | enum class MemberOperatorType { |
108 | otArrow, |
109 | otDot, |
110 | otDColon, |
111 | otOther |
112 | }; |
113 | |
114 | struct RemovedStatement{ |
115 | QString type; // type "int" |
116 | QString command; // identifier/name of statement "foo" |
117 | int definitionLine; // definition |
118 | QString definitionFileName; // definition |
119 | QString fullName; // fullname(including class and namespace) |
120 | QString noNameArgs; // Args without name |
121 | }; |
122 | |
123 | enum class EvalStatementKind { |
124 | Namespace, |
125 | Type, |
126 | Variable, |
127 | Literal, |
128 | Function |
129 | }; |
130 | |
131 | using PRemovedStatement = std::shared_ptr<RemovedStatement>; |
132 | |
133 | struct StatementMatchPosition{ |
134 | int start; |
135 | int end; |
136 | }; |
137 | |
138 | using PStatementMathPosition = std::shared_ptr<StatementMatchPosition>; |
139 | |
140 | struct Statement; |
141 | using PStatement = std::shared_ptr<Statement>; |
142 | using StatementList = QList<PStatement>; |
143 | using PStatementList = std::shared_ptr<StatementList>; |
144 | using StatementMap = QMultiMap<QString, PStatement>; |
145 | struct Statement { |
146 | std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference |
147 | QString type; // type "int" |
148 | QString command; // identifier/name of statement "foo" |
149 | QString args; // args "(int a,float b)" |
150 | QString value; // Used for macro defines/typedef, "100" in "#defin COUNT 100" |
151 | StatementKind kind; // kind of statement class/variable/function/etc |
152 | QList<std::weak_ptr<Statement>> inheritanceList; // list of statements this one inherits from, can be nil |
153 | StatementScope scope; // global/local/classlocal |
154 | StatementClassScope classScope; // protected/private/public |
155 | bool hasDefinition; // definiton line/filename is valid |
156 | int line; // declaration |
157 | int definitionLine; // definition |
158 | QString fileName; // declaration |
159 | QString definitionFileName; // definition |
160 | bool inProject; // statement in project |
161 | bool ; // statement in system header (#include <>) |
162 | StatementMap children; // functions can be overloaded,so we use list to save children with the same name |
163 | QSet<QString> friends; // friend class / functions |
164 | bool isStatic; // static function / variable |
165 | bool isInherited; // inherted member; |
166 | QString fullName; // fullname(including class and namespace), ClassA::foo |
167 | QSet<QString> usingList; // using namespaces |
168 | QString noNameArgs;// Args without name |
169 | |
170 | // fields for code completion |
171 | int usageCount; //Usage Count |
172 | int matchPosTotal; // total of matched positions |
173 | int matchPosSpan; // distance between the first match pos and the last match pos; |
174 | int firstMatchLength; // length of first match; |
175 | int caseMatched; // if match with case |
176 | QList<PStatementMathPosition> matchPositions; |
177 | }; |
178 | |
179 | struct EvalStatement; |
180 | using PEvalStatement = std::shared_ptr<EvalStatement>; |
181 | /** |
182 | * @brief Statement for evaluation result |
183 | * Ex. (Test*)(y+1) |
184 | * it's baseStatement is the statement for y |
185 | * it's effetiveTypeStatement is Test |
186 | */ |
187 | struct EvalStatement { |
188 | QString baseType; // type "int" |
189 | EvalStatementKind kind; // namespace / type / variable / function / literal |
190 | int pointerLevel; // 0 for "int", 1 for "int *", 2 for "int **"... |
191 | PStatement baseStatement; // if not literal or primitive type, the base statement |
192 | PStatement effectiveTypeStatement; |
193 | public: |
194 | EvalStatement (const QString& baseType, |
195 | EvalStatementKind kind, |
196 | const PStatement& baseStatement, |
197 | const PStatement& typeStatement, |
198 | int pointerLevel = 0); |
199 | void assignType(const PEvalStatement& typeStatement); |
200 | |
201 | }; |
202 | |
203 | |
204 | struct UsingNamespace { |
205 | QStringList namespaces; // List['std','foo'] for using namespace std::foo; |
206 | QString filename; |
207 | int line; |
208 | bool ; |
209 | }; |
210 | using PUsingNamespace = std::shared_ptr<UsingNamespace>; |
211 | |
212 | struct CppScope { |
213 | int startLine; |
214 | PStatement statement; |
215 | }; |
216 | |
217 | using PCppScope = std::shared_ptr<CppScope>; |
218 | class CppScopes { |
219 | |
220 | public: |
221 | PStatement findScopeAtLine(int line); |
222 | void addScope(int line, PStatement scopeStatement); |
223 | PStatement lastScope(); |
224 | void removeLastScope(); |
225 | void clear(); |
226 | private: |
227 | QVector<PCppScope> mScopes; |
228 | }; |
229 | |
230 | struct FileIncludes { |
231 | QString baseFile; |
232 | QMap<QString, bool> includeFiles; // true means the file is directly included, false means included indirectly |
233 | QStringList directIncludes; // |
234 | QSet<QString> usings; // namespaces it usings |
235 | StatementMap statements; // but we don't save temporary statements (full name as key) |
236 | StatementMap declaredStatements; // statements declared in this file (full name as key) |
237 | CppScopes scopes; // int is start line of the statement scope |
238 | QSet<QString> dependingFiles; // The files I depeneds on |
239 | QSet<QString> dependedFiles; // the files depends on me |
240 | }; |
241 | using PFileIncludes = std::shared_ptr<FileIncludes>; |
242 | |
243 | extern QStringList CppDirectives; |
244 | extern QStringList JavadocTags; |
245 | extern QMap<QString,SkipType> CppKeywords; |
246 | extern QSet<QString> CppControlKeyWords; |
247 | extern QSet<QString> CKeywords; |
248 | extern QSet<QString> CppTypeKeywords; |
249 | extern QSet<QString> STLPointers; |
250 | extern QSet<QString> STLContainers; |
251 | extern QSet<QString> STLElementMethods; |
252 | extern QSet<QString> MemberOperators; |
253 | extern QSet<QString> IOManipulators; |
254 | |
255 | void initParser(); |
256 | |
257 | QString (const QString& relativeTo, const QString& line, |
258 | const QStringList& includePaths, const QStringList& projectIncludePaths); |
259 | |
260 | QString (const QString& relativeTo, const QString& fileName); |
261 | |
262 | QString (const QString& fileName, const QStringList& includePaths); |
263 | bool (const QString& fileName, const QSet<QString>& includePaths); |
264 | bool isHFile(const QString& filename); |
265 | bool isCFile(const QString& filename); |
266 | bool isCppFile(const QString& filename); |
267 | bool isCppKeyword(const QString& word); |
268 | bool isCppControlKeyword(const QString& word); |
269 | bool isScopeTypeKind(StatementKind kind); |
270 | MemberOperatorType getOperatorType(const QString& phrase, int index); |
271 | QStringList getOwnerExpressionAndMember( |
272 | const QStringList expression, |
273 | QString& memberOperator, |
274 | QStringList& memberExpression); |
275 | bool isMemberOperator(QString token); |
276 | StatementKind getKindOfStatement(const PStatement& statement); |
277 | |
278 | #endif // PARSER_UTILS_H |
279 | |