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
25namespace KSyntaxHighlighting
26{
27class WordDelimiters;
28class DefinitionData;
29class IncludeRules;
30
31class Rule
32{
33public:
34 Rule() = default;
35 virtual ~Rule();
36
37 typedef std::shared_ptr<Rule> Ptr;
38
39 const Format &attributeFormat() const
40 {
41 return m_attributeFormat;
42 }
43
44 const ContextSwitch &context() const
45 {
46 return m_context;
47 }
48
49 bool isLookAhead() const
50 {
51 return m_lookAhead;
52 }
53
54 bool isDynamic() const
55 {
56 return m_dynamic;
57 }
58
59 bool firstNonSpace() const
60 {
61 return m_firstNonSpace;
62 }
63
64 int requiredColumn() const
65 {
66 return m_column;
67 }
68
69 const FoldingRegion &beginRegion() const
70 {
71 return m_beginRegion;
72 }
73
74 const FoldingRegion &endRegion() const
75 {
76 return m_endRegion;
77 }
78
79 const IncludeRules *castToIncludeRules() const;
80
81 bool isLineContinue() const
82 {
83 return m_type == Type::LineContinue;
84 }
85
86 // If true, then the rule uses the skipOffset parameter of MatchResult.
87 // This is used by AbstractHighlighter::highlightLine() to look for a rule
88 // in the skipOffsets cache only if it can be found there.
89 bool hasSkipOffset() const
90 {
91 return m_hasSkipOffset;
92 }
93
94 virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures) const = 0;
95
96 static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName);
97
98private:
99 Q_DISABLE_COPY(Rule)
100
101 bool resolveCommon(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName);
102
103 enum class Type : quint8 {
104 OtherRule,
105 LineContinue,
106 IncludeRules,
107 };
108
109private:
110 Format m_attributeFormat;
111 ContextSwitch m_context;
112 int m_column = -1;
113 FoldingRegion m_beginRegion;
114 FoldingRegion m_endRegion;
115 Type m_type;
116 bool m_firstNonSpace = false;
117 bool m_lookAhead = false;
118
119protected:
120 bool m_hasSkipOffset = false;
121 bool m_dynamic = false;
122};
123
124class AnyChar final : public Rule
125{
126public:
127 AnyChar(const HighlightingContextData::Rule::AnyChar &data);
128
129protected:
130 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
131
132private:
133 WordDelimiters m_chars;
134};
135
136class DetectChar final : public Rule
137{
138public:
139 DetectChar(const HighlightingContextData::Rule::DetectChar &data);
140
141protected:
142 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
143
144private:
145 QChar m_char;
146 int m_captureIndex = 0;
147};
148
149class Detect2Chars final : public Rule
150{
151public:
152 Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &data);
153
154protected:
155 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
156
157private:
158 QChar m_char1;
159 QChar m_char2;
160};
161
162class DetectIdentifier final : public Rule
163{
164protected:
165 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
166};
167
168class DetectSpaces final : public Rule
169{
170protected:
171 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
172};
173
174class Float final : public Rule
175{
176public:
177 Float(DefinitionData &def, const HighlightingContextData::Rule::Float &data);
178
179protected:
180 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
181
182private:
183 WordDelimiters m_wordDelimiters;
184};
185
186class IncludeRules final : public Rule
187{
188public:
189 IncludeRules(const HighlightingContextData::Rule::IncludeRules &data);
190
191 const QString &contextName() const
192 {
193 return m_contextName;
194 }
195
196 bool includeAttribute() const
197 {
198 return m_includeAttribute;
199 }
200
201protected:
202 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
203
204private:
205 QString m_contextName;
206 bool m_includeAttribute;
207};
208
209class Int final : public Rule
210{
211public:
212 Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data);
213
214protected:
215 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
216
217private:
218 WordDelimiters m_wordDelimiters;
219};
220
221class HlCChar final : public Rule
222{
223protected:
224 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
225};
226
227class HlCHex final : public Rule
228{
229public:
230 HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex &data);
231
232protected:
233 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
234
235private:
236 WordDelimiters m_wordDelimiters;
237};
238
239class HlCOct final : public Rule
240{
241public:
242 HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct &data);
243
244protected:
245 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
246
247private:
248 WordDelimiters m_wordDelimiters;
249};
250
251class HlCStringChar final : public Rule
252{
253protected:
254 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
255};
256
257class KeywordListRule final : public Rule
258{
259public:
260 KeywordListRule(const KeywordList &keywordList, DefinitionData &def, const HighlightingContextData::Rule::Keyword &data);
261
262 static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule::Keyword &data, QStringView lookupContextName);
263
264protected:
265 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
266
267private:
268 WordDelimiters m_wordDelimiters;
269 const KeywordList &m_keywordList;
270 Qt::CaseSensitivity m_caseSensitivity;
271};
272
273class LineContinue final : public Rule
274{
275public:
276 LineContinue(const HighlightingContextData::Rule::LineContinue &data);
277
278protected:
279 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
280
281private:
282 QChar m_char;
283};
284
285class RangeDetect final : public Rule
286{
287public:
288 RangeDetect(const HighlightingContextData::Rule::RangeDetect &data);
289
290protected:
291 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
292
293private:
294 QChar m_begin;
295 QChar m_end;
296};
297
298class RegExpr final : public Rule
299{
300public:
301 RegExpr(const HighlightingContextData::Rule::RegExpr &data);
302
303protected:
304 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
305
306private:
307 void resolve();
308 QRegularExpression m_regexp;
309 bool m_isResolved = false;
310};
311
312class DynamicRegExpr final : public Rule
313{
314public:
315 DynamicRegExpr(const HighlightingContextData::Rule::RegExpr &data);
316
317protected:
318 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
319
320private:
321 void resolve();
322 QString m_pattern;
323 QRegularExpression::PatternOptions m_patternOptions;
324 bool m_isResolved = false;
325};
326
327class StringDetect final : public Rule
328{
329public:
330 StringDetect(const HighlightingContextData::Rule::StringDetect &data);
331
332protected:
333 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
334
335private:
336 QString m_string;
337 Qt::CaseSensitivity m_caseSensitivity;
338};
339
340class DynamicStringDetect final : public Rule
341{
342public:
343 DynamicStringDetect(const HighlightingContextData::Rule::StringDetect &data);
344
345protected:
346 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
347
348private:
349 QString m_string;
350 Qt::CaseSensitivity m_caseSensitivity;
351};
352
353class WordDetect final : public Rule
354{
355public:
356 WordDetect(DefinitionData &def, const HighlightingContextData::Rule::WordDetect &data);
357
358protected:
359 MatchResult doMatch(QStringView text, int offset, const QStringList &) const override;
360
361private:
362 WordDelimiters m_wordDelimiters;
363 QString m_word;
364 Qt::CaseSensitivity m_caseSensitivity;
365};
366
367}
368
369#endif // KSYNTAXHIGHLIGHTING_RULE_P_H
370

source code of syntax-highlighting/src/lib/rule_p.h