forked from qt-creator/qt-creator
C++ editor: Remove scanning/caching of includes
With the completion now in a separate thread this should no longer be necessary. Reviewed-by: Roberto Raggi
This commit is contained in:
@@ -1156,20 +1156,22 @@ bool CppCompletionAssistProcessor::completeInclude(const QTextCursor &cursor)
|
||||
}
|
||||
|
||||
// Make completion for all relevant includes
|
||||
CppModelManagerInterface *manager = CppModelManagerInterface::instance();
|
||||
QStringList includePaths = m_interface->includePaths();
|
||||
const QString ¤tFilePath = QFileInfo(m_interface->file()->fileName()).path();
|
||||
if (!includePaths.contains(currentFilePath))
|
||||
includePaths.append(currentFilePath);
|
||||
|
||||
const Core::MimeType mimeType =
|
||||
Core::ICore::instance()->mimeDatabase()->findByType(QLatin1String("text/x-c++hdr"));
|
||||
const QStringList suffixes = mimeType.suffixes();
|
||||
|
||||
foreach (const QString &includePath, includePaths) {
|
||||
QString realPath = includePath;
|
||||
if (!directoryPrefix.isEmpty()) {
|
||||
realPath += QLatin1Char('/');
|
||||
realPath += directoryPrefix;
|
||||
}
|
||||
foreach (const QString &itemText, manager->includesInPath(realPath))
|
||||
addCompletionItem(itemText, m_icons.keywordIcon());
|
||||
completeInclude(realPath, suffixes);
|
||||
}
|
||||
|
||||
foreach (const QString &frameworkPath, m_interface->frameworkPaths()) {
|
||||
@@ -1179,13 +1181,29 @@ bool CppCompletionAssistProcessor::completeInclude(const QTextCursor &cursor)
|
||||
realPath += directoryPrefix;
|
||||
realPath += QLatin1String(".framework/Headers");
|
||||
}
|
||||
foreach (const QString &itemText, manager->includesInPath(realPath))
|
||||
addCompletionItem(itemText, m_icons.keywordIcon());
|
||||
completeInclude(realPath, suffixes);
|
||||
}
|
||||
|
||||
return !m_completions.isEmpty();
|
||||
}
|
||||
|
||||
void CppCompletionAssistProcessor::completeInclude(const QString &realPath,
|
||||
const QStringList &suffixes)
|
||||
{
|
||||
QDirIterator i(realPath, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
while (i.hasNext()) {
|
||||
const QString fileName = i.next();
|
||||
const QFileInfo fileInfo = i.fileInfo();
|
||||
const QString suffix = fileInfo.suffix();
|
||||
if (suffix.isEmpty() || suffixes.contains(suffix)) {
|
||||
QString text = fileName.mid(realPath.length() + 1);
|
||||
if (fileInfo.isDir())
|
||||
text += QLatin1Char('/');
|
||||
addCompletionItem(text, m_icons.keywordIcon());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCompletionAssistProcessor::completePreprocessor()
|
||||
{
|
||||
foreach (const QString &preprocessorCompletion, preprocessorCompletions)
|
||||
|
||||
@@ -97,6 +97,7 @@ private:
|
||||
|
||||
void completeObjCMsgSend(CPlusPlus::ClassOrNamespace *binding, bool staticClassAccess);
|
||||
bool completeInclude(const QTextCursor &cursor);
|
||||
void completeInclude(const QString &realPath, const QStringList &suffixes);
|
||||
void completePreprocessor();
|
||||
bool completeConstructorOrFunction(const QList<CPlusPlus::LookupItem> &results,
|
||||
int endOfExpression,
|
||||
|
||||
@@ -777,16 +777,6 @@ QByteArray CppModelManager::internalDefinedMacros() const
|
||||
return macros;
|
||||
}
|
||||
|
||||
void CppModelManager::setIncludesInPaths(const QMap<QString, QStringList> &includesInPaths)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
QMapIterator<QString, QStringList> i(includesInPaths);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
m_includesInPaths.insert(i.key(), i.value());
|
||||
}
|
||||
}
|
||||
|
||||
void CppModelManager::addEditorSupport(AbstractEditorSupport *editorSupport)
|
||||
{
|
||||
m_addtionalEditorSupport.insert(editorSupport);
|
||||
@@ -877,25 +867,6 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo)
|
||||
|
||||
m_projects.insert(pinfo.project, pinfo);
|
||||
m_dirty = true;
|
||||
|
||||
if (m_indexerEnabled) {
|
||||
QFuture<void> result = QtConcurrent::run(&CppModelManager::updateIncludesInPaths,
|
||||
this,
|
||||
pinfo.includePaths,
|
||||
pinfo.frameworkPaths,
|
||||
m_headerSuffixes);
|
||||
|
||||
if (pinfo.includePaths.size() > 1) {
|
||||
m_core->progressManager()->addTask(result, tr("Scanning"),
|
||||
CppTools::Constants::TASK_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList CppModelManager::includesInPath(const QString &path) const
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
return m_includesInPaths.value(path);
|
||||
}
|
||||
|
||||
QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles)
|
||||
@@ -1196,122 +1167,6 @@ void CppModelManager::onAboutToUnloadSession()
|
||||
GC();
|
||||
}
|
||||
|
||||
void CppModelManager::updateIncludesInPaths(QFutureInterface<void> &future,
|
||||
CppModelManager *manager,
|
||||
QStringList paths,
|
||||
QStringList frameworkPaths,
|
||||
QStringList suffixes)
|
||||
{
|
||||
QMap<QString, QStringList> entriesInPaths;
|
||||
typedef QPair<QString, QString> SymLink;
|
||||
typedef QList<SymLink> SymLinks;
|
||||
SymLinks symlinks;
|
||||
int processed = 0;
|
||||
|
||||
future.setProgressRange(0, paths.size());
|
||||
|
||||
static const int MAX_DEPTH = 3;
|
||||
QList<int> pathDepths;
|
||||
pathDepths.reserve(paths.size());
|
||||
for (int i = 0; i < paths.size(); ++i) {
|
||||
pathDepths.append(0);
|
||||
}
|
||||
|
||||
// Add framework header directories to path list
|
||||
QStringList frameworkFilter;
|
||||
frameworkFilter << QLatin1String("*.framework");
|
||||
QStringListIterator fwPathIt(frameworkPaths);
|
||||
while (fwPathIt.hasNext()) {
|
||||
const QString &fwPath = fwPathIt.next();
|
||||
QStringList entriesInFrameworkPath;
|
||||
const QStringList &frameworks = QDir(fwPath).entryList(frameworkFilter, QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
QStringListIterator fwIt(frameworks);
|
||||
while (fwIt.hasNext()) {
|
||||
QString framework = fwIt.next();
|
||||
paths.append(fwPath + QLatin1Char('/') + framework + QLatin1String("/Headers"));
|
||||
pathDepths.append(0);
|
||||
framework.chop(10); // remove the ".framework"
|
||||
entriesInFrameworkPath.append(framework + QLatin1Char('/'));
|
||||
}
|
||||
entriesInPaths.insert(fwPath, entriesInFrameworkPath);
|
||||
}
|
||||
|
||||
while (!paths.isEmpty()) {
|
||||
if (future.isPaused())
|
||||
future.waitForResume();
|
||||
|
||||
if (future.isCanceled())
|
||||
return;
|
||||
|
||||
const QString path = paths.takeFirst();
|
||||
const int depth = pathDepths.takeFirst();
|
||||
|
||||
// Skip non-existing paths
|
||||
if (!QFile::exists(path))
|
||||
continue;
|
||||
|
||||
// Skip already scanned paths
|
||||
if (entriesInPaths.contains(path))
|
||||
continue;
|
||||
|
||||
QStringList entries;
|
||||
|
||||
QDirIterator i(path, QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
while (i.hasNext()) {
|
||||
const QString fileName = i.next();
|
||||
const QFileInfo fileInfo = i.fileInfo();
|
||||
QString text = fileInfo.fileName();
|
||||
if (depth < MAX_DEPTH && fileInfo.isDir()) {
|
||||
text += QLatin1Char('/');
|
||||
|
||||
// Also scan subdirectory, but avoid endless recursion with symbolic links
|
||||
if (fileInfo.isSymLink()) {
|
||||
QString target = fileInfo.symLinkTarget();
|
||||
|
||||
// Don't add broken symlinks
|
||||
if (!QFileInfo(target).exists())
|
||||
continue;
|
||||
|
||||
QMap<QString, QStringList>::const_iterator result = entriesInPaths.find(target);
|
||||
if (result != entriesInPaths.constEnd()) {
|
||||
entriesInPaths.insert(fileName, result.value());
|
||||
} else {
|
||||
paths.append(target);
|
||||
pathDepths.append(depth + 1);
|
||||
symlinks.append(SymLink(fileName, target));
|
||||
}
|
||||
} else {
|
||||
paths.append(fileName);
|
||||
pathDepths.append(depth + 1);
|
||||
}
|
||||
entries.append(text);
|
||||
} else {
|
||||
const QString suffix = fileInfo.suffix();
|
||||
if (suffix.isEmpty() || suffixes.contains(suffix))
|
||||
entries.append(text);
|
||||
}
|
||||
}
|
||||
|
||||
entriesInPaths.insert(path, entries);
|
||||
|
||||
++processed;
|
||||
future.setProgressRange(0, processed + paths.size());
|
||||
future.setProgressValue(processed);
|
||||
}
|
||||
// link symlinks
|
||||
QListIterator<SymLink> it(symlinks);
|
||||
it.toBack();
|
||||
while (it.hasPrevious()) {
|
||||
SymLink v = it.previous();
|
||||
QMap<QString, QStringList>::const_iterator result = entriesInPaths.find(v.second);
|
||||
entriesInPaths.insert(v.first, result.value());
|
||||
}
|
||||
|
||||
manager->setIncludesInPaths(entriesInPaths);
|
||||
|
||||
future.reportFinished();
|
||||
}
|
||||
|
||||
void CppModelManager::parse(QFutureInterface<void> &future,
|
||||
CppPreprocessor *preproc,
|
||||
QStringList files)
|
||||
|
||||
@@ -100,8 +100,6 @@ public:
|
||||
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
|
||||
virtual void updateProjectInfo(const ProjectInfo &pinfo);
|
||||
|
||||
virtual QStringList includesInPath(const QString &path) const;
|
||||
|
||||
virtual CPlusPlus::Snapshot snapshot() const;
|
||||
virtual void GC();
|
||||
|
||||
@@ -132,9 +130,6 @@ public:
|
||||
|
||||
virtual QList<LanguageUtils::FakeMetaObject::ConstPtr> exportedQmlObjects(const CPlusPlus::Document::Ptr &doc) const;
|
||||
|
||||
void setHeaderSuffixes(const QStringList &suffixes)
|
||||
{ m_headerSuffixes = suffixes; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void projectPathChanged(const QString &projectPath);
|
||||
|
||||
@@ -187,14 +182,6 @@ private:
|
||||
QStringList internalFrameworkPaths() const;
|
||||
QByteArray internalDefinedMacros() const;
|
||||
|
||||
void setIncludesInPaths(const QMap<QString, QStringList> &includesInPaths);
|
||||
|
||||
static void updateIncludesInPaths(QFutureInterface<void> &future,
|
||||
CppModelManager *manager,
|
||||
QStringList paths,
|
||||
QStringList frameworkPaths,
|
||||
QStringList suffixes);
|
||||
|
||||
static void parse(QFutureInterface<void> &future,
|
||||
CppPreprocessor *preproc,
|
||||
QStringList files);
|
||||
@@ -210,9 +197,6 @@ private:
|
||||
QStringList m_frameworkPaths;
|
||||
QByteArray m_definedMacros;
|
||||
|
||||
QMap<QString, QStringList> m_includesInPaths;
|
||||
QStringList m_headerSuffixes;
|
||||
|
||||
// editor integration
|
||||
QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport;
|
||||
|
||||
|
||||
@@ -149,11 +149,6 @@ void CppToolsPlugin::extensionsInitialized()
|
||||
m_fileSettings->fromSettings(Core::ICore::instance()->settings());
|
||||
if (!m_fileSettings->applySuffixesToMimeDB())
|
||||
qWarning("Unable to apply cpp suffixes to mime database (cpp mime types not found).\n");
|
||||
|
||||
// Initialize header suffixes
|
||||
const Core::MimeDatabase *mimeDatabase = Core::ICore::instance()->mimeDatabase();
|
||||
const Core::MimeType mimeType = mimeDatabase->findByType(QLatin1String("text/x-c++hdr"));
|
||||
m_modelManager->setHeaderSuffixes(mimeType.suffixes());
|
||||
}
|
||||
|
||||
ExtensionSystem::IPlugin::ShutdownFlag CppToolsPlugin::aboutToShutdown()
|
||||
|
||||
Reference in New Issue
Block a user