diff --git a/src/lib/abstracthighlighter.cpp b/src/lib/abstracthighlighter.cpp --- a/src/lib/abstracthighlighter.cpp +++ b/src/lib/abstracthighlighter.cpp @@ -127,13 +127,14 @@ auto defData = DefinitionData::get(d->m_definition); auto newState = state; auto stateData = StateData::get(newState); - if (stateData->m_defData && defData != stateData->m_defData) { + const DefinitionRef currentDefRef(d->m_definition); + if (!stateData->isEmpty() && (stateData->m_defRef != currentDefRef)) { qCDebug(Log) << "Got invalid state, resetting."; stateData->clear(); } if (stateData->isEmpty()) { stateData->push(defData->initialContext(), QStringList()); - stateData->m_defData = defData; + stateData->m_defRef = currentDefRef; } // process empty lines diff --git a/src/lib/definition.cpp b/src/lib/definition.cpp --- a/src/lib/definition.cpp +++ b/src/lib/definition.cpp @@ -783,3 +783,12 @@ return Definition(d.lock()); return Definition(); } + +bool DefinitionRef::operator==(const DefinitionRef &other) const +{ + if (d.expired() != other.d.expired()) { + return false; + } + + return d.expired() || d.lock().get() == other.d.lock().get(); +} diff --git a/src/lib/definitionref_p.h b/src/lib/definitionref_p.h --- a/src/lib/definitionref_p.h +++ b/src/lib/definitionref_p.h @@ -50,6 +50,19 @@ Definition definition() const; + /** + * Checks two definition references for equality. + */ + bool operator==(const DefinitionRef &other) const; + + /** + * Checks two definition references for inequality. + */ + bool operator!=(const DefinitionRef &other) const + { + return !(*this == other); + } + private: friend class DefinitionData; std::weak_ptr d; diff --git a/src/lib/state.cpp b/src/lib/state.cpp --- a/src/lib/state.cpp +++ b/src/lib/state.cpp @@ -97,7 +97,8 @@ bool State::operator==(const State &other) const { - return d->m_contextStack == other.d->m_contextStack && d->m_defData == other.d->m_defData; + // use pointer equal as shortcut for shared states + return (d == other.d) || (d->m_contextStack == other.d->m_contextStack && d->m_defRef == other.d->m_defRef); } bool State::operator!=(const State &other) const diff --git a/src/lib/state_p.h b/src/lib/state_p.h --- a/src/lib/state_p.h +++ b/src/lib/state_p.h @@ -28,19 +28,21 @@ #include #include +#include "definitionref_p.h" + QT_BEGIN_NAMESPACE class QStringList; QT_END_NAMESPACE namespace KSyntaxHighlighting { class Context; -class DefinitionData; class StateData : public QSharedData { friend class State; + friend class AbstractHighlighter; public: StateData() = default; @@ -54,14 +56,11 @@ Context* topContext() const; const QStringList &topCaptures() const; +private: /** - * definition pointer to check for invalid states - * FIXME: this is a hack, one could get the same pointer - * later for other object + * weak reference to the used definition to filter out invalid states */ - DefinitionData *m_defData = nullptr; - -private: + DefinitionRef m_defRef; /** * the context stack combines the active context + valid captures