diff options
7 files changed, 134 insertions, 71 deletions
diff --git a/src/plugins/texteditor/generichighlighter/progressdata.cpp b/src/plugins/texteditor/generichighlighter/progressdata.cpp index fe892a359b..5bc4ad02c4 100644 --- a/src/plugins/texteditor/generichighlighter/progressdata.cpp +++ b/src/plugins/texteditor/generichighlighter/progressdata.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "progressdata.h" +#include "rule.h" #include <QtCore/QtGlobal> @@ -43,6 +44,12 @@ ProgressData::ProgressData() : m_willContinueLine(false) {} +ProgressData::~ProgressData() +{ + foreach (Rule *rule, m_trackedRules) + rule->progressFinished(); +} + void ProgressData::setOffset(const int offset) { m_offset = offset; } @@ -102,3 +109,8 @@ void ProgressData::setCaptures(const QStringList &captures) const QStringList &ProgressData::captures() const { return m_captures; } + +void ProgressData::trackRule(Rule *rule) +{ + m_trackedRules.append(rule); +} diff --git a/src/plugins/texteditor/generichighlighter/progressdata.h b/src/plugins/texteditor/generichighlighter/progressdata.h index d82b4914d5..8e104c36f5 100644 --- a/src/plugins/texteditor/generichighlighter/progressdata.h +++ b/src/plugins/texteditor/generichighlighter/progressdata.h @@ -35,10 +35,13 @@ namespace TextEditor { namespace Internal { +class Rule; + class ProgressData { public: ProgressData(); + ~ProgressData(); void setOffset(const int offset); int offset() const; @@ -66,6 +69,8 @@ public: void setCaptures(const QStringList &captures); const QStringList &captures() const; + void trackRule(Rule *rule); + private: int m_offset; int m_savedOffset; @@ -74,6 +79,7 @@ private: bool m_closingBraceMatchAtNonEnd; bool m_willContinueLine; QStringList m_captures; + QList<Rule *> m_trackedRules; }; } // namespace Internal diff --git a/src/plugins/texteditor/generichighlighter/rule.cpp b/src/plugins/texteditor/generichighlighter/rule.cpp index f30e6e8e3c..cea4403170 100644 --- a/src/plugins/texteditor/generichighlighter/rule.cpp +++ b/src/plugins/texteditor/generichighlighter/rule.cpp @@ -162,7 +162,7 @@ bool Rule::charPredicateMatchSucceed(const QString &text, return predicateMatchSucceed(text, length, progress, std::ptr_fun(predicate)); } -bool Rule::matchSucceed(const QString &text, const int length, ProgressData *progress) const +bool Rule::matchSucceed(const QString &text, const int length, ProgressData *progress) { if (m_firstNonSpace && !progress->isOnlySpacesSoFar()) return false; @@ -187,6 +187,9 @@ bool Rule::matchSucceed(const QString &text, const int length, ProgressData *pro Rule *Rule::clone() const { return doClone(); } +void Rule::progressFinished() +{ doProgressFinished(); } + bool Rule::matchCharacter(const QString &text, const int length, ProgressData *progress, diff --git a/src/plugins/texteditor/generichighlighter/rule.h b/src/plugins/texteditor/generichighlighter/rule.h index 77c8397bf1..18c21749c7 100644 --- a/src/plugins/texteditor/generichighlighter/rule.h +++ b/src/plugins/texteditor/generichighlighter/rule.h @@ -74,10 +74,12 @@ public: void setDefinition(const QSharedPointer<HighlightDefinition> &definition); const QSharedPointer<HighlightDefinition> &definition() const; - bool matchSucceed(const QString &text, const int length, ProgressData *progress) const; + bool matchSucceed(const QString &text, const int length, ProgressData *progress); Rule *clone() const; + void progressFinished(); + protected: bool charPredicateMatchSucceed(const QString &text, const int length, @@ -128,12 +130,12 @@ protected: static const QLatin1Char kClosingBrace; private: - virtual bool doMatchSucceed(const QString &text, - const int length, - ProgressData *progress) const = 0; + virtual bool doMatchSucceed(const QString &text, const int length, ProgressData *progress) = 0; virtual Rule *doClone() const = 0; + virtual void doProgressFinished() {} + template <class predicate_t> bool predicateMatchSucceed(const QString &text, const int length, diff --git a/src/plugins/texteditor/generichighlighter/specificrules.cpp b/src/plugins/texteditor/generichighlighter/specificrules.cpp index 3e17e1ec35..905aa90072 100644 --- a/src/plugins/texteditor/generichighlighter/specificrules.cpp +++ b/src/plugins/texteditor/generichighlighter/specificrules.cpp @@ -84,7 +84,7 @@ void DetectCharRule::doReplaceExpressions(const QStringList &captures) bool DetectCharRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, m_char)) { // This is to make code folding have a control flow style look in the case of braces. @@ -115,7 +115,7 @@ void Detect2CharsRule::doReplaceExpressions(const QStringList &captures) bool Detect2CharsRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, m_char)) { if (progress->offset() < length && matchCharacter(text, length, progress, m_char1, false)) @@ -133,7 +133,7 @@ void AnyCharRule::setCharacterSet(const QString &s) bool AnyCharRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { Q_UNUSED(length) @@ -163,7 +163,7 @@ void StringDetectRule::doReplaceExpressions(const QStringList &captures) bool StringDetectRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (length - progress->offset() >= m_length) { QString candidate = text.fromRawData(text.unicode() + progress->offset(), m_length); @@ -178,7 +178,11 @@ bool StringDetectRule::doMatchSucceed(const QString &text, // RegExpr void RegExprRule::setPattern(const QString &pattern) -{ m_expression.setPattern(pattern); } +{ + if (pattern.startsWith(QLatin1Char('^'))) + m_onlyBegin = true; + m_expression.setPattern(pattern); +} void RegExprRule::setInsensitive(const QString &insensitive) { m_expression.setCaseSensitivity(toCaseSensitivity(!toBool(insensitive))); } @@ -193,23 +197,50 @@ void RegExprRule::doReplaceExpressions(const QStringList &captures) m_expression.setPattern(s); } +void RegExprRule::doProgressFinished() +{ + m_isCached = false; +} + +bool RegExprRule::isExactMatch(ProgressData *progress) +{ + if (progress->offset() == m_offset && m_length > 0) { + progress->incrementOffset(m_length); + progress->setCaptures(m_captures); + return true; + } + return false; +} + bool RegExprRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { Q_UNUSED(length) - // This is not documented but a regular expression match is considered valid if it starts - // at the current position and if the match length is not zero. + // A regular expression match is considered valid if it happens at the current position + // and if the match length is not zero. const int offset = progress->offset(); - if (m_expression.indexIn(text, offset, QRegExp::CaretAtZero) == offset) { - if (m_expression.matchedLength() == 0) + if (offset > 0 && m_onlyBegin) + return false; + + if (m_isCached) { + if (offset < m_offset || m_offset == -1 || m_length == 0) return false; - progress->incrementOffset(m_expression.matchedLength()); - progress->setCaptures(m_expression.capturedTexts()); - return true; + if (isExactMatch(progress)) + return true; } + m_offset = m_expression.indexIn(text, offset, QRegExp::CaretAtOffset); + m_length = m_expression.matchedLength(); + m_captures = m_expression.capturedTexts(); + + if (isExactMatch(progress)) + return true; + + m_isCached = true; + progress->trackRule(this); + return false; } @@ -237,7 +268,7 @@ void KeywordRule::setList(const QString &listName) bool KeywordRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { int current = progress->offset(); @@ -263,7 +294,7 @@ bool KeywordRule::doMatchSucceed(const QString &text, // Int bool IntRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { const int offset = progress->offset(); @@ -281,7 +312,7 @@ bool IntRule::doMatchSucceed(const QString &text, } // Float -bool FloatRule::doMatchSucceed(const QString &text, const int length, ProgressData *progress) const +bool FloatRule::doMatchSucceed(const QString &text, const int length, ProgressData *progress) { progress->saveOffset(); @@ -322,7 +353,7 @@ bool FloatRule::doMatchSucceed(const QString &text, const int length, ProgressDa // COctal bool HlCOctRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, kZero)) { // In the definition files the number matching rules which are more restrictive should @@ -345,7 +376,7 @@ bool HlCOctRule::doMatchSucceed(const QString &text, // CHex bool HlCHexRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, kZero)) { const int offset = progress->offset(); @@ -367,7 +398,7 @@ bool HlCHexRule::doMatchSucceed(const QString &text, // CString bool HlCStringCharRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchEscapeSequence(text, length, progress)) return true; @@ -384,7 +415,7 @@ bool HlCStringCharRule::doMatchSucceed(const QString &text, // CChar bool HlCCharRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, kSingleQuote)) { if (progress->offset() < length) { @@ -419,7 +450,7 @@ void RangeDetectRule::setChar1(const QString &character) bool RangeDetectRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (matchCharacter(text, length, progress, m_char)) { while (progress->offset() < length) { @@ -436,7 +467,7 @@ bool RangeDetectRule::doMatchSucceed(const QString &text, // LineContinue bool LineContinueRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { if (progress->offset() != length - 1) return false; @@ -456,7 +487,7 @@ DetectSpacesRule::DetectSpacesRule() : Rule(false) bool DetectSpacesRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { return charPredicateMatchSucceed(text, length, progress, &QChar::isSpace); } @@ -464,7 +495,7 @@ bool DetectSpacesRule::doMatchSucceed(const QString &text, // DetectIdentifier bool DetectIdentifierRule::doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const + ProgressData *progress) { // Identifiers are characterized by a letter or underscore as the first character and then // zero or more word characters (\w*). diff --git a/src/plugins/texteditor/generichighlighter/specificrules.h b/src/plugins/texteditor/generichighlighter/specificrules.h index b2d08cd560..a9b38d1bbe 100644 --- a/src/plugins/texteditor/generichighlighter/specificrules.h +++ b/src/plugins/texteditor/generichighlighter/specificrules.h @@ -34,7 +34,7 @@ #include "dynamicrule.h" #include <QtCore/QChar> -#include <QtCore/QString> +#include <QtCore/QStringList> #include <QtCore/QRegExp> #include <QtCore/QSharedPointer> @@ -54,7 +54,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual DetectCharRule *doClone() const { return new DetectCharRule(*this); } virtual void doReplaceExpressions(const QStringList &captures); @@ -72,7 +72,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual Detect2CharsRule *doClone() const { return new Detect2CharsRule(*this); } virtual void doReplaceExpressions(const QStringList &captures); @@ -90,7 +90,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual AnyCharRule *doClone() const { return new AnyCharRule(*this); } QString m_characterSet; @@ -107,7 +107,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual StringDetectRule *doClone() const { return new StringDetectRule(*this); } virtual void doReplaceExpressions(const QStringList &captures); @@ -119,6 +119,7 @@ private: class RegExprRule : public DynamicRule { public: + RegExprRule() : m_onlyBegin(false), m_isCached(false) {} virtual ~RegExprRule() {} void setPattern(const QString &pattern); @@ -128,10 +129,18 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual RegExprRule *doClone() const { return new RegExprRule(*this); } virtual void doReplaceExpressions(const QStringList &captures); + virtual void doProgressFinished(); + bool isExactMatch(ProgressData *progress); + + bool m_onlyBegin; + bool m_isCached; + int m_offset; + int m_length; + QStringList m_captures; QRegExp m_expression; }; @@ -147,7 +156,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual KeywordRule *doClone() const { return new KeywordRule(*this); } bool m_overrideGlobal; @@ -163,7 +172,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual IntRule *doClone() const { return new IntRule(*this); } }; @@ -175,7 +184,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual FloatRule *doClone() const { return new FloatRule(*this); } }; @@ -187,7 +196,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual HlCOctRule *doClone() const { return new HlCOctRule(*this); } }; @@ -199,7 +208,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual HlCHexRule *doClone() const { return new HlCHexRule(*this); } }; @@ -211,7 +220,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual HlCStringCharRule *doClone() const { return new HlCStringCharRule(*this); } }; @@ -223,7 +232,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual HlCCharRule *doClone() const { return new HlCCharRule(*this); } }; @@ -238,7 +247,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual RangeDetectRule *doClone() const { return new RangeDetectRule(*this); } QChar m_char; @@ -253,7 +262,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual LineContinueRule *doClone() const { return new LineContinueRule(*this); } }; @@ -266,7 +275,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual DetectSpacesRule *doClone() const { return new DetectSpacesRule(*this); } }; @@ -278,7 +287,7 @@ public: private: virtual bool doMatchSucceed(const QString &text, const int length, - ProgressData *progress) const; + ProgressData *progress); virtual DetectIdentifierRule *doClone() const { return new DetectIdentifierRule(*this); } }; diff --git a/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp b/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp index 45197a97d0..d530c0caab 100644 --- a/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp +++ b/tests/auto/generichighlighter/specificrules/tst_specificrules.cpp @@ -105,8 +105,8 @@ private slots: private: void addCommonColumns() const; - void testMatch(const Rule &rule) const; - void testMatch(const Rule &rule, ProgressData *progress) const; + void testMatch(Rule *rule); + void testMatch(Rule *rule, ProgressData *progress); void noMatchForInt() const; void noMatchForFloat() const; @@ -138,17 +138,17 @@ void tst_SpecificRules::addCommonColumns() const QTest::addColumn<bool>("will continue"); } -void tst_SpecificRules::testMatch(const Rule &rule) const +void tst_SpecificRules::testMatch(Rule *rule) { ProgressData progress; testMatch(rule, &progress); } -void tst_SpecificRules::testMatch(const Rule &rule, ProgressData *progress) const +void tst_SpecificRules::testMatch(Rule *rule, ProgressData *progress) { QFETCH(QString, s); - QTEST(rule.matchSucceed(s, s.length(), progress), "match"); + QTEST(rule->matchSucceed(s, s.length(), progress), "match"); QTEST(progress->offset(), "offset"); QTEST(progress->isOnlySpacesSoFar(), "only spaces"); QTEST(progress->isWillContinueLine(), "will continue"); @@ -160,7 +160,7 @@ void tst_SpecificRules::testDetectChar() DetectCharRule rule; rule.setChar(c); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testDetectChar_data() @@ -186,7 +186,7 @@ void tst_SpecificRules::testDetect2Char() rule.setChar(c); rule.setChar1(c1); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testDetect2Char_data() @@ -214,7 +214,7 @@ void tst_SpecificRules::testAnyChar() AnyCharRule rule; rule.setCharacterSet(chars); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testAnyChar_data() @@ -245,7 +245,7 @@ void tst_SpecificRules::testStringDetect() rule.setString(referenceString); rule.setInsensitive(insensitive); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testStringDetect_data() @@ -277,7 +277,7 @@ void tst_SpecificRules::testRegExpr() rule.setInsensitive(insensitive); rule.setMinimal(minimal); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testRegExpr_data() @@ -322,7 +322,7 @@ void tst_SpecificRules::testRegExprOffsetIncremented() ProgressData progress; progress.setOffset(1); - testMatch(rule, &progress); + testMatch(&rule, &progress); } void tst_SpecificRules::testRegExprOffsetIncremented_data() @@ -388,7 +388,7 @@ void tst_SpecificRules::testKeywordGlobalSensitiveLocalSensitive() rule.setInsensitive("false"); rule.setList("keywords"); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testKeywordGlobalSensitiveLocalSensitive_data() @@ -410,7 +410,7 @@ void tst_SpecificRules::testKeywordGlobalSensitiveLocalInsensitive() rule.setInsensitive("true"); rule.setList("keywords"); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testKeywordGlobalSensitiveLocalInsensitive_data() @@ -432,7 +432,7 @@ void tst_SpecificRules::testKeywordGlobalInsensitiveLocalInsensitive() rule.setInsensitive("true"); rule.setList("keywords"); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testKeywordGlobalInsensitiveLocalInsensitive_data() @@ -447,7 +447,7 @@ void tst_SpecificRules::testKeywordGlobalInsensitiveLocalSensitive() rule.setInsensitive("false"); rule.setList("keywords"); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testKeywordGlobalInsensitiveLocalSensitive_data() @@ -510,7 +510,7 @@ void tst_SpecificRules::noMatchForNumber() const void tst_SpecificRules::testInt() { IntRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testInt_data() @@ -534,7 +534,7 @@ void tst_SpecificRules::testInt_data() void tst_SpecificRules::testFloat() { FloatRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testFloat_data() @@ -568,7 +568,7 @@ void tst_SpecificRules::testFloat_data() void tst_SpecificRules::testCOctal() { HlCOctRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testCOctal_data() @@ -589,7 +589,7 @@ void tst_SpecificRules::testCOctal_data() void tst_SpecificRules::testCHex() { HlCHexRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testCHex_data() @@ -609,7 +609,7 @@ void tst_SpecificRules::testCHex_data() void tst_SpecificRules::testCString() { HlCStringCharRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testCString_data() @@ -656,7 +656,7 @@ void tst_SpecificRules::testCString_data() void tst_SpecificRules::testCChar() { HlCCharRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testCChar_data() @@ -692,7 +692,7 @@ void tst_SpecificRules::testRangeDetect() rule.setChar(c); rule.setChar1(c1); - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testRangeDetect_data() @@ -719,7 +719,7 @@ void tst_SpecificRules::testRangeDetect_data() void tst_SpecificRules::testLineContinue() { LineContinueRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testLineContinue_data() @@ -737,7 +737,7 @@ void tst_SpecificRules::testLineContinue_data() void tst_SpecificRules::testDetectSpaces() { DetectSpacesRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testDetectSpaces_data() @@ -754,7 +754,7 @@ void tst_SpecificRules::testDetectSpaces_data() void tst_SpecificRules::testDetectIdentifier() { DetectIdentifierRule rule; - testMatch(rule); + testMatch(&rule); } void tst_SpecificRules::testDetectIdentifier_data() |