summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/builtinindexingsupport.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2012-11-23 11:47:39 +0100
committerErik Verbruggen <erik.verbruggen@digia.com>2012-11-26 14:07:35 +0100
commit271fb797cb77a39d59dc6930bd4dafea98a325bb (patch)
treea9a91ad373a7c130f3d0d132d1186ebe6173b05e /src/plugins/cpptools/builtinindexingsupport.cpp
parent65942d2d8d7bb5597c749c8653055cef96c54a7e (diff)
downloadqt-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.cpp216
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);
+}