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

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