From 0481176ea7e9caa12e0e00dd7282c217c71852d6 Mon Sep 17 00:00:00 2001 From: Roberto Raggi <roberto.raggi@nokia.com> Date: Wed, 24 Jun 2009 16:40:30 +0200 Subject: [PATCH] Highlight the locals. --- src/libs/cplusplus/CppDocument.cpp | 14 +-- src/plugins/cppeditor/cppeditor.cpp | 146 ++++++++++++++++++++++- src/plugins/cppeditor/cppeditor.h | 2 + src/shared/cplusplus/TranslationUnit.cpp | 10 ++ src/shared/cplusplus/TranslationUnit.h | 8 ++ 5 files changed, 170 insertions(+), 10 deletions(-) diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 3f4e04066d5..ea6c0feb3a2 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -367,19 +367,17 @@ QByteArray Snapshot::preprocessedCode(const QString &source, const QString &file Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode, const QString &fileName) const { - if (Document::Ptr thisDocument = value(fileName)) { - FastPreprocessor pp(*this); - Document::Ptr newDoc = Document::create(fileName); + FastPreprocessor pp(*this); + Document::Ptr newDoc = Document::create(fileName); + if (Document::Ptr thisDocument = value(fileName)) { newDoc->_includes = thisDocument->_includes; newDoc->_definedMacros = thisDocument->_definedMacros; - - newDoc->setSource(preprocessedCode); - newDoc->parse(); - return newDoc; } - return Document::Ptr(); + newDoc->setSource(preprocessedCode); + newDoc->parse(); + return newDoc; } QSharedPointer<NamespaceBinding> Snapshot::globalNamespaceBinding(Document::Ptr doc) const diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index a8d4c83be2a..f3448474e3b 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -86,6 +86,10 @@ using namespace CPlusPlus; using namespace CppEditor::Internal; +enum { + UPDATE_METHOD_BOX_INTERVAL = 150 +}; + namespace { class OverviewTreeView : public QTreeView @@ -105,6 +109,93 @@ public: } }; +class FunctionDefinitionUnderCursor: protected ASTVisitor +{ + QTextCursor _textCursor; + unsigned _line; + unsigned _column; + FunctionDefinitionAST *_functionDefinition; + +public: + FunctionDefinitionUnderCursor(Control *control) + : ASTVisitor(control) + { } + + FunctionDefinitionAST *operator()(AST *ast, const QTextCursor &tc) + { + _functionDefinition = 0; + _textCursor = tc; + _line = tc.blockNumber() + 1; + _column = tc.columnNumber() + 1; + accept(ast); + return _functionDefinition; + } + +protected: + virtual bool preVisit(AST *ast) + { + if (_functionDefinition) + return false; + + else if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) { + unsigned startLine, startColumn; + unsigned endLine, endColumn; + getTokenStartPosition(def->firstToken(), &startLine, &startColumn); + getTokenEndPosition(def->lastToken() - 1, &endLine, &endColumn); + + if (_line > startLine || (_line == startLine && _column >= startColumn)) { + if (_line < endLine || (_line == endLine && _column < endColumn)) { + _functionDefinition = def; + return false; + } + } + } + + return true; + } + +}; + +class ProcessDeclarators: protected ASTVisitor +{ + QList<DeclaratorIdAST *> _declarators; + bool _visitFunctionDeclarator; + +public: + ProcessDeclarators(Control *control) + : ASTVisitor(control), _visitFunctionDeclarator(true) + { } + + QList<DeclaratorIdAST *> operator()(FunctionDefinitionAST *ast) + { + _declarators.clear(); + + if (ast) { + if (ast->declarator) { + _visitFunctionDeclarator = true; + accept(ast->declarator->postfix_declarators); + } + + _visitFunctionDeclarator = false; + accept(ast->function_body); + } + + return _declarators; + } + +protected: + using ASTVisitor::visit; + + virtual bool visit(FunctionDeclaratorAST *) + { return _visitFunctionDeclarator; } + + virtual bool visit(DeclaratorIdAST *ast) + { + _declarators.append(ast); + return true; + } +}; + class FindFunctionDefinitions: protected SymbolVisitor { Name *_declarationName; @@ -372,6 +463,11 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) connect(m_sortAction, SIGNAL(toggled(bool)), CppPlugin::instance(), SLOT(setSortedMethodOverview(bool))); m_methodCombo->addAction(m_sortAction); + m_updateMethodBoxTimer = new QTimer(this); + m_updateMethodBoxTimer->setSingleShot(true); + m_updateMethodBoxTimer->setInterval(UPDATE_METHOD_BOX_INTERVAL); + connect(m_updateMethodBoxTimer, SIGNAL(timeout()), this, SLOT(updateMethodBoxIndexNow())); + connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int))); connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex())); connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip())); @@ -486,7 +582,7 @@ void CPPEditor::onDocumentUpdated(Document::Ptr doc) m_overviewModel->rebuild(doc); OverviewTreeView *treeView = static_cast<OverviewTreeView *>(m_methodCombo->view()); treeView->sync(); - updateMethodBoxIndex(); + updateMethodBoxIndexNow(); } void CPPEditor::reformatDocument() @@ -552,7 +648,7 @@ void CPPEditor::setSortedMethodOverview(bool sort) bool block = m_sortAction->blockSignals(true); m_sortAction->setChecked(m_proxyModel->sortColumn() == 0); m_sortAction->blockSignals(block); - updateMethodBoxIndex(); + updateMethodBoxIndexNow(); } } @@ -563,6 +659,13 @@ bool CPPEditor::sortedMethodOverview() const void CPPEditor::updateMethodBoxIndex() { + m_updateMethodBoxTimer->start(UPDATE_METHOD_BOX_INTERVAL); +} + +void CPPEditor::updateMethodBoxIndexNow() +{ + m_updateMethodBoxTimer->stop(); + int line = 0, column = 0; convertPosition(position(), &line, &column); @@ -586,6 +689,45 @@ void CPPEditor::updateMethodBoxIndex() (void) m_methodCombo->blockSignals(blocked); } + const Snapshot snapshot = m_modelManager->snapshot(); + const QByteArray preprocessedCode = snapshot.preprocessedCode(toPlainText(), file()->fileName()); + Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, file()->fileName()); + Control *control = doc->control(); + TranslationUnit *translationUnit = doc->translationUnit(); + AST *ast = translationUnit->ast(); + + FunctionDefinitionUnderCursor functionDefinitionUnderCursor(control); + FunctionDefinitionAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, textCursor()); + + QTextCharFormat format; + format.setUnderlineColor(Qt::darkGray); + format.setUnderlineStyle(QTextCharFormat::DashUnderline); + ProcessDeclarators processDeclarators(control); + const QList<DeclaratorIdAST *> declarators = processDeclarators(currentFunctionDefinition); + foreach (DeclaratorIdAST *declarator, declarators) { + bool generated = false; + for (unsigned tk = declarator->firstToken(), end = declarator->lastToken(); tk != end; ++tk) { + if (translationUnit->tokenAt(tk).generated) { + generated = true; + break; + } + } + if (generated) + continue; + unsigned startLine, startColumn; + unsigned endLine, endColumn; + translationUnit->getTokenStartPosition(declarator->firstToken(), &startLine, &startColumn); + translationUnit->getTokenEndPosition(declarator->lastToken() - 1, &endLine, &endColumn); + QTextEdit::ExtraSelection sel; + sel.cursor = textCursor(); + sel.cursor.setPosition(document()->findBlockByNumber(startLine - 1).position() + startColumn - 1); + sel.cursor.setPosition(document()->findBlockByLineNumber(endLine - 1).position() + endColumn - 1, + QTextCursor::KeepAnchor); + sel.format = format; + selections.append(sel); + } + setExtraSelections(CodeSemanticsSelection, selections); + #ifdef QTCREATOR_WITH_ADVANCED_HIGHLIGHTER Snapshot snapshot = m_modelManager->snapshot(); Document::Ptr thisDocument = snapshot.value(file()->fileName()); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 9121ee07d00..5b4f03f6568 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -118,6 +118,7 @@ private slots: void updateFileName(); void jumpToMethod(int index); void updateMethodBoxIndex(); + void updateMethodBoxIndexNow(); void updateMethodBoxToolTip(); void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void reformatDocument(); @@ -175,6 +176,7 @@ private: CPlusPlus::OverviewModel *m_overviewModel; QSortFilterProxyModel *m_proxyModel; QAction *m_sortAction; + QTimer *m_updateMethodBoxTimer; }; } // namespace Internal diff --git a/src/shared/cplusplus/TranslationUnit.cpp b/src/shared/cplusplus/TranslationUnit.cpp index d4039137a7a..db5fbe1c054 100644 --- a/src/shared/cplusplus/TranslationUnit.cpp +++ b/src/shared/cplusplus/TranslationUnit.cpp @@ -341,6 +341,16 @@ void TranslationUnit::getTokenPosition(unsigned index, StringLiteral **fileName) const { return getPosition(tokenAt(index).offset, line, column, fileName); } +void TranslationUnit::getTokenStartPosition(unsigned index, unsigned *line, + unsigned *column, + StringLiteral **fileName) const +{ return getPosition(tokenAt(index).begin(), line, column, fileName); } + +void TranslationUnit::getTokenEndPosition(unsigned index, unsigned *line, + unsigned *column, + StringLiteral **fileName) const +{ return getPosition(tokenAt(index).end(), line, column, fileName); } + void TranslationUnit::getPosition(unsigned tokenOffset, unsigned *line, unsigned *column, diff --git a/src/shared/cplusplus/TranslationUnit.h b/src/shared/cplusplus/TranslationUnit.h index 4bfd2018395..35f79480f02 100644 --- a/src/shared/cplusplus/TranslationUnit.h +++ b/src/shared/cplusplus/TranslationUnit.h @@ -127,6 +127,14 @@ public: void resetAST(); void release(); + void getTokenStartPosition(unsigned index, unsigned *line, + unsigned *column = 0, + StringLiteral **fileName = 0) const; + + void getTokenEndPosition(unsigned index, unsigned *line, + unsigned *column = 0, + StringLiteral **fileName = 0) const; + void getPosition(unsigned offset, unsigned *line, unsigned *column = 0, -- GitLab