diff --git a/src/plugins/cpptools/cppsemanticsearch.cpp b/src/plugins/cpptools/cppsemanticsearch.cpp index 526b5b2e46843c60898b06ec09996c4b203c613b..b86e963e073ca785b13b75bfe53fb7ae2e688bb4 100644 --- a/src/plugins/cpptools/cppsemanticsearch.cpp +++ b/src/plugins/cpptools/cppsemanticsearch.cpp @@ -112,6 +112,76 @@ protected: } }; +class SearchFunctionCall: public SemanticSearch +{ + QString _text; + QTextDocument::FindFlags _findFlags; + +public: + SearchFunctionCall(QFutureInterface<Core::Utils::FileSearchResult> &future, + Document::Ptr doc, Snapshot snapshot) + : SemanticSearch(future, doc, snapshot) + { } + + void setText(const QString &text) + { _text = text; } + + void setFindFlags(QTextDocument::FindFlags findFlags) + { _findFlags = findFlags; } + + virtual void run(AST *ast) + { accept(ast); } + +protected: + using ASTVisitor::visit; + + bool match(NameAST *name) + { + if (! name) + return false; + + else if (SimpleNameAST *simpleName = name->asSimpleName()) { + if (Identifier *id = identifier(simpleName->identifier_token)) { + Qt::CaseSensitivity cs = Qt::CaseInsensitive; + + if (_findFlags & QTextDocument::FindCaseSensitively) + cs = Qt::CaseSensitive; + + QString s = QString::fromUtf8(id->chars(), id->size()); + int index = s.indexOf(_text, 0, cs); + if (index != -1) { + reportResult(simpleName->identifier_token, index, _text.length()); + return true; + } + } + } + + else if (QualifiedNameAST *q = name->asQualifiedName()) { + return match(q->unqualified_name); + } + + return false; + } + + virtual bool visit(PostfixExpressionAST *ast) + { + NameAST *name = 0; + + if (ast->base_expression) + name = ast->base_expression->asName(); + + for (PostfixAST *fx = ast->postfix_expressions; fx; fx = fx->next) { + if (fx->asCall() != 0) { + match(name); + } else if (MemberAccessAST *mem = fx->asMemberAccess()) { + name = mem->member_name; + } + } + + return true; + } +}; + } // end of anonymous namespace SemanticSearch::SemanticSearch(QFutureInterface<Core::Utils::FileSearchResult> &future, @@ -174,10 +244,20 @@ SemanticSearch *SearchClassDeclarationsFactory::create(QFutureInterface<Core::Ut Document::Ptr doc, Snapshot snapshot) { - SearchClass *findClass = new SearchClass(future, doc, snapshot); - findClass->setText(_text); - findClass->setFindFlags(_findFlags); - return findClass; + SearchClass *search = new SearchClass(future, doc, snapshot); + search->setText(_text); + search->setFindFlags(_findFlags); + return search; +} + +SemanticSearch *SearchFunctionCallFactory::create(QFutureInterface<Core::Utils::FileSearchResult> &future, + Document::Ptr doc, + Snapshot snapshot) +{ + SearchFunctionCall *search = new SearchFunctionCall(future, doc, snapshot); + search->setText(_text); + search->setFindFlags(_findFlags); + return search; } static void semanticSearch_helper(QFutureInterface<Core::Utils::FileSearchResult> &future, diff --git a/src/plugins/cpptools/cppsemanticsearch.h b/src/plugins/cpptools/cppsemanticsearch.h index 7bd10b5cc3b0db132ad7b731a7b614e86bcef2ae..0ce1199ea113bc35d6e9a729b74fe177f9abfbc2 100644 --- a/src/plugins/cpptools/cppsemanticsearch.h +++ b/src/plugins/cpptools/cppsemanticsearch.h @@ -101,6 +101,20 @@ public: CPlusPlus::Snapshot snapshot); }; +class SearchFunctionCallFactory: public SemanticSearchFactory +{ + QString _text; + QTextDocument::FindFlags _findFlags; + +public: + SearchFunctionCallFactory(const QString &text, QTextDocument::FindFlags findFlags) + : _text(text), _findFlags(findFlags) + { } + + virtual SemanticSearch *create(QFutureInterface<Core::Utils::FileSearchResult> &future, + CPlusPlus::Document::Ptr doc, + CPlusPlus::Snapshot snapshot); +}; QFuture<Core::Utils::FileSearchResult> semanticSearch(QPointer<CppModelManager> modelManager, SemanticSearchFactory::Ptr factory); diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 62d77eb27d2df62bd74a32f42477236a73edf23a..dc8e6a66004ad1e946d5d7d525669dc8d971f318 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -127,6 +127,61 @@ void FindClassDeclarations::openEditor(const QString &fileName, int line, int co TextEditor::BaseTextEditor::openEditorAt(fileName, line, column); } +////// +FindFunctionCalls::FindFunctionCalls(CppModelManager *modelManager) + : _modelManager(modelManager), + _resultWindow(ExtensionSystem::PluginManager::instance()->getObject<Find::SearchResultWindow>()) +{ + m_watcher.setPendingResultsLimit(1); + connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(displayResult(int))); + connect(&m_watcher, SIGNAL(finished()), this, SLOT(searchFinished())); +} + +void FindFunctionCalls::findAll(const QString &text, QTextDocument::FindFlags findFlags) +{ + _resultWindow->clearContents(); + _resultWindow->popup(true); + + Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); + + SemanticSearchFactory::Ptr factory(new SearchFunctionCallFactory(text, findFlags)); + + QFuture<Core::Utils::FileSearchResult> result = semanticSearch(_modelManager, factory); + + m_watcher.setFuture(result); + + Core::FutureProgress *progress = progressManager->addTask(result, tr("Search functions"), + CppTools::Constants::TASK_INDEX, + Core::ProgressManager::CloseOnSuccess); + + connect(progress, SIGNAL(clicked()), _resultWindow, SLOT(popup())); +} + +void FindFunctionCalls::displayResult(int index) +{ + Core::Utils::FileSearchResult result = m_watcher.future().resultAt(index); + Find::ResultWindowItem *item = _resultWindow->addResult(result.fileName, + result.lineNumber, + result.matchingLine, + result.matchStart, + result.matchLength); + if (item) + connect(item, SIGNAL(activated(const QString&,int,int)), + this, SLOT(openEditor(const QString&,int,int))); +} + +void FindFunctionCalls::searchFinished() +{ + emit changed(); +} + +void FindFunctionCalls::openEditor(const QString &fileName, int line, int column) +{ + TextEditor::BaseTextEditor::openEditorAt(fileName, line, column); +} + + + CppToolsPlugin::CppToolsPlugin() : m_context(-1), m_modelManager(0), @@ -167,6 +222,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error) addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings)); addAutoReleasedObject(new FindClassDeclarations(m_modelManager)); + addAutoReleasedObject(new FindFunctionCalls(m_modelManager)); // Menus Core::ActionContainer *mtools = am->actionContainer(Core::Constants::M_TOOLS); diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index eb3380f1fa912d7228368dc63472a9e168596724..73f127e54c131657ea88d8af48796ea94f8662f2 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -86,6 +86,30 @@ private: QFutureWatcher<Core::Utils::FileSearchResult> m_watcher; }; +class FindFunctionCalls: public Find::IFindFilter // ### share code with FindClassDeclarations +{ + Q_OBJECT + +public: + FindFunctionCalls(CppModelManager *modelManager); + + // Find::IFindFilter + virtual QString id() const { return QLatin1String("CppTools.Find.FunctionCalls"); } + virtual QString name() const { return tr("Function calls"); } + virtual bool isEnabled() const { return true; } + virtual QKeySequence defaultShortcut() const { return QKeySequence(); } + virtual void findAll(const QString &txt, QTextDocument::FindFlags findFlags); + +protected Q_SLOTS: + void displayResult(int); + void searchFinished(); + void openEditor(const QString&, int, int); + +private: + QPointer<CppModelManager> _modelManager; + Find::SearchResultWindow *_resultWindow; + QFutureWatcher<Core::Utils::FileSearchResult> m_watcher; +}; class CppToolsPlugin : public ExtensionSystem::IPlugin {