diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2012-11-23 11:47:39 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2012-11-26 14:07:35 +0100 |
commit | 271fb797cb77a39d59dc6930bd4dafea98a325bb (patch) | |
tree | a9a91ad373a7c130f3d0d132d1186ebe6173b05e /src/plugins/cpptools/builtinindexingsupport.cpp | |
parent | 65942d2d8d7bb5597c749c8653055cef96c54a7e (diff) | |
download | qt-creator-271fb797cb77a39d59dc6930bd4dafea98a325bb.tar.gz |
Made symbol searching plug-able through indexing support.
The indexing support for the built-in code model is moved to its own
file. Symbol searching will now call for a searcher through that support
interface, which will create a fully configured and ready-to-go searcher
that can be started in the/a future.
Change-Id: Idc3ee1c7c789a69fa05ee1d42415313dcea94cf8
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Diffstat (limited to 'src/plugins/cpptools/builtinindexingsupport.cpp')
-rw-r--r-- | src/plugins/cpptools/builtinindexingsupport.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src/plugins/cpptools/builtinindexingsupport.cpp b/src/plugins/cpptools/builtinindexingsupport.cpp new file mode 100644 index 0000000000..eb03a799fb --- /dev/null +++ b/src/plugins/cpptools/builtinindexingsupport.cpp @@ -0,0 +1,216 @@ +#include "builtinindexingsupport.h" +#include "cppmodelmanager.h" +#include "searchsymbols.h" + +#include <coreplugin/icore.h> +#include <coreplugin/mimedatabase.h> +#include <coreplugin/progressmanager/progressmanager.h> +#include <utils/runextensions.h> + +#include <QCoreApplication> + +using namespace CppTools; +using namespace CppTools::Internal; + +namespace { + +static void parse(QFutureInterface<void> &future, + CppPreprocessor *preproc, + QStringList files, + const char *pp_configuration_file) +{ + if (files.isEmpty()) + return; + + const Core::MimeDatabase *mimeDb = Core::ICore::mimeDatabase(); + Core::MimeType cSourceTy = mimeDb->findByType(QLatin1String("text/x-csrc")); + Core::MimeType cppSourceTy = mimeDb->findByType(QLatin1String("text/x-c++src")); + Core::MimeType mSourceTy = mimeDb->findByType(QLatin1String("text/x-objcsrc")); + + QStringList sources; + QStringList headers; + + QStringList suffixes = cSourceTy.suffixes(); + suffixes += cppSourceTy.suffixes(); + suffixes += mSourceTy.suffixes(); + + foreach (const QString &file, files) { + QFileInfo info(file); + + preproc->snapshot.remove(file); + + if (suffixes.contains(info.suffix())) + sources.append(file); + else + headers.append(file); + } + + const int sourceCount = sources.size(); + files = sources; + files += headers; + + preproc->setTodo(files); + + future.setProgressRange(0, files.size()); + + QString conf = QLatin1String(pp_configuration_file); + + bool processingHeaders = false; + + for (int i = 0; i < files.size(); ++i) { + if (future.isPaused()) + future.waitForResume(); + + if (future.isCanceled()) + break; + + const QString fileName = files.at(i); + + const bool isSourceFile = i < sourceCount; + if (isSourceFile) + (void) preproc->run(conf); + + else if (! processingHeaders) { + (void) preproc->run(conf); + + processingHeaders = true; + } + + preproc->run(fileName); + + future.setProgressValue(files.size() - preproc->todo().size()); + + if (isSourceFile) + preproc->resetEnvironment(); + } + + future.setProgressValue(files.size()); + preproc->modelManager()->finishedRefreshingSourceFiles(files); + + delete preproc; +} + +class BuiltinSymbolSearcher: public SymbolSearcher +{ +public: + BuiltinSymbolSearcher(const CPlusPlus::Snapshot &snapshot, + Parameters parameters, QSet<QString> fileNames) + : m_snapshot(snapshot) + , m_parameters(parameters) + , m_fileNames(fileNames) + {} + + ~BuiltinSymbolSearcher() + {} + + void runSearch(QFutureInterface<Find::SearchResultItem> &future) + { + future.setProgressRange(0, m_snapshot.size()); + future.setProgressValue(0); + int progress = 0; + + SearchSymbols search; + search.setSymbolsToSearchFor(m_parameters.types); + search.setSeparateScope(true); + CPlusPlus::Snapshot::const_iterator it = m_snapshot.begin(); + + QString findString = (m_parameters.flags & Find::FindRegularExpression + ? m_parameters.text : QRegExp::escape(m_parameters.text)); + if (m_parameters.flags & Find::FindWholeWords) + findString = QString::fromLatin1("\\b%1\\b").arg(findString); + QRegExp matcher(findString, (m_parameters.flags & Find::FindCaseSensitively + ? Qt::CaseSensitive : Qt::CaseInsensitive)); + while (it != m_snapshot.end()) { + if (future.isPaused()) + future.waitForResume(); + if (future.isCanceled()) + break; + if (m_fileNames.isEmpty() || m_fileNames.contains(it.value()->fileName())) { + QVector<Find::SearchResultItem> resultItems; + QList<ModelItemInfo> modelInfos = search(it.value()); + foreach (const ModelItemInfo &info, modelInfos) { + int index = matcher.indexIn(info.symbolName); + if (index != -1) { + QStringList path = info.fullyQualifiedName.mid(0, + info.fullyQualifiedName.size() - 1); + Find::SearchResultItem item; + item.path = path; + item.text = info.symbolName; + item.textMarkPos = -1; + item.textMarkLength = 0; + item.icon = info.icon; + item.lineNumber = -1; + item.userData = qVariantFromValue(info); + resultItems << item; + } + } + if (!resultItems.isEmpty()) + future.reportResults(resultItems); + } + ++it; + ++progress; + future.setProgressValue(progress); + } + if (future.isPaused()) + future.waitForResume(); + } + +private: + const CPlusPlus::Snapshot m_snapshot; + const Parameters m_parameters; + const QSet<QString> m_fileNames; +}; + +} // anonymous namespace + +BuiltinIndexingSupport::BuiltinIndexingSupport(const char *pp_configuration_file) + : m_pp_configuration_file(pp_configuration_file) + , m_revision(0) +{ + m_synchronizer.setCancelOnWait(true); + m_dumpFileNameWhileParsing = !qgetenv("QTCREATOR_DUMP_FILENAME_WHILE_PARSING").isNull(); +} + +BuiltinIndexingSupport::~BuiltinIndexingSupport() +{} + +QFuture<void> BuiltinIndexingSupport::refreshSourceFiles(const QStringList &sourceFiles) +{ + CppModelManager *mgr = CppModelManager::instance(); + const WorkingCopy workingCopy = mgr->workingCopy(); + + CppPreprocessor *preproc = new CppPreprocessor(mgr, m_dumpFileNameWhileParsing); + preproc->setRevision(++m_revision); + preproc->setProjectFiles(mgr->projectFiles()); + preproc->setIncludePaths(mgr->includePaths()); + preproc->setFrameworkPaths(mgr->frameworkPaths()); + preproc->setWorkingCopy(workingCopy); + + QFuture<void> result = QtConcurrent::run(&parse, preproc, sourceFiles, m_pp_configuration_file); + + if (m_synchronizer.futures().size() > 10) { + QList<QFuture<void> > futures = m_synchronizer.futures(); + + m_synchronizer.clearFutures(); + + foreach (const QFuture<void> &future, futures) { + if (! (future.isFinished() || future.isCanceled())) + m_synchronizer.addFuture(future); + } + } + + m_synchronizer.addFuture(result); + + if (sourceFiles.count() > 1) { + Core::ICore::progressManager()->addTask(result, + QCoreApplication::translate("IndexingSupport", "Parsing"), + QLatin1String(CppTools::Constants::TASK_INDEX)); + } + + return result; +} + +SymbolSearcher *BuiltinIndexingSupport::createSymbolSearcher(SymbolSearcher::Parameters parameters, QSet<QString> fileNames) +{ + return new BuiltinSymbolSearcher(CppModelManager::instance()->snapshot(), parameters, fileNames); +} |