diff --git a/src/plugins/duieditor/duieditor.cpp b/src/plugins/duieditor/duieditor.cpp index 71aa0a0c31a3be12e82c2696c7711da921c1380a..e52b33bb244796b776aff0bada83b4e808488088 100644 --- a/src/plugins/duieditor/duieditor.cpp +++ b/src/plugins/duieditor/duieditor.cpp @@ -85,6 +85,76 @@ protected: { AST::Node::acceptChild(node, this); } }; +class HighlightBindings: protected Visitor +{ +public: + HighlightBindings(QTextDocument *doc) + : _doc(doc) + { } + + void setFormat(const QTextCharFormat &format) + { _format = format; } + + QList<QTextEdit::ExtraSelection> operator()(AST::Node *node) + { + _selections.clear(); + accept(node); + return _selections; + } + +protected: + using Visitor::visit; + + void accept(AST::Node *node) + { AST::Node::acceptChild(node, this); } + + void highlight(int begin, int end) + { + QTextCursor cursor(_doc); + cursor.setPosition(begin); + cursor.setPosition(end, QTextCursor::KeepAnchor); + QTextEdit::ExtraSelection sel; + sel.cursor = cursor; + sel.format = _format; + _selections.append(sel); + } + + void highlight(AST::UiQualifiedId *qualifiedId) + { + AST::UiQualifiedId *last = qualifiedId; + for (; last; last = last->next) { + if (! last->next) + break; + } + highlight(qualifiedId->identifierToken.begin(), + last->identifierToken.end()); + } + + virtual bool visit(AST::UiScriptBinding *node) + { + highlight(node->qualifiedId); + + return false; // there's no need to visit the JS statement, we can't find bindings there. + } + + virtual bool visit(AST::UiObjectBinding *node) + { + highlight(node->qualifiedId); + return true; // search for more bindings + } + + virtual bool visit(AST::UiArrayBinding *node) + { + highlight(node->qualifiedId); + return true; // search for more bindings + } + +private: + QTextDocument *_doc; + QTextCharFormat _format; + QList<QTextEdit::ExtraSelection> _selections; +}; + ScriptEditorEditable::ScriptEditorEditable(ScriptEditor *editor, const QList<int>& context) : BaseTextEditorEditable(editor), m_context(context) { @@ -165,9 +235,14 @@ void ScriptEditor::updateDocumentNow() lexer.setCode(code, /*line = */ 1); driver.setLexer(&lexer); - if (parser.parse(&driver)) { - FindDeclarations decls; - m_declarations = decls(parser.ast()); + bool parsed = parser.parse(&driver); + + if (parsed) { + if (DuiHighlighter *highlighter = qobject_cast<DuiHighlighter*>(baseTextDocument()->syntaxHighlighter())) { + HighlightBindings highlightIds(document()); + highlightIds.setFormat(highlighter->labelTextCharFormat()); + setExtraSelections(CodeSemanticsSelection, highlightIds(parser.ast())); + } m_words.clear(); foreach (const JavaScriptNameIdImpl &id, driver.literals()) diff --git a/src/shared/qscripthighlighter/qscripthighlighter.h b/src/shared/qscripthighlighter/qscripthighlighter.h index 51c4932d5df5dfa13181455755d44c8b53e229bf..8917af0ee3e60bca0848a1cc82711c5f243845d7 100644 --- a/src/shared/qscripthighlighter/qscripthighlighter.h +++ b/src/shared/qscripthighlighter/qscripthighlighter.h @@ -53,6 +53,9 @@ public: void setFormats(const QVector<QTextCharFormat> &s); static const QVector<QTextCharFormat> &defaultFormats(); + QTextCharFormat labelTextCharFormat() const + { return m_formats[LabelFormat]; } + private: // The functions are notified whenever parentheses are encountered. // Custom behaviour can be added, for example storing info for indenting.