1 /*
2     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
3     SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com>
4 
5     SPDX-License-Identifier: MIT
6 */
7 
8 #ifndef KSYNTAXHIGHLIGHTING_RULE_P_H
9 #define KSYNTAXHIGHLIGHTING_RULE_P_H
10 
11 #include "contextswitch_p.h"
12 #include "definitionref_p.h"
13 #include "foldingregion.h"
14 #include "format.h"
15 #include "highlightingdata_p.hpp"
16 #include "keywordlist_p.h"
17 #include "matchresult_p.h"
18 #include "worddelimiters_p.h"
19 
20 #include <QRegularExpression>
21 #include <QString>
22 
23 #include <memory>
24 
25 namespace KSyntaxHighlighting
26 {
27 class WordDelimiters;
28 class DefinitionData;
29 class IncludeRules;
30 
31 class Rule
32 {
33 public:
34     Rule() = default;
35     virtual ~Rule();
36 
37     typedef std::shared_ptr<Rule> Ptr;
38 
attributeFormat()39     const Format &attributeFormat() const
40     {
41         return m_attributeFormat;
42     }
43 
context()44     const ContextSwitch &context() const
45     {
46         return m_context;
47     }
48 
isLookAhead()49     bool isLookAhead() const
50     {
51         return m_lookAhead;
52     }
53 
isDynamic()54     bool isDynamic() const
55     {
56         return m_dynamic;
57     }
58 
firstNonSpace()59     bool firstNonSpace() const
60     {
61         return m_firstNonSpace;
62     }
63 
requiredColumn()64     int requiredColumn() const
65     {
66         return m_column;
67     }
68 
beginRegion()69     const FoldingRegion &beginRegion() const
70     {
71         return m_beginRegion;
72     }
73 
endRegion()74     const FoldingRegion &endRegion() const
75     {
76         return m_endRegion;
77     }
78 
79     const IncludeRules *castToIncludeRules() const;
80 
isLineContinue()81     bool isLineContinue() const
82     {
83         return m_type == Type::LineContinue;
84     }
85 
resolvePostProcessing()86     virtual void resolvePostProcessing()
87     {
88     }
89 
90     virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
91 
92     static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName);
93 
94 private:
95     Q_DISABLE_COPY(Rule)
96 
97     bool resolveCommon(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName);
98 
99     enum class Type : quint8 {
100         OtherRule,
101         LineContinue,
102         IncludeRules,
103     };
104 
105     Format m_attributeFormat;
106     ContextSwitch m_context;
107     int m_column = -1;
108     FoldingRegion m_beginRegion;
109     FoldingRegion m_endRegion;
110     Type m_type;
111     bool m_firstNonSpace = false;
112     bool m_lookAhead = false;
113 
114 protected:
115     bool m_dynamic = false;
116 };
117 
118 class AnyChar final : public Rule
119 {
120 public:
121     AnyChar(const HighlightingContextData::Rule::AnyChar &data);
122 
123 protected:
124     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
125 
126 private:
127     QString m_chars;
128 };
129 
130 class DetectChar final : public Rule
131 {
132 public:
133     DetectChar(const HighlightingContextData::Rule::DetectChar &data);
134 
135 protected:
136     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
137 
138 private:
139     QChar m_char;
140     int m_captureIndex = 0;
141 };
142 
143 class Detect2Chars final : public Rule
144 {
145 public:
146     Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &data);
147 
148 protected:
149     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
150 
151 private:
152     QChar m_char1;
153     QChar m_char2;
154 };
155 
156 class DetectIdentifier final : public Rule
157 {
158 protected:
159     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
160 };
161 
162 class DetectSpaces final : public Rule
163 {
164 protected:
165     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
166 };
167 
168 class Float final : public Rule
169 {
170 public:
171     Float(DefinitionData &def, const HighlightingContextData::Rule::Float &data);
172 
173 protected:
174     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
175 
176 private:
177     WordDelimiters m_wordDelimiters;
178 };
179 
180 class IncludeRules final : public Rule
181 {
182 public:
183     IncludeRules(const HighlightingContextData::Rule::IncludeRules &data);
184 
contextName()185     const QString &contextName() const
186     {
187         return m_contextName;
188     }
189 
includeAttribute()190     bool includeAttribute() const
191     {
192         return m_includeAttribute;
193     }
194 
195 protected:
196     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
197 
198 private:
199     QString m_contextName;
200     bool m_includeAttribute;
201 };
202 
203 class Int final : public Rule
204 {
205 public:
206     Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data);
207 
208 protected:
209     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
210 
211 private:
212     WordDelimiters m_wordDelimiters;
213 };
214 
215 class HlCChar final : public Rule
216 {
217 protected:
218     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
219 };
220 
221 class HlCHex final : public Rule
222 {
223 public:
224     HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex &data);
225 
226 protected:
227     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
228 
229 private:
230     WordDelimiters m_wordDelimiters;
231 };
232 
233 class HlCOct final : public Rule
234 {
235 public:
236     HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct &data);
237 
238 protected:
239     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
240 
241 private:
242     WordDelimiters m_wordDelimiters;
243 };
244 
245 class HlCStringChar final : public Rule
246 {
247 protected:
248     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
249 };
250 
251 class KeywordListRule final : public Rule
252 {
253 public:
254     KeywordListRule(const KeywordList &keywordList, DefinitionData &def, const HighlightingContextData::Rule::Keyword &data);
255 
256     static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule::Keyword &data, QStringView lookupContextName);
257 
258 protected:
259     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
260 
261 private:
262     WordDelimiters m_wordDelimiters;
263     const KeywordList &m_keywordList;
264     Qt::CaseSensitivity m_caseSensitivity;
265 };
266 
267 class LineContinue final : public Rule
268 {
269 public:
270     LineContinue(const HighlightingContextData::Rule::LineContinue &data);
271 
272 protected:
273     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
274 
275 private:
276     QChar m_char;
277 };
278 
279 class RangeDetect final : public Rule
280 {
281 public:
282     RangeDetect(const HighlightingContextData::Rule::RangeDetect &data);
283 
284 protected:
285     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
286 
287 private:
288     QChar m_begin;
289     QChar m_end;
290 };
291 
292 class RegExpr final : public Rule
293 {
294 public:
295     RegExpr(const HighlightingContextData::Rule::RegExpr &data);
296 
297 protected:
298     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
299     void resolvePostProcessing() override;
300 
301 private:
302     QRegularExpression m_regexp;
303     bool m_isResolved = false;
304 };
305 
306 class StringDetect final : public Rule
307 {
308 public:
309     StringDetect(const HighlightingContextData::Rule::StringDetect &data);
310 
311 protected:
312     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
313 
314 private:
315     QString m_string;
316     Qt::CaseSensitivity m_caseSensitivity;
317 };
318 
319 class WordDetect final : public Rule
320 {
321 public:
322     WordDetect(DefinitionData &def, const HighlightingContextData::Rule::WordDetect &data);
323 
324 protected:
325     MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
326 
327 private:
328     WordDelimiters m_wordDelimiters;
329     QString m_word;
330     Qt::CaseSensitivity m_caseSensitivity;
331 };
332 
333 }
334 
335 #endif // KSYNTAXHIGHLIGHTING_RULE_P_H
336