forked from qt-creator/qt-creator
CompilationDatabase: Ask for the root path and scan for headers
Let's use the same approach we have for CMake projects by using the same TreeScanner class. Compilation database does not have a concept of the root directory so let's show a file dialog and ask for it the first time the project is loaded. Next times we open it we take this path from settings. This root path can later be changed from the project tree context menu. Fixes: QTCREATORBUG-22031 Change-Id: I151aed8d0504b2e8aa14aa774cad25f8c86d5c17 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -30,11 +30,11 @@
|
||||
#include "builddirmanager.h"
|
||||
#include "cmakebuildtarget.h"
|
||||
#include "cmakeprojectimporter.h"
|
||||
#include "treescanner.h"
|
||||
|
||||
#include <projectexplorer/extracompiler.h>
|
||||
#include <projectexplorer/projectmacro.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectmacro.h>
|
||||
#include <projectexplorer/treescanner.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
CppTools::CppProjectUpdater *m_cppCodeModelUpdater = nullptr;
|
||||
QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers;
|
||||
|
||||
Internal::TreeScanner m_treeScanner;
|
||||
ProjectExplorer::TreeScanner m_treeScanner;
|
||||
Internal::BuildDirManager m_buildDirManager;
|
||||
|
||||
bool m_waitingForScan = false;
|
||||
|
||||
@@ -35,8 +35,7 @@ HEADERS = builddirmanager.h \
|
||||
configmodelitemdelegate.h \
|
||||
servermode.h \
|
||||
servermodereader.h \
|
||||
tealeafreader.h \
|
||||
treescanner.h
|
||||
tealeafreader.h
|
||||
|
||||
SOURCES = builddirmanager.cpp \
|
||||
builddirparameters.cpp \
|
||||
@@ -70,8 +69,7 @@ SOURCES = builddirmanager.cpp \
|
||||
configmodelitemdelegate.cpp \
|
||||
servermode.cpp \
|
||||
servermodereader.cpp \
|
||||
tealeafreader.cpp \
|
||||
treescanner.cpp \
|
||||
tealeafreader.cpp
|
||||
|
||||
RESOURCES += cmakeproject.qrc
|
||||
|
||||
|
||||
@@ -88,8 +88,6 @@ QtcPlugin {
|
||||
"servermodereader.cpp",
|
||||
"servermodereader.h",
|
||||
"tealeafreader.cpp",
|
||||
"tealeafreader.h",
|
||||
"treescanner.cpp",
|
||||
"treescanner.h",
|
||||
"tealeafreader.h"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Alexander Drozdov.
|
||||
** Contact: Alexander Drozdov (adrozdoff@gmail.com)
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "treescanner.h"
|
||||
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <cpptools/cpptoolsconstants.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/runextensions.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
TreeScanner::TreeScanner(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_factory = TreeScanner::genericFileType;
|
||||
m_filter = [](const Utils::MimeType &mimeType, const Utils::FileName &fn) {
|
||||
return isWellKnownBinary(mimeType, fn) && isMimeBinary(mimeType, fn);
|
||||
};
|
||||
|
||||
connect(&m_futureWatcher, &FutureWatcher::finished, this, &TreeScanner::finished);
|
||||
}
|
||||
|
||||
TreeScanner::~TreeScanner()
|
||||
{
|
||||
if (!m_futureWatcher.isFinished()) {
|
||||
m_futureWatcher.cancel();
|
||||
m_futureWatcher.waitForFinished();
|
||||
}
|
||||
}
|
||||
|
||||
bool TreeScanner::asyncScanForFiles(const Utils::FileName &directory)
|
||||
{
|
||||
if (!m_futureWatcher.isFinished())
|
||||
return false;
|
||||
|
||||
auto fi = new FutureInterface();
|
||||
m_scanFuture = fi->future();
|
||||
m_futureWatcher.setFuture(m_scanFuture);
|
||||
|
||||
Utils::runAsync([this, fi, directory]() { TreeScanner::scanForFiles(fi, directory, m_filter, m_factory); });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TreeScanner::setFilter(TreeScanner::FileFilter filter)
|
||||
{
|
||||
if (isFinished())
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
void TreeScanner::setTypeFactory(TreeScanner::FileTypeFactory factory)
|
||||
{
|
||||
if (isFinished())
|
||||
m_factory = factory;
|
||||
}
|
||||
|
||||
TreeScanner::Future TreeScanner::future() const
|
||||
{
|
||||
return m_scanFuture;
|
||||
}
|
||||
|
||||
bool TreeScanner::isFinished() const
|
||||
{
|
||||
return m_futureWatcher.isFinished();
|
||||
}
|
||||
|
||||
TreeScanner::Result TreeScanner::result() const
|
||||
{
|
||||
if (isFinished())
|
||||
return m_scanFuture.result();
|
||||
return Result();
|
||||
}
|
||||
|
||||
TreeScanner::Result TreeScanner::release()
|
||||
{
|
||||
if (isFinished()) {
|
||||
auto result = m_scanFuture.result();
|
||||
m_scanFuture = Future();
|
||||
return result;
|
||||
}
|
||||
return Result();
|
||||
}
|
||||
|
||||
void TreeScanner::reset()
|
||||
{
|
||||
if (isFinished())
|
||||
m_scanFuture = Future();
|
||||
}
|
||||
|
||||
bool TreeScanner::isWellKnownBinary(const Utils::MimeType & /*mdb*/, const Utils::FileName &fn)
|
||||
{
|
||||
return fn.endsWith(QLatin1String(".a")) ||
|
||||
fn.endsWith(QLatin1String(".o")) ||
|
||||
fn.endsWith(QLatin1String(".d")) ||
|
||||
fn.endsWith(QLatin1String(".exe")) ||
|
||||
fn.endsWith(QLatin1String(".dll")) ||
|
||||
fn.endsWith(QLatin1String(".obj")) ||
|
||||
fn.endsWith(QLatin1String(".elf"));
|
||||
}
|
||||
|
||||
bool TreeScanner::isMimeBinary(const Utils::MimeType &mimeType, const Utils::FileName &/*fn*/)
|
||||
{
|
||||
bool isBinary = false;
|
||||
if (mimeType.isValid()) {
|
||||
QStringList mimes;
|
||||
mimes << mimeType.name() << mimeType.allAncestors();
|
||||
isBinary = !mimes.contains(QLatin1String("text/plain"));
|
||||
}
|
||||
return isBinary;
|
||||
}
|
||||
|
||||
FileType TreeScanner::genericFileType(const Utils::MimeType &mimeType, const Utils::FileName &/*fn*/)
|
||||
{
|
||||
return Node::fileTypeForMimeType(mimeType);
|
||||
}
|
||||
|
||||
void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FileName& directory,
|
||||
const FileFilter &filter, const FileTypeFactory &factory)
|
||||
{
|
||||
std::unique_ptr<FutureInterface> fip(fi);
|
||||
fip->reportStarted();
|
||||
|
||||
Result nodes = FileNode::scanForFiles(
|
||||
directory,
|
||||
[&filter, &factory](const Utils::FileName &fn) -> FileNode * {
|
||||
const Utils::MimeType mimeType = Utils::mimeTypeForFile(fn.toString());
|
||||
|
||||
// Skip some files during scan.
|
||||
if (filter && filter(mimeType, fn))
|
||||
return nullptr;
|
||||
|
||||
// Type detection
|
||||
FileType type = FileType::Unknown;
|
||||
if (factory)
|
||||
type = factory(mimeType, fn);
|
||||
|
||||
return new FileNode(fn, type);
|
||||
}, fip.get());
|
||||
|
||||
Utils::sort(nodes, ProjectExplorer::Node::sortByPath);
|
||||
|
||||
fip->setProgressValue(fip->progressMaximum());
|
||||
fip->reportResult(nodes);
|
||||
fip->reportFinished();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
@@ -1,104 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Alexander Drozdov.
|
||||
** Contact: Alexander Drozdov (adrozdoff@gmail.com)
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "projectexplorer/projectnodes.h"
|
||||
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Core { class IVersionControl; }
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class TreeScanner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using Result = QList<ProjectExplorer::FileNode *>;
|
||||
using Future = QFuture<Result>;
|
||||
using FutureWatcher = QFutureWatcher<Result>;
|
||||
using FutureInterface = QFutureInterface<Result>;
|
||||
|
||||
using FileFilter = std::function<bool(const Utils::MimeType &, const Utils::FileName &)>;
|
||||
using FileTypeFactory = std::function<ProjectExplorer::FileType(const Utils::MimeType &, const Utils::FileName &)>;
|
||||
|
||||
explicit TreeScanner(QObject *parent = nullptr);
|
||||
~TreeScanner() override;
|
||||
|
||||
// Start scanning in given directory
|
||||
bool asyncScanForFiles(const Utils::FileName& directory);
|
||||
|
||||
// Setup filter for ignored files
|
||||
void setFilter(FileFilter filter);
|
||||
|
||||
// Setup factory for file types
|
||||
void setTypeFactory(FileTypeFactory factory);
|
||||
|
||||
Future future() const;
|
||||
bool isFinished() const;
|
||||
|
||||
// Takes not-owning result
|
||||
Result result() const;
|
||||
// Takes owning of result
|
||||
Result release();
|
||||
// Clear scan results
|
||||
void reset();
|
||||
|
||||
// Standard filters helpers
|
||||
static bool isWellKnownBinary(const Utils::MimeType &mimeType, const Utils::FileName &fn);
|
||||
static bool isMimeBinary(const Utils::MimeType &mimeType, const Utils::FileName &fn);
|
||||
|
||||
// Standard file factory
|
||||
static ProjectExplorer::FileType genericFileType(const Utils::MimeType &mdb, const Utils::FileName& fn);
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
static void scanForFiles(FutureInterface *fi, const Utils::FileName &directory,
|
||||
const FileFilter &filter, const FileTypeFactory &factory);
|
||||
|
||||
private:
|
||||
FileFilter m_filter;
|
||||
FileTypeFactory m_factory;
|
||||
|
||||
FutureWatcher m_futureWatcher;
|
||||
Future m_scanFuture;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
|
||||
Reference in New Issue
Block a user