aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilian Wolff <mail@milianw.de>2012-10-17 17:14:01 (GMT)
committerMilian Wolff <mail@milianw.de>2012-10-17 17:22:05 (GMT)
commit64746da896a4f1a200be95da31569512d699d799 (patch)
treed2d13f69bc4530cbf72646b995f7bb61532ad66e
parent06240d03957920b99d8dcce61f8c70e60b220c51 (diff)
Greatly reduce memory consumption by using IndexedString in the BackgroundParser.
IndexedString::str or ::toUrl do not leverage implicit sharing (see recently added unit test that shows that). Thus we end up duplicating the URLs in-memory when we add all project files to the BackgroundParser. Instead, we now leverage IndexedString which greatly reduces the memory consumption. In my test with two big projects (QtWebKit and QtBase from Qt 5) I see a drop of from about 815MB RSS down to about 550MB RSS. Furthermore this new API is also faster as we can safe quite a few conversions between KUrl and IndexedString. And the hasing of an IndexedString is also faster compared to a KUrl. The TestBackgroundparser::benchmark shows a speed increase of about 10%, i.e. ~1.9s vs ~2.1s. NOTE: This commit breaks the API/ABI and is not source compatible. When you port your code to this new API, I encourage you to review the callers. Most often you do not want to use KUrl anyways but an IndexedString. NOTE2: While writing this patch, I found a few more places where we could and should change our API to use IndexedString instead of KUrl to decrease the number of conversions.
-rw-r--r--language/backgroundparser/backgroundparser.cpp134
-rw-r--r--language/backgroundparser/backgroundparser.h38
-rw-r--r--language/backgroundparser/documentchangetracker.cpp2
-rw-r--r--language/backgroundparser/parseprojectjob.cpp24
-rw-r--r--language/backgroundparser/parseprojectjob.h8
-rw-r--r--language/backgroundparser/tests/test_backgroundparser.cpp21
-rw-r--r--language/backgroundparser/tests/test_backgroundparser.h8
-rw-r--r--language/codegen/documentchangeset.cpp23
-rw-r--r--language/duchain/duchain.cpp10
-rw-r--r--language/duchain/duchainutils.h2
-rw-r--r--shell/kross/xmltokross/duchainextractor.cpp2
-rw-r--r--shell/projectcontroller.cpp6
12 files changed, 148 insertions, 130 deletions
diff --git a/language/backgroundparser/backgroundparser.cpp b/language/backgroundparser/backgroundparser.cpp
index 417a8e4..aeb2fa2 100644
--- a/language/backgroundparser/backgroundparser.cpp
+++ b/language/backgroundparser/backgroundparser.cpp
@@ -61,6 +61,25 @@
const bool separateThreadForHighPriority = true;
+namespace {
+/**
+ * @return true if @p url is non-empty, valid and has a clean path, false otherwise.
+ */
+inline bool isValidURL(const KDevelop::IndexedString& url)
+{
+ if (url.isEmpty()) {
+ return false;
+ }
+ KUrl original = url.toUrl();
+ if (!original.isValid()) {
+ return false;
+ }
+ KUrl cleaned = original;
+ cleaned.cleanPath();
+ return original == cleaned;
+}
+}
+
namespace KDevelop
{
@@ -97,7 +116,7 @@ public:
m_weaver.finish();
// Release dequeued jobs
- QHashIterator<KUrl, ParseJob*> it = m_parseJobs;
+ QHashIterator<IndexedString, ParseJob*> it = m_parseJobs;
while (it.hasNext()) {
it.next();
delete it.value();
@@ -123,14 +142,14 @@ public:
}
bool done = false;
- for (QMap<int, QSet<KUrl> >::Iterator it1 = m_documentsForPriority.begin();
+ for (QMap<int, QSet<IndexedString> >::Iterator it1 = m_documentsForPriority.begin();
it1 != m_documentsForPriority.end(); ++it1 )
{
if(it1.key() > m_neededPriority)
break; //The priority is not good enough to be processed right now
- for(QSet<KUrl>::Iterator it = it1.value().begin(); it != it1.value().end();) {
+ for(QSet<IndexedString>::Iterator it = it1.value().begin(); it != it1.value().end();) {
//Only create parse-jobs for up to thread-count * 2 documents, so we don't fill the memory unnecessarily
if(m_parseJobs.count() >= m_threads+1 || (m_parseJobs.count() >= m_threads && !separateThreadForHighPriority) )
break;
@@ -156,7 +175,7 @@ public:
continue;
}
- kDebug(9505) << "creating parse-job" << *it << "new count of active parse-jobs:" << m_parseJobs.count() + 1;
+ kDebug(9505) << "creating parse-job" << it->toUrl() << "new count of active parse-jobs:" << m_parseJobs.count() + 1;
ParseJob* job = createParseJob(*it, parsePlan.features(), parsePlan.notifyWhenReady(), parsePlan.priority());
if(m_parseJobs.count() == m_threads+1 && !specialParseJob)
@@ -211,19 +230,21 @@ public:
}
}
- ParseJob* createParseJob(const KUrl& url, TopDUContext::Features features, const QList<QWeakPointer<QObject> >& notifyWhenReady, int priority = 0)
+ ParseJob* createParseJob(const IndexedString& url, TopDUContext::Features features, const QList<QWeakPointer<QObject> >& notifyWhenReady, int priority = 0)
{
- QList<ILanguage*> languages = m_languageController->languagesForUrl(url);
+ ///FIXME: use IndexedString in the other APIs as well! Esp. for createParseJob!
+ KUrl kUrl = url.toUrl();
+ QList<ILanguage*> languages = m_languageController->languagesForUrl(kUrl);
foreach (ILanguage* language, languages) {
if(!language) {
- kWarning() << "got zero language for" << url;
+ kWarning() << "got zero language for" << kUrl;
continue;
}
if(!language->languageSupport()) {
kWarning() << "language has no language support assigned:" << language->name();
continue;
}
- ParseJob* job = language->languageSupport()->createParseJob(url);
+ ParseJob* job = language->languageSupport()->createParseJob(kUrl);
if (!job) {
continue; // Language part did not produce a valid ParseJob.
}
@@ -248,15 +269,15 @@ public:
}
if(languages.isEmpty())
- kDebug() << "found no languages for url" << url;
+ kDebug() << "found no languages for url" << kUrl;
else
- kDebug() << "could not create parse-job for url" << url;
+ kDebug() << "could not create parse-job for url" << kUrl;
//Notify that we failed
typedef QWeakPointer<QObject> Notify;
foreach(const Notify& n, notifyWhenReady)
if(n)
- QMetaObject::invokeMethod(n.data(), "updateReady", Qt::QueuedConnection, Q_ARG(KDevelop::IndexedString, IndexedString(url)), Q_ARG(KDevelop::ReferencedTopDUContext, ReferencedTopDUContext()));
+ QMetaObject::invokeMethod(n.data(), "updateReady", Qt::QueuedConnection, Q_ARG(KDevelop::IndexedString, url), Q_ARG(KDevelop::ReferencedTopDUContext, ReferencedTopDUContext()));
return 0;
}
@@ -378,11 +399,11 @@ config.readEntry(entry, oldConfig.readEntry(entry, default))
}
};
// A list of documents that are planned to be parsed, and their priority
- QHash<KUrl, DocumentParsePlan > m_documents;
+ QHash<IndexedString, DocumentParsePlan > m_documents;
// The documents ordered by priority
- QMap<int, QSet<KUrl> > m_documentsForPriority;
+ QMap<int, QSet<IndexedString> > m_documentsForPriority;
// Currently running parse jobs
- QHash<KUrl, ParseJob*> m_parseJobs;
+ QHash<IndexedString, ParseJob*> m_parseJobs;
// A change tracker for each managed document
QHash<IndexedString, DocumentChangeTracker*> m_managed;
// The url for each managed document. Those may temporarily differ from the real url.
@@ -444,7 +465,7 @@ void BackgroundParser::clear(QObject* parent)
{
QMutexLocker lock(&d->m_mutex);
- QHashIterator<KUrl, ParseJob*> it = d->m_parseJobs;
+ QHashIterator<IndexedString, ParseJob*> it = d->m_parseJobs;
while (it.hasNext()) {
it.next();
if (it.value()->parent() == parent) {
@@ -468,7 +489,7 @@ void BackgroundParser::parseProgress(KDevelop::ParseJob* job, float value, QStri
void BackgroundParser::revertAllRequests(QObject* notifyWhenReady)
{
QMutexLocker lock(&d->m_mutex);
- for(QHash<KUrl, BackgroundParserPrivate::DocumentParsePlan >::iterator it = d->m_documents.begin(); it != d->m_documents.end(); ) {
+ for(QHash<IndexedString, BackgroundParserPrivate::DocumentParsePlan >::iterator it = d->m_documents.begin(); it != d->m_documents.end(); ) {
d->m_documentsForPriority[it.value().priority()].remove(it.key());
@@ -492,33 +513,30 @@ void BackgroundParser::revertAllRequests(QObject* notifyWhenReady)
}
}
-void BackgroundParser::addDocument(const KUrl& url, TopDUContext::Features features, int priority, QObject* notifyWhenReady, ParseJob::SequentialProcessingFlags flags)
+void BackgroundParser::addDocument(const IndexedString& url, TopDUContext::Features features, int priority, QObject* notifyWhenReady, ParseJob::SequentialProcessingFlags flags)
{
-// kDebug(9505) << "BackgroundParser::addDocument" << url.prettyUrl();
- KUrl cleanedUrl = url;
- cleanedUrl.cleanPath();
+// kDebug(9505) << "BackgroundParser::addDocument" << url.toUrl();
+ Q_ASSERT(isValidURL(url));
QMutexLocker lock(&d->m_mutex);
{
- Q_ASSERT(cleanedUrl.isValid());
-
BackgroundParserPrivate::DocumentParseTarget target;
target.priority = priority;
target.features = features;
target.sequentialProcessingFlags = flags;
target.notifyWhenReady = QWeakPointer<QObject>(notifyWhenReady);
- QHash<KUrl, BackgroundParserPrivate::DocumentParsePlan>::iterator it = d->m_documents.find(cleanedUrl);
+ QHash<IndexedString, BackgroundParserPrivate::DocumentParsePlan>::iterator it = d->m_documents.find(url);
if (it != d->m_documents.end()) {
//Update the stored plan
- d->m_documentsForPriority[it.value().priority()].remove(cleanedUrl);
+ d->m_documentsForPriority[it.value().priority()].remove(url);
it.value().targets << target;
- d->m_documentsForPriority[it.value().priority()].insert(cleanedUrl);
+ d->m_documentsForPriority[it.value().priority()].insert(url);
}else{
// kDebug(9505) << "BackgroundParser::addDocument: queuing" << cleanedUrl;
- d->m_documents[cleanedUrl].targets << target;
- d->m_documentsForPriority[d->m_documents[cleanedUrl].priority()].insert(cleanedUrl);
+ d->m_documents[url].targets << target;
+ d->m_documentsForPriority[d->m_documents[url].priority()].insert(url);
++d->m_maxParseJobs; //So the progress-bar waits for this document
}
@@ -526,22 +544,16 @@ void BackgroundParser::addDocument(const KUrl& url, TopDUContext::Features featu
}
}
-void BackgroundParser::addDocumentList(const KUrl::List &urls, TopDUContext::Features features, int priority)
+void BackgroundParser::removeDocument(const IndexedString& url, QObject* notifyWhenReady)
{
- foreach (const KUrl &url, urls)
- addDocument(url, features, priority);
-}
+ Q_ASSERT(isValidURL(url));
-void BackgroundParser::removeDocument(const KUrl &url, QObject* notifyWhenReady)
-{
QMutexLocker lock(&d->m_mutex);
- Q_ASSERT(url.isValid());
-
if(d->m_documents.contains(url)) {
-
+
d->m_documentsForPriority[d->m_documents[url].priority()].remove(url);
-
+
foreach(const BackgroundParserPrivate::DocumentParseTarget& target, d->m_documents[url].targets) {
if(target.notifyWhenReady.data() == notifyWhenReady) {
d->m_documents[url].targets.removeAll(target);
@@ -578,11 +590,11 @@ void BackgroundParser::parseComplete(ThreadWeaver::Job* job)
{
{
QMutexLocker lock(&d->m_mutex);
-
- d->m_parseJobs.remove(parseJob->document().str());
-
+
+ d->m_parseJobs.remove(parseJob->document());
+
d->m_jobProgress.remove(parseJob);
-
+
++d->m_doneParseJobs;
updateProgressBar();
}
@@ -605,12 +617,16 @@ void BackgroundParser::enableProcessing()
setNeededPriority(WorstPriority);
}
-int BackgroundParser::priorityForDocument(const KUrl& url) const {
+int BackgroundParser::priorityForDocument(const IndexedString& url) const
+{
+ Q_ASSERT(isValidURL(url));
QMutexLocker lock(&d->m_mutex);
return d->m_documents[url].priority();
}
-bool BackgroundParser::isQueued(KUrl url) const {
+bool BackgroundParser::isQueued(const IndexedString& url) const
+{
+ Q_ASSERT(isValidURL(url));
QMutexLocker lock(&d->m_mutex);
return d->m_documents.contains(url);
}
@@ -664,15 +680,12 @@ ParserDependencyPolicy* BackgroundParser::dependencyPolicy() const
return &d->m_dependencyPolicy;
}
-ParseJob* BackgroundParser::parseJobForDocument(const KUrl& document) const
+ParseJob* BackgroundParser::parseJobForDocument(const IndexedString& document) const
{
- QMutexLocker lock(&d->m_mutex);
+ Q_ASSERT(isValidURL(document));
- if (d->m_parseJobs.contains(document)) {
- return d->m_parseJobs[document];
- }
-
- return 0;
+ QMutexLocker lock(&d->m_mutex);
+ return d->m_parseJobs.value(document, 0);
}
void BackgroundParser::setThreadCount(int threadCount)
@@ -705,8 +718,15 @@ QList< IndexedString > BackgroundParser::managedDocuments()
DocumentChangeTracker* BackgroundParser::trackerForUrl(const KDevelop::IndexedString& url) const
{
+ if (url.isEmpty()) {
+ // this happens e.g. when setting the final location of a problem that is not
+ // yet associated with a top ctx.
+ return 0;
+ }
+ Q_ASSERT(isValidURL(url));
+
QMutexLocker l(&d->m_mutex);
-
+
QHash< IndexedString, DocumentChangeTracker* >::iterator it = d->m_managed.find(url);
if(it != d->m_managed.end())
return *it;
@@ -714,22 +734,22 @@ DocumentChangeTracker* BackgroundParser::trackerForUrl(const KDevelop::IndexedSt
return 0;
}
-void BackgroundParser::documentClosed ( IDocument* document )
+void BackgroundParser::documentClosed(IDocument* document)
{
QMutexLocker l(&d->m_mutex);
-
+
if(document->textDocument())
{
KTextEditor::Document* textDocument = document->textDocument();
-
+
if(!d->m_managedTextDocumentUrls.contains(textDocument))
return; // Probably the document had an invalid url, and thus it wasn't added to the background parser
-
+
Q_ASSERT(d->m_managedTextDocumentUrls.contains(textDocument));
-
+
IndexedString url(d->m_managedTextDocumentUrls[textDocument]);
Q_ASSERT(d->m_managed.contains(url));
-
+
kDebug() << "removing" << url.str() << "from background parser";
delete d->m_managed[url];
d->m_managedTextDocumentUrls.remove(textDocument);
diff --git a/language/backgroundparser/backgroundparser.h b/language/backgroundparser/backgroundparser.h
index a1fe5c8..4c38d1a 100644
--- a/language/backgroundparser/backgroundparser.h
+++ b/language/backgroundparser/backgroundparser.h
@@ -29,8 +29,6 @@
#include <QtCore/QMutex>
#include <QtCore/QHash>
-#include <KDE/KUrl>
-
#include "../languageexport.h"
#include <interfaces/istatus.h>
#include <language/duchain/topducontext.h>
@@ -55,6 +53,12 @@ class ILanguageController;
class ParseJob;
class ParserDependencyPolicy;
+/**
+ * This class handles the creation of parse jobs for given file URLs.
+ *
+ * For performance reasons you must always use clean, canonical URLs. If you do not do that,
+ * issues might arise (and the debug build will assert).
+ */
class KDEVPLATFORMLANGUAGE_EXPORT BackgroundParser : public QObject, public IStatus
{
Q_OBJECT
@@ -72,7 +76,7 @@ public:
///There is an additional parsing-thread reserved for jobs with this and better priority, to improve responsiveness.
WorstPriority = 100000 ///Worst possible job-priority.
};
-
+
/**
* Abort or dequeue all current running jobs with the specified @p parent.
*/
@@ -86,7 +90,7 @@ public:
* unless you call in from your job's ThreadWeaver::Job::aboutToBeQueued()
* function.
*/
- Q_SCRIPTABLE ParseJob* parseJobForDocument(const KUrl& document) const;
+ Q_SCRIPTABLE ParseJob* parseJobForDocument(const IndexedString& document) const;
/**
* The dependency policy which applies to all jobs (it is applied automatically).
@@ -144,7 +148,7 @@ public Q_SLOTS:
* Suspends execution of the background parser
*/
void suspend();
-
+
/**
* Resumes execution of the background parser
*/
@@ -153,7 +157,7 @@ public Q_SLOTS:
///Reverts all requests that were made for the given notification-target.
///priorities and requested features will be reverted as well.
void revertAllRequests(QObject* notifyWhenReady);
-
+
/**
* Queues up the @p url to be parsed.
* @p features The minimum features that should be computed for this top-context
@@ -163,20 +167,14 @@ public Q_SLOTS:
* The notification is guaranteed to be called once for each call to addDocument. The given top-context
* may be invalid if the update failed.
*/
- void addDocument(const KUrl& url, TopDUContext::Features features = TopDUContext::VisibleDeclarationsAndContexts, int priority = 0, QObject* notifyWhenReady = 0, ParseJob::SequentialProcessingFlags flags = ParseJob::IgnoresSequentialProcessing);
-
- /**
- * Queues up the list of @p urls to be parsed.
- * @p features The minimum features that should be computed for these top-contexts
- * @p priority A value that manages the order of parsing. Documents with lowest priority are parsed first.
- */
- void addDocumentList(const KUrl::List& urls, TopDUContext::Features features = TopDUContext::VisibleDeclarationsAndContexts, int priority = 0);
+ void addDocument(const IndexedString& url, TopDUContext::Features features = TopDUContext::VisibleDeclarationsAndContexts, int priority = 0, QObject* notifyWhenReady = 0, ParseJob::SequentialProcessingFlags flags = ParseJob::IgnoresSequentialProcessing);
/**
* Removes the @p url that is registered for the given notification from the url.
- * @param notifyWhenReady Notifier the document was added with
+ *
+ * @param notifyWhenReady Notifier the document was added with.
*/
- void removeDocument(const KUrl& url, QObject* notifyWhenReady = 0);
+ void removeDocument(const IndexedString& url, QObject* notifyWhenReady = 0);
/**
* Forces the current queue to be parsed.
@@ -195,17 +193,17 @@ public Q_SLOTS:
void disableProcessing();
///Enables all processing of new jobs, equivalent to setNeededPriority(WorstPriority)
void enableProcessing();
-
+
///Returns true if the given url is queued for parsing
- bool isQueued(KUrl url) const;
+ bool isQueued(const IndexedString& url) const;
///Retrieve the current priority for the given URL.
///You need to check whether @param url is queued before calling this function.
- int priorityForDocument(const KUrl& url) const;
+ int priorityForDocument(const IndexedString& url) const;
///Returns the number of currently active or queued jobs
int queuedCount() const;
-
+
void documentClosed(KDevelop::IDocument*);
void documentLoaded(KDevelop::IDocument*);
void documentUrlChanged(KDevelop::IDocument*);
diff --git a/language/backgroundparser/documentchangetracker.cpp b/language/backgroundparser/documentchangetracker.cpp
index 8fb332c..2aab705 100644
--- a/language/backgroundparser/documentchangetracker.cpp
+++ b/language/backgroundparser/documentchangetracker.cpp
@@ -214,7 +214,7 @@ void DocumentChangeTracker::updateChangedRange( Range changed )
ModificationRevision::setEditorRevisionForFile(m_url, m_moving->revision());
if(needUpdate())
- ICore::self()->languageController()->backgroundParser()->addDocument(m_url.toUrl(), TopDUContext::AllDeclarationsContextsAndUses);
+ ICore::self()->languageController()->backgroundParser()->addDocument(m_url, TopDUContext::AllDeclarationsContextsAndUses);
}
void DocumentChangeTracker::textInserted( Document* document, Range range )
diff --git a/language/backgroundparser/parseprojectjob.cpp b/language/backgroundparser/parseprojectjob.cpp
index 1683ae3..0f4cfcb 100644
--- a/language/backgroundparser/parseprojectjob.cpp
+++ b/language/backgroundparser/parseprojectjob.cpp
@@ -1,6 +1,6 @@
/*
Copyright 2009 David Nolden <david.nolden.kdevelop@art-master.de>
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
@@ -35,20 +35,20 @@ bool ParseProjectJob::doKill() {
}
ParseProjectJob::~ParseProjectJob() {
- KDevelop::ICore::self()->languageController()->backgroundParser()->revertAllRequests(this);
+ ICore::self()->languageController()->backgroundParser()->revertAllRequests(this);
if(ICore::self()->runController()->currentJobs().contains(this))
ICore::self()->runController()->unregisterJob(this);
}
-ParseProjectJob::ParseProjectJob(KDevelop::IProject* project) {
+ParseProjectJob::ParseProjectJob(IProject* project) {
connect(project, SIGNAL(destroyed(QObject*)), SLOT(deleteNow()));
m_project = project;
m_updated = 0;
m_totalFiles = project->fileSet().size();
-
+
setCapabilities(Killable);
-
+
setObjectName(i18np("Process 1 file in %2","Process %1 files in %2", m_totalFiles, m_project->name()));
}
@@ -57,22 +57,22 @@ void ParseProjectJob::deleteNow() {
}
void ParseProjectJob::updateProgress() {
-
+
}
-void ParseProjectJob::updateReady(KDevelop::IndexedString url, KDevelop::ReferencedTopDUContext topContext) {
+void ParseProjectJob::updateReady(const IndexedString& url, ReferencedTopDUContext topContext) {
Q_UNUSED(url);
Q_UNUSED(topContext);
++m_updated;
if(m_updated % ((m_totalFiles / 100)+1) == 0)
updateProgress();
-
+
if(m_updated >= m_totalFiles)
deleteLater();
}
void ParseProjectJob::start() {
- if (KDevelop::ICore::self()->shuttingDown()) {
+ if (ICore::self()->shuttingDown()) {
return;
}
@@ -80,14 +80,14 @@ void ParseProjectJob::start() {
QSet< IndexedString > files = m_project->fileSet();
TopDUContext::Features processingLevel = files.size() < ICore::self()->languageController()->completionSettings()->minFilesForSimplifiedParsing() ?
- KDevelop::TopDUContext::VisibleDeclarationsAndContexts : KDevelop::TopDUContext::SimplifiedVisibleDeclarationsAndContexts;
+ TopDUContext::VisibleDeclarationsAndContexts : TopDUContext::SimplifiedVisibleDeclarationsAndContexts;
// prevent UI-lockup by processing events after some files
// esp. noticeable when dealing with huge projects
const int processAfter = 1000;
int processed = 0;
- foreach(const KDevelop::IndexedString& url, files) {
- KDevelop::ICore::self()->languageController()->backgroundParser()->addDocument( url.toUrl(), processingLevel, BackgroundParser::WorstPriority, this );
+ foreach(const IndexedString& url, files) {
+ ICore::self()->languageController()->backgroundParser()->addDocument( url, processingLevel, BackgroundParser::WorstPriority, this );
++processed;
if (processed == processAfter) {
QApplication::processEvents();
diff --git a/language/backgroundparser/parseprojectjob.h b/language/backgroundparser/parseprojectjob.h
index 6e4c40e..413ffe2 100644
--- a/language/backgroundparser/parseprojectjob.h
+++ b/language/backgroundparser/parseprojectjob.h
@@ -38,12 +38,12 @@ public:
virtual ~ParseProjectJob();
virtual void start();
virtual bool doKill();
-
+
private Q_SLOTS:
void deleteNow();
- void updateReady(KDevelop::IndexedString url, KDevelop::ReferencedTopDUContext topContext);
-
- private:
+ void updateReady(const KDevelop::IndexedString& url, KDevelop::ReferencedTopDUContext topContext);
+
+private:
int m_updated;
int m_totalFiles;
KDevelop::IProject* m_project;
diff --git a/language/backgroundparser/tests/test_backgroundparser.cpp b/language/backgroundparser/tests/test_backgroundparser.cpp
index dfbbae2..1c2dee9 100644
--- a/language/backgroundparser/tests/test_backgroundparser.cpp
+++ b/language/backgroundparser/tests/test_backgroundparser.cpp
@@ -75,11 +75,10 @@ void JobPlan::parseJobCreated(ParseJob* job)
TestParseJob* testJob = dynamic_cast<TestParseJob*>(job);
Q_ASSERT(testJob);
- const KUrl url = testJob->document().toUrl();
- kDebug() << "assigning propierties for created job" << url;
- testJob->duration_ms = jobForUrl(url).m_duration;
+ kDebug() << "assigning propierties for created job" << testJob->document().toUrl();
+ testJob->duration_ms = jobForUrl(testJob->document()).m_duration;
- m_createdJobs.append(url);
+ m_createdJobs.append(testJob->document());
}
bool JobPlan::runJobs(int timeoutMS)
@@ -106,7 +105,7 @@ bool JobPlan::runJobs(int timeoutMS)
// verify they're started in the right order
int currentBestPriority = BackgroundParser::BestPriority;
- foreach ( const KUrl& url, m_createdJobs ) {
+ foreach ( const IndexedString& url, m_createdJobs ) {
const JobPrototype p = jobForUrl(url);
QVERIFY_RETURN(p.m_priority >= currentBestPriority, false);
currentBestPriority = p.m_priority;
@@ -115,7 +114,7 @@ bool JobPlan::runJobs(int timeoutMS)
return true;
}
-JobPrototype JobPlan::jobForUrl(const KUrl& url)
+JobPrototype JobPlan::jobForUrl(const IndexedString& url)
{
foreach(const JobPrototype& job, m_jobs) {
if (job.m_url == url) {
@@ -129,8 +128,8 @@ void JobPlan::updateReady(const IndexedString& url, const ReferencedTopDUContext
{
kDebug() << "update ready on " << url.toUrl();
- const JobPrototype job = jobForUrl(url.toUrl());
- QVERIFY(job.m_url.isValid());
+ const JobPrototype job = jobForUrl(url);
+ QVERIFY(job.m_url.toUrl().isValid());
if (job.m_flags & ParseJob::RequiresSequentialProcessing) {
// ensure that all jobs that respect sequential processing
@@ -248,14 +247,14 @@ void TestBackgroundparser::benchmark()
{
const int jobs = 10000;
- QVector<KUrl> jobUrls;
+ QVector<IndexedString> jobUrls;
jobUrls.reserve(jobs);
for ( int i = 0; i < jobs; ++i ) {
- jobUrls << KUrl("test" + QString::number(i) + ".txt");
+ jobUrls << IndexedString("test" + QString::number(i) + ".txt");
}
QBENCHMARK {
- foreach ( const KUrl& url, jobUrls ) {
+ foreach ( const IndexedString& url, jobUrls ) {
ICore::self()->languageController()->backgroundParser()->addDocument(url);
}
diff --git a/language/backgroundparser/tests/test_backgroundparser.h b/language/backgroundparser/tests/test_backgroundparser.h
index f8e80ff..09ab8e9 100644
--- a/language/backgroundparser/tests/test_backgroundparser.h
+++ b/language/backgroundparser/tests/test_backgroundparser.h
@@ -49,7 +49,7 @@ public:
{
Q_ASSERT(url.isValid());
}
- KUrl m_url;
+ IndexedString m_url;
int m_priority;
int m_duration;
ParseJob::SequentialProcessingFlags m_flags;
@@ -72,7 +72,7 @@ public:
void clear();
- JobPrototype jobForUrl(const KUrl& url);
+ JobPrototype jobForUrl(const IndexedString& url);
private slots:
void updateReady(const KDevelop::IndexedString& url, const KDevelop::ReferencedTopDUContext& context);
@@ -80,8 +80,8 @@ private slots:
private:
QVector<JobPrototype> m_jobs;
- QVector<KUrl> m_finishedJobs;
- QVector<KUrl> m_createdJobs;
+ QVector<IndexedString> m_finishedJobs;
+ QVector<IndexedString> m_createdJobs;
};
class TestBackgroundparser : public QObject
diff --git a/language/codegen/documentchangeset.cpp b/language/codegen/documentchangeset.cpp
index 2c6f36f..630ddcd 100644
--- a/language/codegen/documentchangeset.cpp
+++ b/language/codegen/documentchangeset.cpp
@@ -432,28 +432,29 @@ void DocumentChangeSetPrivate::updateFiles()
if(updatePolicy != DocumentChangeSet::NoUpdate && ICore::self())
{
// The active document should be updated first, so that the user sees the results instantly
- if(ICore::self()->documentController()->activeDocument())
- ICore::self()->languageController()->backgroundParser()->addDocument(ICore::self()->documentController()->activeDocument()->url());
-
+ if(IDocument* activeDoc = ICore::self()->documentController()->activeDocument()) {
+ ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(activeDoc->url()));
+ }
+
// If there are currently open documents that now need an update, update them too
foreach(const IndexedString& doc, ICore::self()->languageController()->backgroundParser()->managedDocuments()) {
DUChainReadLocker lock(DUChain::lock());
TopDUContext* top = DUChainUtils::standardContextForUrl(doc.toUrl(), true);
if((top && top->parsingEnvironmentFile() && top->parsingEnvironmentFile()->needsUpdate()) || !top) {
lock.unlock();
- ICore::self()->languageController()->backgroundParser()->addDocument(doc.toUrl());
+ ICore::self()->languageController()->backgroundParser()->addDocument(doc);
}
}
-
+
// Eventually update _all_ affected files
foreach(const IndexedString &file, changes.keys())
{
- if(!file.toUrl().isValid()) {
- kWarning() << "Trying to apply changes to an invalid document";
- continue;
- }
-
- ICore::self()->languageController()->backgroundParser()->addDocument(file.toUrl());
+ if(!file.toUrl().isValid()) {
+ kWarning() << "Trying to apply changes to an invalid document";
+ continue;
+ }
+
+ ICore::self()->languageController()->backgroundParser()->addDocument(file);
}
}
}
diff --git a/language/duchain/duchain.cpp b/language/duchain/duchain.cpp
index cf95e02..851b344 100644
--- a/language/duchain/duchain.cpp
+++ b/language/duchain/duchain.cpp
@@ -1481,7 +1481,7 @@ void DUChain::documentActivated(KDevelop::IDocument* doc)
TopDUContext* ctx = DUChainUtils::standardContextForUrl(doc->url(), true);
if(ctx && ctx->parsingEnvironmentFile())
if(ctx->parsingEnvironmentFile()->needsUpdate())
- ICore::self()->languageController()->backgroundParser()->addDocument(doc->url());
+ ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(doc->url()));
}
void DUChain::documentClosed(IDocument* document)
@@ -1541,13 +1541,13 @@ void DUChain::documentLoadedPrepare(KDevelop::IDocument* doc)
}
if(needsUpdate || !(standardContext->features() & TopDUContext::AllDeclarationsContextsAndUses)) {
- ICore::self()->languageController()->backgroundParser()->addDocument(doc->url(), (TopDUContext::Features)(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdate));
+ ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(doc->url()), (TopDUContext::Features)(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdate));
return;
}
}
//Add for highlighting etc.
- ICore::self()->languageController()->backgroundParser()->addDocument(doc->url(), TopDUContext::AllDeclarationsContextsAndUses);
+ ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(doc->url()), TopDUContext::AllDeclarationsContextsAndUses);
}
void DUChain::documentRenamed(KDevelop::IDocument* doc)
@@ -1559,7 +1559,7 @@ void DUChain::documentRenamed(KDevelop::IDocument* doc)
///Maybe this happens when a file was deleted?
kWarning() << "Strange, url of renamed document is invalid!";
}else{
- ICore::self()->languageController()->backgroundParser()->addDocument(doc->url(), (TopDUContext::Features)(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdate));
+ ICore::self()->languageController()->backgroundParser()->addDocument(IndexedString(doc->url()), (TopDUContext::Features)(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdate));
}
}
@@ -1690,7 +1690,7 @@ void DUChain::updateContextForUrl(const IndexedString& document, TopDUContext::F
QMetaObject::invokeMethod(notifyReady, "updateReady", Qt::DirectConnection, Q_ARG(KDevelop::IndexedString, document), Q_ARG(KDevelop::ReferencedTopDUContext, ReferencedTopDUContext(standardContext)));
}else{
///Start a parse-job for the given document
- ICore::self()->languageController()->backgroundParser()->addDocument(document.toUrl(), minFeatures, priority, notifyReady);
+ ICore::self()->languageController()->backgroundParser()->addDocument(document, minFeatures, priority, notifyReady);
}
}
diff --git a/language/duchain/duchainutils.h b/language/duchain/duchainutils.h
index d3cc1af..de6b5f9 100644
--- a/language/duchain/duchainutils.h
+++ b/language/duchain/duchainutils.h
@@ -53,6 +53,8 @@ namespace DUChainUtils {
* If there is no language-plugin registered for the given url, it will just try to get any top-context for the file from the du-chain.
* NOTE: The DUChain needs to be read or write locked when you call this.
* @param proxyContext Whether the returned context should be a proxy context. When no proxy-context is found, a normal context is returned.
+ *
+ * FIXME: this should operate on IndexedString
*/
KDEVPLATFORMLANGUAGE_EXPORT KDevelop::TopDUContext* standardContextForUrl(const KUrl& url, bool preferProxyContext = false);
/**
diff --git a/shell/kross/xmltokross/duchainextractor.cpp b/shell/kross/xmltokross/duchainextractor.cpp
index 0a99a91..8a3626e 100644
--- a/shell/kross/xmltokross/duchainextractor.cpp
+++ b/shell/kross/xmltokross/duchainextractor.cpp
@@ -86,7 +86,7 @@ void DUChainExtractor::start(const KUrl& _input, const KUrl& builddir,
DumbProject* project = new DumbProject();
project->setManagerPlugin(m_manager);
Core::self()->projectControllerInternal()->addProject(project);
- Core::self()->languageController()->backgroundParser()->addDocument(input);
+ Core::self()->languageController()->backgroundParser()->addDocument(IndexedString(input));
}
void DUChainExtractor::parsingFinished(KDevelop::ParseJob* job)
diff --git a/shell/projectcontroller.cpp b/shell/projectcontroller.cpp
index b805edf..13afff0 100644
--- a/shell/projectcontroller.cpp
+++ b/shell/projectcontroller.cpp
@@ -767,18 +767,16 @@ void ProjectController::projectImportingFinished( IProject* project )
KJob* parseProjectJob = new KDevelop::ParseProjectJob(project);
ICore::self()->runController()->registerJob(parseProjectJob);
}
-
- KUrl::List parseList;
+
// Add all currently open files that belong to the project to the background-parser,
// since more information may be available for parsing them now(Like include-paths).
foreach(IDocument* document, Core::self()->documentController()->openDocuments())
{
if(!project->filesForUrl(document->url()).isEmpty())
{
- parseList.append(document->url());
+ Core::self()->languageController()->backgroundParser()->addDocument( IndexedString(document->url()), TopDUContext::AllDeclarationsContextsAndUses, 10 );
}
}
- Core::self()->languageController()->backgroundParser()->addDocumentList( parseList, KDevelop::TopDUContext::AllDeclarationsContextsAndUses, 10 );
}
// helper method for closeProject()