File indexing completed on 2024-05-12 04:02:20
0001 /* 0002 SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org> 0003 SPDX-FileCopyrightText: 2020 Jonathan Poelen <jonathan.poelen@gmail.com> 0004 0005 SPDX-License-Identifier: MIT 0006 */ 0007 0008 #ifndef KSYNTAXHIGHLIGHTING_RULE_P_H 0009 #define KSYNTAXHIGHLIGHTING_RULE_P_H 0010 0011 #include "contextswitch_p.h" 0012 #include "definitionref_p.h" 0013 #include "foldingregion.h" 0014 #include "format.h" 0015 #include "highlightingdata_p.hpp" 0016 #include "keywordlist_p.h" 0017 #include "matchresult_p.h" 0018 #include "worddelimiters_p.h" 0019 0020 #include <QRegularExpression> 0021 #include <QString> 0022 0023 #include <memory> 0024 0025 namespace KSyntaxHighlighting 0026 { 0027 class WordDelimiters; 0028 class DefinitionData; 0029 class IncludeRules; 0030 class DynamicRegexpCache; 0031 0032 class Rule 0033 { 0034 public: 0035 Rule() = default; 0036 virtual ~Rule(); 0037 0038 typedef std::shared_ptr<Rule> Ptr; 0039 0040 const Format &attributeFormat() const 0041 { 0042 return m_attributeFormat; 0043 } 0044 0045 const ContextSwitch &context() const 0046 { 0047 return m_context; 0048 } 0049 0050 bool isLookAhead() const 0051 { 0052 return m_lookAhead; 0053 } 0054 0055 bool isDynamic() const 0056 { 0057 return m_dynamic; 0058 } 0059 0060 bool firstNonSpace() const 0061 { 0062 return m_firstNonSpace; 0063 } 0064 0065 int requiredColumn() const 0066 { 0067 return m_column; 0068 } 0069 0070 const FoldingRegion &beginRegion() const 0071 { 0072 return m_beginRegion; 0073 } 0074 0075 const FoldingRegion &endRegion() const 0076 { 0077 return m_endRegion; 0078 } 0079 0080 const IncludeRules *castToIncludeRules() const; 0081 0082 bool isLineContinue() const 0083 { 0084 return m_type == Type::LineContinue; 0085 } 0086 0087 // If true, then the rule uses the skipOffset parameter of MatchResult. 0088 // This is used by AbstractHighlighter::highlightLine() to look for a rule 0089 // in the skipOffsets cache only if it can be found there. 0090 bool hasSkipOffset() const 0091 { 0092 return m_hasSkipOffset; 0093 } 0094 0095 virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &dynamicRegexpCache) const = 0; 0096 0097 static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName); 0098 0099 private: 0100 Q_DISABLE_COPY(Rule) 0101 0102 bool resolveCommon(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName); 0103 0104 enum class Type : quint8 { 0105 OtherRule, 0106 LineContinue, 0107 IncludeRules, 0108 }; 0109 0110 private: 0111 Format m_attributeFormat; 0112 ContextSwitch m_context; 0113 int m_column = -1; 0114 FoldingRegion m_beginRegion; 0115 FoldingRegion m_endRegion; 0116 Type m_type; 0117 bool m_firstNonSpace = false; 0118 bool m_lookAhead = false; 0119 0120 protected: 0121 bool m_hasSkipOffset = false; 0122 bool m_dynamic = false; 0123 }; 0124 0125 class AnyChar final : public Rule 0126 { 0127 public: 0128 AnyChar(const HighlightingContextData::Rule::AnyChar &data); 0129 0130 protected: 0131 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0132 0133 private: 0134 WordDelimiters m_chars; 0135 }; 0136 0137 class DetectChar final : public Rule 0138 { 0139 public: 0140 DetectChar(const HighlightingContextData::Rule::DetectChar &data); 0141 0142 protected: 0143 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0144 0145 private: 0146 QChar m_char; 0147 int m_captureIndex = 0; 0148 }; 0149 0150 class Detect2Chars final : public Rule 0151 { 0152 public: 0153 Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &data); 0154 0155 protected: 0156 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0157 0158 private: 0159 QChar m_char1; 0160 QChar m_char2; 0161 }; 0162 0163 class DetectIdentifier final : public Rule 0164 { 0165 protected: 0166 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0167 }; 0168 0169 class DetectSpaces final : public Rule 0170 { 0171 protected: 0172 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0173 }; 0174 0175 class Float final : public Rule 0176 { 0177 public: 0178 Float(DefinitionData &def, const HighlightingContextData::Rule::Float &data); 0179 0180 protected: 0181 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0182 0183 private: 0184 WordDelimiters m_wordDelimiters; 0185 }; 0186 0187 class IncludeRules final : public Rule 0188 { 0189 public: 0190 IncludeRules(const HighlightingContextData::Rule::IncludeRules &data); 0191 0192 const QString &contextName() const 0193 { 0194 return m_contextName; 0195 } 0196 0197 bool includeAttribute() const 0198 { 0199 return m_includeAttribute; 0200 } 0201 0202 protected: 0203 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0204 0205 private: 0206 QString m_contextName; 0207 bool m_includeAttribute; 0208 }; 0209 0210 class Int final : public Rule 0211 { 0212 public: 0213 Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data); 0214 0215 protected: 0216 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0217 0218 private: 0219 WordDelimiters m_wordDelimiters; 0220 }; 0221 0222 class HlCChar final : public Rule 0223 { 0224 protected: 0225 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0226 }; 0227 0228 class HlCHex final : public Rule 0229 { 0230 public: 0231 HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex &data); 0232 0233 protected: 0234 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0235 0236 private: 0237 WordDelimiters m_wordDelimiters; 0238 }; 0239 0240 class HlCOct final : public Rule 0241 { 0242 public: 0243 HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct &data); 0244 0245 protected: 0246 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0247 0248 private: 0249 WordDelimiters m_wordDelimiters; 0250 }; 0251 0252 class HlCStringChar final : public Rule 0253 { 0254 protected: 0255 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0256 }; 0257 0258 class KeywordListRule final : public Rule 0259 { 0260 public: 0261 KeywordListRule(const KeywordList &keywordList, DefinitionData &def, const HighlightingContextData::Rule::Keyword &data); 0262 0263 static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule::Keyword &data, QStringView lookupContextName); 0264 0265 protected: 0266 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0267 0268 private: 0269 WordDelimiters m_wordDelimiters; 0270 const KeywordList &m_keywordList; 0271 Qt::CaseSensitivity m_caseSensitivity; 0272 }; 0273 0274 class LineContinue final : public Rule 0275 { 0276 public: 0277 LineContinue(const HighlightingContextData::Rule::LineContinue &data); 0278 0279 protected: 0280 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0281 0282 private: 0283 QChar m_char; 0284 }; 0285 0286 class RangeDetect final : public Rule 0287 { 0288 public: 0289 RangeDetect(const HighlightingContextData::Rule::RangeDetect &data); 0290 0291 protected: 0292 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0293 0294 private: 0295 QChar m_begin; 0296 QChar m_end; 0297 }; 0298 0299 class RegExpr final : public Rule 0300 { 0301 public: 0302 RegExpr(const HighlightingContextData::Rule::RegExpr &data); 0303 0304 protected: 0305 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0306 0307 private: 0308 void resolve(); 0309 QRegularExpression m_regexp; 0310 bool m_isResolved = false; 0311 }; 0312 0313 class DynamicRegExpr final : public Rule 0314 { 0315 public: 0316 DynamicRegExpr(const HighlightingContextData::Rule::RegExpr &data); 0317 0318 protected: 0319 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0320 0321 private: 0322 void resolve(); 0323 QString m_pattern; 0324 QRegularExpression::PatternOptions m_patternOptions; 0325 bool m_isResolved = false; 0326 }; 0327 0328 class StringDetect final : public Rule 0329 { 0330 public: 0331 StringDetect(const HighlightingContextData::Rule::StringDetect &data); 0332 0333 protected: 0334 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0335 0336 private: 0337 QString m_string; 0338 Qt::CaseSensitivity m_caseSensitivity; 0339 }; 0340 0341 class DynamicStringDetect final : public Rule 0342 { 0343 public: 0344 DynamicStringDetect(const HighlightingContextData::Rule::StringDetect &data); 0345 0346 protected: 0347 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0348 0349 private: 0350 QString m_string; 0351 Qt::CaseSensitivity m_caseSensitivity; 0352 }; 0353 0354 class WordDetect final : public Rule 0355 { 0356 public: 0357 WordDetect(DefinitionData &def, const HighlightingContextData::Rule::WordDetect &data); 0358 0359 protected: 0360 MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; 0361 0362 private: 0363 WordDelimiters m_wordDelimiters; 0364 QString m_word; 0365 Qt::CaseSensitivity m_caseSensitivity; 0366 }; 0367 0368 } 0369 0370 #endif // KSYNTAXHIGHLIGHTING_RULE_P_H