forked from qt-creator/qt-creator
QmlJS: Release the same documents we keep before
When rescanning imports we generally get a new version of the parent document. When replacing the cached documents we want to release the old ones, not the new ones. Failing to do so leads to types disappearing from the QML code model and to leaking memory. Task-number: QTCREATORBUG-17175 Change-Id: I3994444ac0a6cd87f9d9d0b47ab3d6015660e416 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@theqtcompany.com>
This commit is contained in:
@@ -1300,7 +1300,7 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||
interface.setProgressValue(0);
|
||||
|
||||
CppDataHash newData;
|
||||
QHash<QString, QStringList> newDeclarations;
|
||||
QHash<QString, QList<CPlusPlus::Document::Ptr> > newDeclarations;
|
||||
{
|
||||
QMutexLocker locker(&qmlModelManager->m_cppDataMutex);
|
||||
newData = qmlModelManager->m_cppDataHash;
|
||||
@@ -1321,33 +1321,36 @@ void ModelManagerInterface::updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||
const QString fileName = doc->fileName();
|
||||
if (!scan) {
|
||||
hasNewInfo = newData.remove(fileName) > 0 || hasNewInfo;
|
||||
foreach (const QString &file, newDeclarations[fileName]) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.document(file);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
finder(doc);
|
||||
hasNewInfo = rescanExports(file, finder, newData) || hasNewInfo;
|
||||
foreach (const CPlusPlus::Document::Ptr &savedDoc, newDeclarations.value(fileName)) {
|
||||
finder(savedDoc);
|
||||
hasNewInfo = rescanExports(savedDoc->fileName(), finder, newData) || hasNewInfo;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto it = newDeclarations.begin(), end = newDeclarations.end(); it != end;) {
|
||||
if (it->removeOne(fileName)) {
|
||||
doc->releaseSourceAndAST();
|
||||
if (it->isEmpty()) {
|
||||
it = newDeclarations.erase(it);
|
||||
continue;
|
||||
for (auto docIt = it->begin(), endDocIt = it->end(); docIt != endDocIt;) {
|
||||
CPlusPlus::Document::Ptr &savedDoc = *docIt;
|
||||
if (savedDoc->fileName() == fileName) {
|
||||
savedDoc->releaseSourceAndAST();
|
||||
it->erase(docIt);
|
||||
break;
|
||||
} else {
|
||||
++docIt;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
if (it->isEmpty())
|
||||
it = newDeclarations.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
foreach (const QString &declarationFile, finder(doc)) {
|
||||
newDeclarations[declarationFile].append(fileName);
|
||||
newDeclarations[declarationFile].append(doc);
|
||||
doc->keepSourceAndAST(); // keep for later reparsing when dependent doc changes
|
||||
}
|
||||
|
||||
hasNewInfo = rescanExports(doc->fileName(), finder, newData) || hasNewInfo;
|
||||
hasNewInfo = rescanExports(fileName, finder, newData) || hasNewInfo;
|
||||
doc->releaseSourceAndAST();
|
||||
}
|
||||
|
||||
|
@@ -275,7 +275,7 @@ private:
|
||||
QrcCache m_qrcCache;
|
||||
|
||||
CppDataHash m_cppDataHash;
|
||||
QHash<QString, QStringList> m_cppDeclarationFiles;
|
||||
QHash<QString, QList<CPlusPlus::Document::Ptr> > m_cppDeclarationFiles;
|
||||
mutable QMutex m_cppDataMutex;
|
||||
|
||||
// project integration
|
||||
|
Reference in New Issue
Block a user