summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2017-05-04 14:46:12 +0200
committerDavid Schulz <david.schulz@qt.io>2017-05-05 05:58:26 +0000
commit7e38b54525ac23c5cdbc18582e70d4a506b399d6 (patch)
treefeada2b9cc374aefcb4d0d83bef0ac3892b2e438
parent7fb81d94f40b8a9538c4521244396b5772e1cfae (diff)
downloadqt-creator-7e38b54525ac23c5cdbc18582e70d4a506b399d6.tar.gz
Highlighter: Fix freezing highlighter for complex context switches
Exclamation marks in context attributes are used to split the attribute into a number of orders and an identifier. This identifier is the context that have to be set after executing the orders. Ignoring this context identifier could lead to an endless loop if used inside a default context with a Rule that has set the lookAhead attribute. Task-number: QTCREATORBUG-14611 Change-Id: I5992fa47ed2e353cbf7882bc772fdbee8f7f41f1 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r--src/plugins/texteditor/generichighlighter/highlighter.cpp15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp
index 89150ac6d4..d3c0b47d50 100644
--- a/src/plugins/texteditor/generichighlighter/highlighter.cpp
+++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp
@@ -45,6 +45,7 @@ namespace {
static const QLatin1String kPop("#pop");
static const QLatin1Char kBackSlash('\\');
static const QLatin1Char kHash('#');
+ static const QLatin1Char kExclamationMark('!');
}
class HighlighterCodeFormatterData : public CodeFormatterData
@@ -414,8 +415,13 @@ void Highlighter::changeContext(const QString &contextName,
const QSharedPointer<HighlightDefinition> &definition,
const bool assignCurrent)
{
- if (contextName.startsWith(kPop)) {
- const int count = contextName.splitRef(kHash, QString::SkipEmptyParts).size();
+ QString identifier = contextName;
+ if (identifier.startsWith(kPop)) {
+ const QStringList complexOrder = contextName.split(kExclamationMark);
+ const QString orders = complexOrder.first();
+ identifier = complexOrder.size() > 1 ? complexOrder[1] : QString();
+
+ const int count = orders.splitRef(kHash, QString::SkipEmptyParts).size();
for (int i = 0; i < count; ++i) {
if (m_contexts.isEmpty()) {
throw HighlighterException(
@@ -434,8 +440,9 @@ void Highlighter::changeContext(const QString &contextName,
setCurrentBlockState(
computeState(m_leadingObservableStates.value(currentSequence)));
}
- } else {
- const QSharedPointer<Context> &context = definition->context(contextName);
+ }
+ if (!identifier.isEmpty()) {
+ const QSharedPointer<Context> &context = definition->context(identifier);
if (context->isDynamic())
pushDynamicContext(context);