/* SPDX-FileCopyrightText: 2016 Volker Krause SPDX-FileCopyrightText: 2020 Jonathan Poelen SPDX-License-Identifier: MIT */ #ifndef KSYNTAXHIGHLIGHTING_RULE_P_H #define KSYNTAXHIGHLIGHTING_RULE_P_H #include "contextswitch_p.h" #include "foldingregion.h" #include "format.h" #include "highlightingdata_p.hpp" #include "keywordlist_p.h" #include "matchresult_p.h" #include "worddelimiters_p.h" #include #include #include namespace KSyntaxHighlighting { class WordDelimiters; class DefinitionData; class IncludeRules; class DynamicRegexpCache; class Rule { public: Rule() = default; virtual ~Rule(); typedef std::shared_ptr Ptr; const Format &attributeFormat() const { return m_attributeFormat; } const ContextSwitch &context() const { return m_context; } bool isLookAhead() const { return m_lookAhead; } bool isDynamic() const { return m_dynamic; } bool firstNonSpace() const { return m_firstNonSpace; } int requiredColumn() const { return m_column; } const FoldingRegion &beginRegion() const { return m_beginRegion; } const FoldingRegion &endRegion() const { return m_endRegion; } const IncludeRules *castToIncludeRules() const; bool isLineContinue() const { return m_type == Type::LineContinue; } // If true, then the rule uses the skipOffset parameter of MatchResult. // This is used by AbstractHighlighter::highlightLine() to look for a rule // in the skipOffsets cache only if it can be found there. bool hasSkipOffset() const { return m_hasSkipOffset; } virtual MatchResult doMatch(QStringView text, int offset, const QStringList &captures, DynamicRegexpCache &dynamicRegexpCache) const = 0; static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName); private: Q_DISABLE_COPY(Rule) bool resolveCommon(DefinitionData &def, const HighlightingContextData::Rule &ruleData, QStringView lookupContextName); enum class Type : quint8 { OtherRule, LineContinue, IncludeRules, }; private: Format m_attributeFormat; ContextSwitch m_context; int m_column = -1; FoldingRegion m_beginRegion; FoldingRegion m_endRegion; Type m_type; bool m_firstNonSpace = false; bool m_lookAhead = false; protected: bool m_hasSkipOffset = false; bool m_dynamic = false; }; class AnyChar final : public Rule { public: AnyChar(const HighlightingContextData::Rule::AnyChar &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_chars; }; class DetectChar final : public Rule { public: DetectChar(const HighlightingContextData::Rule::DetectChar &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QChar m_char; int m_captureIndex = 0; }; class Detect2Chars final : public Rule { public: Detect2Chars(const HighlightingContextData::Rule::Detect2Chars &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QChar m_char1; QChar m_char2; }; class DetectIdentifier final : public Rule { protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; }; class DetectSpaces final : public Rule { protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; }; class Float final : public Rule { public: Float(DefinitionData &def, const HighlightingContextData::Rule::Float &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; }; class IncludeRules final : public Rule { public: IncludeRules(const HighlightingContextData::Rule::IncludeRules &data); const QString &contextName() const { return m_contextName; } bool includeAttribute() const { return m_includeAttribute; } protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QString m_contextName; bool m_includeAttribute; }; class Int final : public Rule { public: Int(DefinitionData &def, const HighlightingContextData::Rule::Int &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; }; class HlCChar final : public Rule { protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; }; class HlCHex final : public Rule { public: HlCHex(DefinitionData &def, const HighlightingContextData::Rule::HlCHex &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; }; class HlCOct final : public Rule { public: HlCOct(DefinitionData &def, const HighlightingContextData::Rule::HlCOct &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; }; class HlCStringChar final : public Rule { protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; }; class KeywordListRule final : public Rule { public: KeywordListRule(const KeywordList &keywordList, DefinitionData &def, const HighlightingContextData::Rule::Keyword &data); static Rule::Ptr create(DefinitionData &def, const HighlightingContextData::Rule::Keyword &data, QStringView lookupContextName); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; const KeywordList &m_keywordList; Qt::CaseSensitivity m_caseSensitivity; }; class LineContinue final : public Rule { public: LineContinue(const HighlightingContextData::Rule::LineContinue &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QChar m_char; }; class RangeDetect final : public Rule { public: RangeDetect(const HighlightingContextData::Rule::RangeDetect &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QChar m_begin; QChar m_end; }; class RegExpr final : public Rule { public: RegExpr(const HighlightingContextData::Rule::RegExpr &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: void resolve(); QRegularExpression m_regexp; bool m_isResolved = false; }; class DynamicRegExpr final : public Rule { public: DynamicRegExpr(const HighlightingContextData::Rule::RegExpr &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: void resolve(); QString m_pattern; QRegularExpression::PatternOptions m_patternOptions; bool m_isResolved = false; }; class StringDetect final : public Rule { public: StringDetect(const HighlightingContextData::Rule::StringDetect &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QString m_string; Qt::CaseSensitivity m_caseSensitivity; }; class DynamicStringDetect final : public Rule { public: DynamicStringDetect(const HighlightingContextData::Rule::StringDetect &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: QString m_string; Qt::CaseSensitivity m_caseSensitivity; }; class WordDetect final : public Rule { public: WordDetect(DefinitionData &def, const HighlightingContextData::Rule::WordDetect &data); protected: MatchResult doMatch(QStringView text, int offset, const QStringList &, DynamicRegexpCache &) const override; private: WordDelimiters m_wordDelimiters; QString m_word; Qt::CaseSensitivity m_caseSensitivity; }; } #endif // KSYNTAXHIGHLIGHTING_RULE_P_H