Commit c105ae47 authored by Christian Kamm's avatar Christian Kamm

QmlJS: Add semantic highlighting.

Change-Id: If9293244075cff1a52801b50cdbb77248ecd21ea
Reviewed-on: http://codereview.qt.nokia.com/3310Reviewed-by: default avatarFawzi Mohamed <fawzi.mohamed@nokia.com>
parent 1b9af316
...@@ -56,6 +56,20 @@ QList<const QmlComponentChain *> QmlComponentChain::instantiatingComponents() co ...@@ -56,6 +56,20 @@ QList<const QmlComponentChain *> QmlComponentChain::instantiatingComponents() co
return m_instantiatingComponents; return m_instantiatingComponents;
} }
const ObjectValue *QmlComponentChain::idScope() const
{
if (!m_document)
return 0;
return m_document->bind()->idEnvironment();
}
const ObjectValue *QmlComponentChain::rootObjectScope() const
{
if (!m_document)
return 0;
return m_document->bind()->rootObjectValue();
}
void QmlComponentChain::addInstantiatingComponent(const QmlComponentChain *component) void QmlComponentChain::addInstantiatingComponent(const QmlComponentChain *component)
{ {
m_instantiatingComponents.append(component); m_instantiatingComponents.append(component);
...@@ -188,9 +202,9 @@ static void collectScopes(const QmlComponentChain *chain, QList<const ObjectValu ...@@ -188,9 +202,9 @@ static void collectScopes(const QmlComponentChain *chain, QList<const ObjectValu
if (!chain->document()) if (!chain->document())
return; return;
if (ObjectValue *root = chain->document()->bind()->rootObjectValue()) if (const ObjectValue *root = chain->rootObjectScope())
target->append(root); target->append(root);
if (ObjectValue *ids = chain->document()->bind()->idEnvironment()) if (const ObjectValue *ids = chain->idScope())
target->append(ids); target->append(ids);
} }
...@@ -294,4 +308,3 @@ void ScopeChain::makeComponentChain( ...@@ -294,4 +308,3 @@ void ScopeChain::makeComponentChain(
} }
} }
} }
...@@ -58,6 +58,9 @@ public: ...@@ -58,6 +58,9 @@ public:
Document::Ptr document() const; Document::Ptr document() const;
QList<const QmlComponentChain *> instantiatingComponents() const; QList<const QmlComponentChain *> instantiatingComponents() const;
const ObjectValue *idScope() const;
const ObjectValue *rootObjectScope() const;
// takes ownership // takes ownership
void addInstantiatingComponent(const QmlComponentChain *component); void addInstantiatingComponent(const QmlComponentChain *component);
......
...@@ -442,7 +442,7 @@ bool CheckSymbols::visit(NamespaceAST *ast) ...@@ -442,7 +442,7 @@ bool CheckSymbols::visit(NamespaceAST *ast)
if (! tok.generated()) { if (! tok.generated()) {
unsigned line, column; unsigned line, column;
getTokenStartPosition(ast->identifier_token, &line, &column); getTokenStartPosition(ast->identifier_token, &line, &column);
Use use(line, column, tok.length()); Use use(line, column, tok.length(), SemanticInfo::TypeUse);
addUse(use); addUse(use);
} }
} }
...@@ -457,7 +457,7 @@ bool CheckSymbols::visit(UsingDirectiveAST *) ...@@ -457,7 +457,7 @@ bool CheckSymbols::visit(UsingDirectiveAST *)
bool CheckSymbols::visit(EnumeratorAST *ast) bool CheckSymbols::visit(EnumeratorAST *ast)
{ {
addUse(ast->identifier_token, Use::Static); addUse(ast->identifier_token, SemanticInfo::StaticUse);
return true; return true;
} }
...@@ -469,7 +469,7 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast) ...@@ -469,7 +469,7 @@ bool CheckSymbols::visit(SimpleDeclarationAST *ast)
if (NameAST *declId = declaratorId(ast->declarator_list->value)) { if (NameAST *declId = declaratorId(ast->declarator_list->value)) {
if (Function *funTy = decl->type()->asFunctionType()) { if (Function *funTy = decl->type()->asFunctionType()) {
if (funTy->isVirtual()) { if (funTy->isVirtual()) {
addUse(declId, Use::VirtualMethod); addUse(declId, SemanticInfo::VirtualMethodUse);
} else if (maybeVirtualMethod(decl->name())) { } else if (maybeVirtualMethod(decl->name())) {
addVirtualMethod(_context.lookup(decl->name(), decl->enclosingScope()), declId, funTy->argumentCount()); addVirtualMethod(_context.lookup(decl->name(), decl->enclosingScope()), declId, funTy->argumentCount());
} }
...@@ -490,7 +490,7 @@ bool CheckSymbols::visit(ElaboratedTypeSpecifierAST *ast) ...@@ -490,7 +490,7 @@ bool CheckSymbols::visit(ElaboratedTypeSpecifierAST *ast)
{ {
accept(ast->attribute_list); accept(ast->attribute_list);
accept(ast->name); accept(ast->name);
addUse(ast->name, Use::Type); addUse(ast->name, SemanticInfo::TypeUse);
return false; return false;
} }
...@@ -643,7 +643,7 @@ void CheckSymbols::checkName(NameAST *ast, Scope *scope) ...@@ -643,7 +643,7 @@ void CheckSymbols::checkName(NameAST *ast, Scope *scope)
if (ast->asDestructorName() != 0) { if (ast->asDestructorName() != 0) {
Class *klass = scope->asClass(); Class *klass = scope->asClass();
if (hasVirtualDestructor(_context.lookupType(klass))) if (hasVirtualDestructor(_context.lookupType(klass)))
addUse(ast, Use::VirtualMethod); addUse(ast, SemanticInfo::VirtualMethodUse);
} else if (maybeType(ast->name) || maybeStatic(ast->name)) { } else if (maybeType(ast->name) || maybeStatic(ast->name)) {
const QList<LookupItem> candidates = _context.lookup(ast->name, scope); const QList<LookupItem> candidates = _context.lookup(ast->name, scope);
addTypeOrStatic(candidates, ast); addTypeOrStatic(candidates, ast);
...@@ -693,7 +693,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) ...@@ -693,7 +693,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) { if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
if (TemplateIdAST *template_id = class_or_namespace_name->asTemplateId()) { if (TemplateIdAST *template_id = class_or_namespace_name->asTemplateId()) {
if (template_id->template_token) { if (template_id->template_token) {
addUse(template_id, Use::Type); addUse(template_id, SemanticInfo::TypeUse);
binding = 0; // there's no way we can find a binding. binding = 0; // there's no way we can find a binding.
} }
...@@ -714,7 +714,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) ...@@ -714,7 +714,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
if (binding && ast->unqualified_name) { if (binding && ast->unqualified_name) {
if (ast->unqualified_name->asDestructorName() != 0) { if (ast->unqualified_name->asDestructorName() != 0) {
if (hasVirtualDestructor(binding)) if (hasVirtualDestructor(binding))
addUse(ast->unqualified_name, Use::VirtualMethod); addUse(ast->unqualified_name, SemanticInfo::VirtualMethodUse);
} else { } else {
addTypeOrStatic(binding->find(ast->unqualified_name->name), ast->unqualified_name); addTypeOrStatic(binding->find(ast->unqualified_name->name), ast->unqualified_name);
} }
...@@ -729,7 +729,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast) ...@@ -729,7 +729,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
bool CheckSymbols::visit(TypenameTypeParameterAST *ast) bool CheckSymbols::visit(TypenameTypeParameterAST *ast)
{ {
addUse(ast->name, Use::Type); addUse(ast->name, SemanticInfo::TypeUse);
accept(ast->type_id); accept(ast->type_id);
return false; return false;
} }
...@@ -737,7 +737,7 @@ bool CheckSymbols::visit(TypenameTypeParameterAST *ast) ...@@ -737,7 +737,7 @@ bool CheckSymbols::visit(TypenameTypeParameterAST *ast)
bool CheckSymbols::visit(TemplateTypeParameterAST *ast) bool CheckSymbols::visit(TemplateTypeParameterAST *ast)
{ {
accept(ast->template_parameter_list); accept(ast->template_parameter_list);
addUse(ast->name, Use::Type); addUse(ast->name, SemanticInfo::TypeUse);
accept(ast->type_id); accept(ast->type_id);
return false; return false;
} }
...@@ -775,7 +775,7 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast) ...@@ -775,7 +775,7 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast)
declId = q->unqualified_name; declId = q->unqualified_name;
if (fun->isVirtual()) { if (fun->isVirtual()) {
addUse(declId, Use::VirtualMethod); addUse(declId, SemanticInfo::VirtualMethodUse);
} else if (maybeVirtualMethod(fun->name())) { } else if (maybeVirtualMethod(fun->name())) {
addVirtualMethod(_context.lookup(fun->name(), fun->enclosingScope()), declId, fun->argumentCount()); addVirtualMethod(_context.lookup(fun->name(), fun->enclosingScope()), declId, fun->argumentCount());
} }
...@@ -798,7 +798,7 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast) ...@@ -798,7 +798,7 @@ bool CheckSymbols::visit(FunctionDefinitionAST *ast)
return false; return false;
} }
void CheckSymbols::addUse(NameAST *ast, Use::Kind kind) void CheckSymbols::addUse(NameAST *ast, UseKind kind)
{ {
if (! ast) if (! ast)
return; return;
...@@ -822,7 +822,7 @@ void CheckSymbols::addUse(NameAST *ast, Use::Kind kind) ...@@ -822,7 +822,7 @@ void CheckSymbols::addUse(NameAST *ast, Use::Kind kind)
addUse(startToken, kind); addUse(startToken, kind);
} }
void CheckSymbols::addUse(unsigned tokenIndex, Use::Kind kind) void CheckSymbols::addUse(unsigned tokenIndex, UseKind kind)
{ {
if (! tokenIndex) if (! tokenIndex)
return; return;
...@@ -871,7 +871,7 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast) ...@@ -871,7 +871,7 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
unsigned line, column; unsigned line, column;
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.length(); const unsigned length = tok.length();
const Use use(line, column, length, Use::Type); const Use use(line, column, length, SemanticInfo::TypeUse);
addUse(use); addUse(use);
//qDebug() << "added use" << oo(ast->name) << line << column << length; //qDebug() << "added use" << oo(ast->name) << line << column << length;
} }
...@@ -913,10 +913,10 @@ void CheckSymbols::addTypeOrStatic(const QList<LookupItem> &candidates, NameAST ...@@ -913,10 +913,10 @@ void CheckSymbols::addTypeOrStatic(const QList<LookupItem> &candidates, NameAST
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.length(); const unsigned length = tok.length();
Use::Kind kind = Use::Type; UseKind kind = SemanticInfo::TypeUse;
if (c->enclosingEnum() != 0) if (c->enclosingEnum() != 0)
kind = Use::Static; kind = SemanticInfo::StaticUse;
const Use use(line, column, length, kind); const Use use(line, column, length, kind);
addUse(use); addUse(use);
...@@ -951,7 +951,7 @@ void CheckSymbols::addClassMember(const QList<LookupItem> &candidates, NameAST * ...@@ -951,7 +951,7 @@ void CheckSymbols::addClassMember(const QList<LookupItem> &candidates, NameAST *
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.length(); const unsigned length = tok.length();
const Use use(line, column, length, Use::Field); const Use use(line, column, length, SemanticInfo::FieldUse);
addUse(use); addUse(use);
break; break;
} }
...@@ -976,7 +976,7 @@ void CheckSymbols::addStatic(const QList<LookupItem> &candidates, NameAST *ast) ...@@ -976,7 +976,7 @@ void CheckSymbols::addStatic(const QList<LookupItem> &candidates, NameAST *ast)
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.length(); const unsigned length = tok.length();
const Use use(line, column, length, Use::Static); const Use use(line, column, length, SemanticInfo::StaticUse);
addUse(use); addUse(use);
//qDebug() << "added use" << oo(ast->name) << line << column << length; //qDebug() << "added use" << oo(ast->name) << line << column << length;
break; break;
...@@ -1015,7 +1015,7 @@ void CheckSymbols::addVirtualMethod(const QList<LookupItem> &candidates, NameAST ...@@ -1015,7 +1015,7 @@ void CheckSymbols::addVirtualMethod(const QList<LookupItem> &candidates, NameAST
getTokenStartPosition(startToken, &line, &column); getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.length(); const unsigned length = tok.length();
const Use use(line, column, length, Use::VirtualMethod); const Use use(line, column, length, SemanticInfo::VirtualMethodUse);
addUse(use); addUse(use);
break; break;
} }
......
...@@ -55,6 +55,7 @@ public: ...@@ -55,6 +55,7 @@ public:
virtual ~CheckSymbols(); virtual ~CheckSymbols();
typedef CppEditor::Internal::SemanticInfo::Use Use; typedef CppEditor::Internal::SemanticInfo::Use Use;
typedef CppEditor::Internal::SemanticInfo::UseKind UseKind;
virtual void run(); virtual void run();
...@@ -110,8 +111,8 @@ protected: ...@@ -110,8 +111,8 @@ protected:
void checkNamespace(NameAST *name); void checkNamespace(NameAST *name);
void addUse(const Use &use); void addUse(const Use &use);
void addUse(unsigned tokenIndex, Use::Kind kind); void addUse(unsigned tokenIndex, UseKind kind);
void addUse(NameAST *name, Use::Kind kind); void addUse(NameAST *name, UseKind kind);
void addType(ClassOrNamespace *b, NameAST *ast); void addType(ClassOrNamespace *b, NameAST *ast);
......
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
#include <texteditor/tabsettings.h> #include <texteditor/tabsettings.h>
#include <texteditor/texteditorconstants.h> #include <texteditor/texteditorconstants.h>
#include <texteditor/refactoroverlay.h> #include <texteditor/refactoroverlay.h>
#include <texteditor/semantichighlighter.h>
#include <texteditor/codeassist/basicproposalitemlistmodel.h> #include <texteditor/codeassist/basicproposalitemlistmodel.h>
#include <texteditor/codeassist/basicproposalitem.h> #include <texteditor/codeassist/basicproposalitem.h>
#include <texteditor/codeassist/genericproposal.h> #include <texteditor/codeassist/genericproposal.h>
...@@ -461,7 +462,6 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent) ...@@ -461,7 +462,6 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
} }
m_highlightRevision = 0; m_highlightRevision = 0;
m_nextHighlightBlockNumber = 0;
connect(&m_highlightWatcher, SIGNAL(resultsReadyAt(int,int)), SLOT(highlightSymbolUsages(int,int))); connect(&m_highlightWatcher, SIGNAL(resultsReadyAt(int,int)), SLOT(highlightSymbolUsages(int,int)));
connect(&m_highlightWatcher, SIGNAL(finished()), SLOT(finishHighlightSymbolUsages())); connect(&m_highlightWatcher, SIGNAL(finished()), SLOT(finishHighlightSymbolUsages()));
...@@ -1010,68 +1010,11 @@ void CPPEditorWidget::highlightSymbolUsages(int from, int to) ...@@ -1010,68 +1010,11 @@ void CPPEditorWidget::highlightSymbolUsages(int from, int to)
else if (m_highlighter.isCanceled()) else if (m_highlighter.isCanceled())
return; // aborted return; // aborted
CppHighlighter *highlighter = qobject_cast<CppHighlighter*>(baseTextDocument()->syntaxHighlighter()); TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
Q_ASSERT(highlighter); QTC_ASSERT(highlighter, return);
QTextDocument *doc = document();
if (m_nextHighlightBlockNumber >= doc->blockCount())
return;
QMap<int, QVector<SemanticInfo::Use> > chunks = CheckSymbols::chunks(m_highlighter, from, to);
if (chunks.isEmpty())
return;
QTextBlock b = doc->findBlockByNumber(m_nextHighlightBlockNumber);
QMapIterator<int, QVector<SemanticInfo::Use> > it(chunks);
while (b.isValid() && it.hasNext()) {
it.next();
const int blockNumber = it.key();
Q_ASSERT(blockNumber < doc->blockCount());
while (m_nextHighlightBlockNumber < blockNumber) {
highlighter->setExtraAdditionalFormats(b, QList<QTextLayout::FormatRange>());
b = b.next();
++m_nextHighlightBlockNumber;
}
QList<QTextLayout::FormatRange> formats;
foreach (const SemanticInfo::Use &use, it.value()) {
QTextLayout::FormatRange formatRange;
switch (use.kind) { TextEditor::SemanticHighlighter::incrementalApplyExtraAdditionalFormats(
case SemanticInfo::Use::Type: highlighter, m_highlighter, from, to, m_semanticHighlightFormatMap);
formatRange.format = m_typeFormat;
break;
case SemanticInfo::Use::Field:
formatRange.format = m_fieldFormat;
break;
case SemanticInfo::Use::Local:
formatRange.format = m_localFormat;
break;
case SemanticInfo::Use::Static:
formatRange.format = m_staticFormat;
break;
case SemanticInfo::Use::VirtualMethod:
formatRange.format = m_virtualMethodFormat;
break;
default:
continue;
}
formatRange.start = use.column - 1;
formatRange.length = use.length;
formats.append(formatRange);
}
highlighter->setExtraAdditionalFormats(b, formats);
b = b.next();
++m_nextHighlightBlockNumber;
}
} }
void CPPEditorWidget::finishHighlightSymbolUsages() void CPPEditorWidget::finishHighlightSymbolUsages()
...@@ -1082,20 +1025,11 @@ void CPPEditorWidget::finishHighlightSymbolUsages() ...@@ -1082,20 +1025,11 @@ void CPPEditorWidget::finishHighlightSymbolUsages()
else if (m_highlighter.isCanceled()) else if (m_highlighter.isCanceled())
return; // aborted return; // aborted
CppHighlighter *highlighter = qobject_cast<CppHighlighter*>(baseTextDocument()->syntaxHighlighter()); TextEditor::SyntaxHighlighter *highlighter = baseTextDocument()->syntaxHighlighter();
Q_ASSERT(highlighter); QTC_ASSERT(highlighter, return);
QTextDocument *doc = document();
if (m_nextHighlightBlockNumber >= doc->blockCount())
return;
QTextBlock b = doc->findBlockByNumber(m_nextHighlightBlockNumber);
while (b.isValid()) { TextEditor::SemanticHighlighter::clearExtraAdditionalFormatsUntilEnd(
highlighter->setExtraAdditionalFormats(b, QList<QTextLayout::FormatRange>()); highlighter, m_highlighter);
b = b.next();
++m_nextHighlightBlockNumber;
}
} }
...@@ -1777,11 +1711,16 @@ void CPPEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) ...@@ -1777,11 +1711,16 @@ void CPPEditorWidget::setFontSettings(const TextEditor::FontSettings &fs)
m_occurrencesUnusedFormat.clearForeground(); m_occurrencesUnusedFormat.clearForeground();
m_occurrencesUnusedFormat.setToolTip(tr("Unused variable")); m_occurrencesUnusedFormat.setToolTip(tr("Unused variable"));
m_occurrenceRenameFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_RENAME)); m_occurrenceRenameFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_RENAME));
m_typeFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_TYPE)); m_semanticHighlightFormatMap[SemanticInfo::TypeUse] =
m_localFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_LOCAL)); fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_TYPE));
m_fieldFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_FIELD)); m_semanticHighlightFormatMap[SemanticInfo::LocalUse] =
m_staticFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_STATIC)); fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_LOCAL));
m_virtualMethodFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_VIRTUAL_METHOD)); m_semanticHighlightFormatMap[SemanticInfo::FieldUse] =
fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_FIELD));
m_semanticHighlightFormatMap[SemanticInfo::StaticUse] =
fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_STATIC));
m_semanticHighlightFormatMap[SemanticInfo::VirtualMethodUse] =
fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_VIRTUAL_METHOD));
m_keywordFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_KEYWORD)); m_keywordFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_KEYWORD));
// only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link // only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
...@@ -1921,7 +1860,6 @@ void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo) ...@@ -1921,7 +1860,6 @@ void CPPEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
CheckSymbols::Future f = CheckSymbols::go(semanticInfo.doc, context); CheckSymbols::Future f = CheckSymbols::go(semanticInfo.doc, context);
m_highlighter = f; m_highlighter = f;
m_highlightRevision = semanticInfo.revision; m_highlightRevision = semanticInfo.revision;
m_nextHighlightBlockNumber = 0;
m_highlightWatcher.setFuture(m_highlighter); m_highlightWatcher.setFuture(m_highlighter);
} }
} }
......
...@@ -297,12 +297,8 @@ private: ...@@ -297,12 +297,8 @@ private:
QTextCharFormat m_occurrencesFormat; QTextCharFormat m_occurrencesFormat;
QTextCharFormat m_occurrencesUnusedFormat; QTextCharFormat m_occurrencesUnusedFormat;
QTextCharFormat m_occurrenceRenameFormat; QTextCharFormat m_occurrenceRenameFormat;
QTextCharFormat m_typeFormat; QHash<int, QTextCharFormat> m_semanticHighlightFormatMap;
QTextCharFormat m_localFormat;
QTextCharFormat m_fieldFormat;
QTextCharFormat m_staticFormat;
QTextCharFormat m_keywordFormat; QTextCharFormat m_keywordFormat;
QTextCharFormat m_virtualMethodFormat;
QList<QTextEdit::ExtraSelection> m_renameSelections; QList<QTextEdit::ExtraSelection> m_renameSelections;
int m_currentRenameSelection; int m_currentRenameSelection;
...@@ -320,7 +316,6 @@ private: ...@@ -320,7 +316,6 @@ private:
QFuture<SemanticInfo::Use> m_highlighter; QFuture<SemanticInfo::Use> m_highlighter;
QFutureWatcher<SemanticInfo::Use> m_highlightWatcher; QFutureWatcher<SemanticInfo::Use> m_highlightWatcher;
unsigned m_highlightRevision; // the editor revision that requested the highlight unsigned m_highlightRevision; // the editor revision that requested the highlight
int m_nextHighlightBlockNumber;
QFuture<QList<int> > m_references; QFuture<QList<int> > m_references;
QFutureWatcher<QList<int> > m_referencesWatcher; QFutureWatcher<QList<int> > m_referencesWatcher;
......
...@@ -99,7 +99,7 @@ protected: ...@@ -99,7 +99,7 @@ protected:
const Identifier *id = member->identifier(); const Identifier *id = member->identifier();
unsigned line, column; unsigned line, column;
getTokenStartPosition(member->sourceLocation(), &line, &column); getTokenStartPosition(member->sourceLocation(), &line, &column);
localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local)); localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
} }
} }
} }
...@@ -117,7 +117,7 @@ protected: ...@@ -117,7 +117,7 @@ protected:
else if (!member->isGenerated() && (member->sourceLocation() < ast->firstToken() || member->enclosingScope()->isFunction())) { else if (!member->isGenerated() && (member->sourceLocation() < ast->firstToken() || member->enclosingScope()->isFunction())) {
unsigned line, column; unsigned line, column;
getTokenStartPosition(simpleName->identifier_token, &line, &column); getTokenStartPosition(simpleName->identifier_token, &line, &column);
localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local)); localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::LocalUse));
return false; return false;
} }
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <cplusplus/CppDocument.h> #include <cplusplus/CppDocument.h>
#include <cplusplus/LookupContext.h> #include <cplusplus/LookupContext.h>
#include <texteditor/semantichighlighter.h>
#include <QtCore/QHash> #include <QtCore/QHash>
namespace CppEditor { namespace CppEditor {
...@@ -45,22 +46,13 @@ class CPPEditorWidget; ...@@ -45,22 +46,13 @@ class CPPEditorWidget;
class SemanticInfo class SemanticInfo
{ {
public: public:
struct Use { typedef TextEditor::SemanticHighlighter::Result Use;
unsigned line; enum UseKind {
unsigned column; TypeUse = 0,
unsigned length; LocalUse,
unsigned kind; FieldUse,
StaticUse,
enum Kind { VirtualMethodUse
Type = 0,
Local,
Field,
Static,
VirtualMethod
};
Use(unsigned line = 0, unsigned column = 0, unsigned length = 0, unsigned kind = Type)
: line(line), column(column), length(length), kind(kind) {}
}; };
typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap; typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "qmljsautocompleter.h" #include "qmljsautocompleter.h"
#include "qmljscompletionassist.h" #include "qmljscompletionassist.h"
#include "qmljsquickfixassist.h" #include "qmljsquickfixassist.h"
#include "qmljssemantichighlighter.h"
#include <qmljs/qmljsbind.h> #include <qmljs/qmljsbind.h>
#include <qmljs/qmljsevaluate.h> #include <qmljs/qmljsevaluate.h>
...@@ -658,7 +659,8 @@ QmlJSTextEditorWidget::QmlJSTextEditorWidget(QWidget *parent) : ...@@ -658,7 +659,8 @@ QmlJSTextEditorWidget::QmlJSTextEditorWidget(QWidget *parent) :
m_modelManager(0), m_modelManager(0),
m_contextPane(0), m_contextPane(0),
m_updateSelectedElements(false), m_updateSelectedElements(false),
m_findReferences(new FindReferences(this)) m_findReferences(new FindReferences(this)),
m_semanticHighlighter(new SemanticHighlighter(this))
{ {
qRegisterMetaType<QmlJSEditor::SemanticInfo>("QmlJSEditor::SemanticInfo"); qRegisterMetaType<QmlJSEditor::SemanticInfo>("QmlJSEditor::SemanticInfo");
...@@ -1218,6 +1220,8 @@ void QmlJSTextEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) ...@@ -1218,6 +1220,8 @@ void QmlJSTextEditorWidget::setFontSettings(const TextEditor::FontSettings &fs)
// only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link // only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
m_occurrencesFormat.clearForeground(); m_occurrencesFormat.clearForeground();
m_occurrenceRenameFormat.clearForeground(); m_occurrenceRenameFormat.clearForeground();
m_semanticHighlighter->updateFontSettings(fs);
} }
...@@ -1544,9 +1548,6 @@ void QmlJSTextEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo) ...@@ -1544,9 +1548,6 @@ void QmlJSTextEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo)
FindIdDeclarations updateIds; FindIdDeclarations updateIds;
m_semanticInfo.idLocations = updateIds(doc); m_semanticInfo.idLocations = updateIds(doc);
FindDeclarations findDeclarations;
m_semanticInfo.declarations = findDeclarations(doc->ast());
if (m_contextPane) { if (m_contextPane) {
Node *newNode = m_semanticInfo.declaringMemberNoProperties(position());