forked from qt-creator/qt-creator
Clang: Add Symbol Indexing
It is a first step and now a database is generated if you start QtCreator. Some code is now shared with the PchManager which can be improved in the future. Change-Id: Ic267fe7960f6c455d91832859a673ce98f269aa2 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -30,3 +30,5 @@
|
||||
#include "requestsourcelocationforrenamingmessage.h"
|
||||
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
|
||||
#include "requestsourcerangesforquerymessage.h"
|
||||
#include "updatepchprojectpartsmessage.h"
|
||||
#include "removepchprojectpartsmessage.h"
|
||||
|
@@ -174,6 +174,7 @@ HEADERS += \
|
||||
$$PWD/ipcclientprovider.h \
|
||||
$$PWD/requestsourcerangesforquerymessage.h \
|
||||
$$PWD/stringcachefwd.h \
|
||||
$$PWD/stringcachealgorithms.h
|
||||
$$PWD/stringcachealgorithms.h \
|
||||
$$PWD/projectmanagementserverinterface.h
|
||||
|
||||
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ipcserverinterface.h"
|
||||
#include "projectmanagementserverinterface.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -35,15 +35,12 @@ class PchManagerClientInterface;
|
||||
class RemovePchProjectPartsMessage;
|
||||
class UpdatePchProjectPartsMessage;
|
||||
|
||||
|
||||
class CMBIPC_EXPORT PchManagerServerInterface : public IpcServerInterface
|
||||
class CMBIPC_EXPORT PchManagerServerInterface : public ProjectManagementServerInterface
|
||||
{
|
||||
public:
|
||||
void dispatch(const MessageEnvelop &messageEnvelop) override;
|
||||
|
||||
virtual void end() = 0;
|
||||
virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
|
||||
virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
42
src/libs/clangsupport/projectmanagementserverinterface.h
Normal file
42
src/libs/clangsupport/projectmanagementserverinterface.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "ipcserverinterface.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class RemovePchProjectPartsMessage;
|
||||
class UpdatePchProjectPartsMessage;
|
||||
|
||||
class CMBIPC_EXPORT ProjectManagementServerInterface : public IpcInterface
|
||||
{
|
||||
public:
|
||||
virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
|
||||
virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -47,6 +47,12 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
|
||||
case MessageType::RequestSourceRangesForQueryMessage:
|
||||
requestSourceRangesForQueryMessage(messageEnvelop.message<RequestSourceRangesForQueryMessage>());
|
||||
break;
|
||||
case MessageType::UpdatePchProjectPartsMessage:
|
||||
updatePchProjectParts(messageEnvelop.message<UpdatePchProjectPartsMessage>());
|
||||
break;
|
||||
case MessageType::RemovePchProjectPartsMessage:
|
||||
removePchProjectParts(messageEnvelop.message<RemovePchProjectPartsMessage>());
|
||||
break;
|
||||
case MessageType::CancelMessage:
|
||||
cancel();
|
||||
break;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ipcserverinterface.h"
|
||||
#include "projectmanagementserverinterface.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -36,8 +36,10 @@ class RequestSourceLocationsForRenamingMessage;
|
||||
class RequestSourceRangesAndDiagnosticsForQueryMessage;
|
||||
class RequestSourceRangesForQueryMessage;
|
||||
class CancelMessage;
|
||||
class UpdatePchProjectPartsMessage;
|
||||
class RemovePchProjectPartsMessage;
|
||||
|
||||
class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface
|
||||
class CMBIPC_EXPORT RefactoringServerInterface : public ProjectManagementServerInterface
|
||||
|
||||
{
|
||||
public:
|
||||
|
@@ -62,6 +62,16 @@ void RefactoringServerProxy::requestSourceRangesForQueryMessage(RequestSourceRan
|
||||
writeMessageBlock.write(message);
|
||||
}
|
||||
|
||||
void RefactoringServerProxy::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
|
||||
{
|
||||
writeMessageBlock.write(message);
|
||||
}
|
||||
|
||||
void RefactoringServerProxy::removePchProjectParts(RemovePchProjectPartsMessage &&message)
|
||||
{
|
||||
writeMessageBlock.write(message);
|
||||
}
|
||||
|
||||
void RefactoringServerProxy::cancel()
|
||||
{
|
||||
writeMessageBlock.write(CancelMessage());
|
||||
|
@@ -53,6 +53,8 @@ public:
|
||||
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
|
||||
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
|
||||
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
|
||||
void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
|
||||
void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
|
||||
void cancel() override;
|
||||
|
||||
void readMessages();
|
||||
|
@@ -125,12 +125,7 @@ public:
|
||||
{
|
||||
std::lock_guard<Mutex> lock(m_mutex);
|
||||
|
||||
Found found = find(stringView);
|
||||
|
||||
if (!found.wasFound)
|
||||
return insertString(found.iterator, stringView);
|
||||
|
||||
return found.iterator->id;
|
||||
return ungardedStringId(stringView);
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
@@ -144,7 +139,7 @@ public:
|
||||
std::transform(strings.begin(),
|
||||
strings.end(),
|
||||
std::back_inserter(ids),
|
||||
[&] (const auto &string) { return this->stringId(string); });
|
||||
[&] (const auto &string) { return this->ungardedStringId(string); });
|
||||
|
||||
return ids;
|
||||
}
|
||||
@@ -182,6 +177,16 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
IndexType ungardedStringId(Utils::SmallStringView stringView)
|
||||
{
|
||||
Found found = find(stringView);
|
||||
|
||||
if (!found.wasFound)
|
||||
return insertString(found.iterator, stringView);
|
||||
|
||||
return found.iterator->id;
|
||||
}
|
||||
|
||||
Found find(Utils::SmallStringView stringView)
|
||||
{
|
||||
return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare);
|
||||
|
@@ -43,7 +43,8 @@ HEADERS += \
|
||||
$$PWD/utf8stringvector.h \
|
||||
$$PWD/sqlitedatabase.h \
|
||||
$$PWD/sqlitetable.h \
|
||||
$$PWD/sqlitecolumn.h
|
||||
$$PWD/sqlitecolumn.h \
|
||||
$$PWD/sqliteindex.h
|
||||
|
||||
DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
|
||||
|
||||
|
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SqliteColumn
|
||||
@@ -108,5 +110,7 @@ private:
|
||||
};
|
||||
|
||||
using SqliteColumns = std::vector<SqliteColumn>;
|
||||
using SqliteColumnConstReference = std::reference_wrapper<const SqliteColumn>;
|
||||
using SqliteColumnConstReferences = std::vector<SqliteColumnConstReference>;
|
||||
|
||||
} // namespace Sqlite
|
||||
|
82
src/libs/sqlite/sqliteindex.h
Normal file
82
src/libs/sqlite/sqliteindex.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "sqliteglobal.h"
|
||||
|
||||
#include "sqliteexception.h"
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
namespace Sqlite {
|
||||
|
||||
class SqliteIndex
|
||||
{
|
||||
public:
|
||||
SqliteIndex(Utils::SmallString &&tableName, Utils::SmallStringVector &&columnNames)
|
||||
: m_tableName(std::move(tableName)),
|
||||
m_columnNames(std::move(columnNames))
|
||||
{
|
||||
}
|
||||
|
||||
Utils::SmallString sqlStatement() const
|
||||
{
|
||||
checkTableName();
|
||||
checkColumns();
|
||||
|
||||
return {"CREATE INDEX IF NOT EXISTS index_",
|
||||
m_tableName,
|
||||
"_",
|
||||
m_columnNames.join("_"),
|
||||
" ON ",
|
||||
m_tableName,
|
||||
"(",
|
||||
m_columnNames.join(", "),
|
||||
")"
|
||||
};
|
||||
}
|
||||
|
||||
void checkTableName() const
|
||||
{
|
||||
if (m_tableName.isEmpty())
|
||||
throw SqliteException("SqliteIndex has not table name!");
|
||||
}
|
||||
|
||||
void checkColumns() const
|
||||
{
|
||||
if (m_columnNames.empty())
|
||||
throw SqliteException("SqliteIndex has no columns!");
|
||||
}
|
||||
|
||||
private:
|
||||
Utils::SmallString m_tableName;
|
||||
Utils::SmallStringVector m_columnNames;
|
||||
};
|
||||
|
||||
using SqliteIndices = std::vector<SqliteIndex>;
|
||||
|
||||
} //
|
@@ -28,6 +28,7 @@
|
||||
#include "createtablesqlstatementbuilder.h"
|
||||
#include "sqliteglobal.h"
|
||||
#include "sqlitecolumn.h"
|
||||
#include "sqliteindex.h"
|
||||
#include "sqliteexception.h"
|
||||
|
||||
namespace Sqlite {
|
||||
@@ -37,6 +38,12 @@ class SqliteDatabase;
|
||||
class SqliteTable
|
||||
{
|
||||
public:
|
||||
SqliteTable(std::size_t reserve = 10)
|
||||
{
|
||||
m_sqliteColumns.reserve(reserve);
|
||||
m_sqliteIndices.reserve(reserve);
|
||||
}
|
||||
|
||||
void setName(Utils::SmallString &&name)
|
||||
{
|
||||
m_tableName = std::move(name);
|
||||
@@ -76,6 +83,13 @@ public:
|
||||
return m_sqliteColumns.back();
|
||||
}
|
||||
|
||||
SqliteIndex &addIndex(const SqliteColumnConstReferences &columns)
|
||||
{
|
||||
m_sqliteIndices.emplace_back(m_tableName.clone(), sqliteColumnNames(columns));
|
||||
|
||||
return m_sqliteIndices.back();
|
||||
}
|
||||
|
||||
const SqliteColumns &columns() const
|
||||
{
|
||||
return m_sqliteColumns;
|
||||
@@ -89,22 +103,25 @@ public:
|
||||
template <typename Database>
|
||||
void initialize(Database &database)
|
||||
{
|
||||
try {
|
||||
CreateTableSqlStatementBuilder builder;
|
||||
CreateTableSqlStatementBuilder builder;
|
||||
|
||||
builder.setTableName(m_tableName.clone());
|
||||
builder.setUseWithoutRowId(m_withoutRowId);
|
||||
builder.setUseIfNotExists(m_useIfNotExists);
|
||||
builder.setUseTemporaryTable(m_useTemporaryTable);
|
||||
builder.setColumns(m_sqliteColumns);
|
||||
builder.setTableName(m_tableName.clone());
|
||||
builder.setUseWithoutRowId(m_withoutRowId);
|
||||
builder.setUseIfNotExists(m_useIfNotExists);
|
||||
builder.setUseTemporaryTable(m_useTemporaryTable);
|
||||
builder.setColumns(m_sqliteColumns);
|
||||
|
||||
database.execute(builder.sqlStatement());
|
||||
database.execute(builder.sqlStatement());
|
||||
|
||||
m_isReady = true;
|
||||
initializeIndices(database);
|
||||
|
||||
} catch (const SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
m_isReady = true;
|
||||
}
|
||||
template <typename Database>
|
||||
void initializeIndices(Database &database)
|
||||
{
|
||||
for (const SqliteIndex &index : m_sqliteIndices)
|
||||
database.execute(index.sqlStatement());
|
||||
}
|
||||
|
||||
friend bool operator==(const SqliteTable &first, const SqliteTable &second)
|
||||
@@ -116,9 +133,21 @@ public:
|
||||
&& first.m_sqliteColumns == second.m_sqliteColumns;
|
||||
}
|
||||
|
||||
private:
|
||||
Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
|
||||
{
|
||||
Utils::SmallStringVector columnNames;
|
||||
|
||||
for (const SqliteColumn &column : columns)
|
||||
columnNames.push_back(column.name());
|
||||
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
private:
|
||||
Utils::SmallString m_tableName;
|
||||
SqliteColumns m_sqliteColumns;
|
||||
SqliteIndices m_sqliteIndices;
|
||||
bool m_withoutRowId = false;
|
||||
bool m_useIfNotExists = false;
|
||||
bool m_useTemporaryTable = false;
|
||||
|
@@ -36,7 +36,7 @@ template <typename Database>
|
||||
class SqliteAbstractTransaction
|
||||
{
|
||||
public:
|
||||
virtual ~SqliteAbstractTransaction()
|
||||
~SqliteAbstractTransaction()
|
||||
{
|
||||
if (!m_isAlreadyCommited)
|
||||
m_database.execute("ROLLBACK");
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
{
|
||||
database.execute("BEGIN");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Database>
|
||||
@@ -80,7 +79,6 @@ public:
|
||||
{
|
||||
database.execute("BEGIN IMMEDIATE");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Database>
|
||||
@@ -92,7 +90,6 @@ public:
|
||||
{
|
||||
database.execute("BEGIN EXCLUSIVE");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
@@ -11,12 +11,14 @@ HEADERS += \
|
||||
$$PWD/pchmanagernotifierinterface.h \
|
||||
$$PWD/pchmanagerconnectionclient.h \
|
||||
$$PWD/clangpchmanager_global.h \
|
||||
$$PWD/projectupdater.h
|
||||
$$PWD/projectupdater.h \
|
||||
$$PWD/pchmanagerprojectupdater.h
|
||||
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/pchmanagerclient.cpp \
|
||||
$$PWD/pchmanagernotifierinterface.cpp \
|
||||
$$PWD/pchmanagerconnectionclient.cpp \
|
||||
$$PWD/projectupdater.cpp
|
||||
$$PWD/projectupdater.cpp \
|
||||
$$PWD/pchmanagerprojectupdater.cpp
|
||||
|
||||
|
@@ -52,7 +52,7 @@ class ClangPchManagerPluginData
|
||||
public:
|
||||
PchManagerClient pchManagerClient;
|
||||
PchManagerConnectionClient connectionClient{&pchManagerClient};
|
||||
QtCreatorProjectUpdater projectUpdate{connectionClient.serverProxy(), pchManagerClient};
|
||||
QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(), pchManagerClient};
|
||||
};
|
||||
|
||||
std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;
|
||||
|
47
src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
Normal file
47
src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "pchmanagerprojectupdater.h"
|
||||
|
||||
#include "pchmanagerclient.h"
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
PchManagerProjectUpdater::PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
PchManagerClient &client)
|
||||
: ProjectUpdater(server),
|
||||
m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
void PchManagerProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
|
||||
{
|
||||
ProjectUpdater::removeProjectParts(projectPartIds);
|
||||
|
||||
for (const QString &projectPartiId : projectPartIds)
|
||||
m_client.precompiledHeaderRemoved(projectPartiId);
|
||||
}
|
||||
|
||||
} // namespace ClangPchManager
|
44
src/plugins/clangpchmanager/pchmanagerprojectupdater.h
Normal file
44
src/plugins/clangpchmanager/pchmanagerprojectupdater.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "projectupdater.h"
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
class PchManagerProjectUpdater : public ProjectUpdater
|
||||
{
|
||||
public:
|
||||
PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
PchManagerClient &client);
|
||||
|
||||
void removeProjectParts(const QStringList &projectPartIds);
|
||||
|
||||
private:
|
||||
PchManagerClient &m_client;
|
||||
};
|
||||
|
||||
} // namespace ClangPchManager
|
@@ -52,10 +52,8 @@ public:
|
||||
Utils::PathStringVector sources;
|
||||
};
|
||||
|
||||
ProjectUpdater::ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
|
||||
PchManagerClient &client)
|
||||
: m_server(server),
|
||||
m_client(client)
|
||||
ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
|
||||
: m_server(server)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,9 +73,6 @@ void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
|
||||
ClangBackEnd::RemovePchProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};
|
||||
|
||||
m_server.removePchProjectParts(std::move(message));
|
||||
|
||||
for (const QString &projectPartiId : projectPartIds)
|
||||
m_client.precompiledHeaderRemoved(projectPartiId);
|
||||
}
|
||||
|
||||
void ProjectUpdater::setExcludedPaths(Utils::PathStringVector &&excludedPaths)
|
||||
|
@@ -35,7 +35,7 @@ class ProjectFile;
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
class PchManagerServerInterface;
|
||||
class ProjectManagementServerInterface;
|
||||
|
||||
namespace V2 {
|
||||
class ProjectPartContainer;
|
||||
@@ -51,11 +51,10 @@ namespace ClangPchManager {
|
||||
class HeaderAndSources;
|
||||
class PchManagerClient;
|
||||
|
||||
class ProjectUpdater
|
||||
class CLANGPCHMANAGER_EXPORT ProjectUpdater
|
||||
{
|
||||
public:
|
||||
ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
|
||||
PchManagerClient &client);
|
||||
ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server);
|
||||
|
||||
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
||||
ClangBackEnd::V2::FileContainers &&generatedFiles);
|
||||
@@ -77,8 +76,7 @@ unittest_public:
|
||||
|
||||
private:
|
||||
Utils::PathStringVector m_excludedPaths;
|
||||
ClangBackEnd::PchManagerServerInterface &m_server;
|
||||
PchManagerClient &m_client;
|
||||
ClangBackEnd::ProjectManagementServerInterface &m_server;
|
||||
};
|
||||
|
||||
} // namespace ClangPchManager
|
||||
|
@@ -26,26 +26,18 @@
|
||||
#include "qtcreatorprojectupdater.h"
|
||||
|
||||
#include <cpptools/abstracteditorsupport.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
static CppTools::CppModelManager *cppModelManager()
|
||||
namespace Internal {
|
||||
|
||||
CppTools::CppModelManager *cppModelManager()
|
||||
{
|
||||
return CppTools::CppModelManager::instance();
|
||||
}
|
||||
|
||||
QtCreatorProjectUpdater::QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
|
||||
PchManagerClient &client)
|
||||
: ProjectUpdater(server, client)
|
||||
{
|
||||
connectToCppModelManager();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
|
||||
{
|
||||
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
||||
@@ -85,30 +77,7 @@ std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project
|
||||
convertToRawPointer);
|
||||
|
||||
return projectParts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QtCreatorProjectUpdater::projectPartsUpdated(ProjectExplorer::Project *project)
|
||||
{
|
||||
updateProjectParts(createProjectParts(project), createGeneratedFiles());
|
||||
}
|
||||
|
||||
void QtCreatorProjectUpdater::projectPartsRemoved(const QStringList &projectPartIds)
|
||||
{
|
||||
removeProjectParts(projectPartIds);
|
||||
}
|
||||
|
||||
void QtCreatorProjectUpdater::connectToCppModelManager()
|
||||
{
|
||||
connect(cppModelManager(),
|
||||
&CppTools::CppModelManager::projectPartsUpdated,
|
||||
this,
|
||||
&QtCreatorProjectUpdater::projectPartsUpdated);
|
||||
connect(cppModelManager(),
|
||||
&CppTools::CppModelManager::projectPartsRemoved,
|
||||
this,
|
||||
&QtCreatorProjectUpdater::projectPartsRemoved);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangPchManager
|
||||
|
@@ -25,7 +25,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "projectupdater.h"
|
||||
#include "pchmanagerprojectupdater.h"
|
||||
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@@ -33,19 +37,57 @@ namespace ProjectExplorer {
|
||||
class Project;
|
||||
}
|
||||
|
||||
namespace CppTools {
|
||||
class CppModelManager;
|
||||
}
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
class QtCreatorProjectUpdater : public QObject, public ProjectUpdater
|
||||
namespace Internal {
|
||||
CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
|
||||
CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
|
||||
CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
|
||||
}
|
||||
|
||||
template <typename ProjectUpdaterType>
|
||||
class QtCreatorProjectUpdater : public ProjectUpdaterType
|
||||
{
|
||||
public:
|
||||
QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
|
||||
PchManagerClient &client);
|
||||
template <typename ClientType>
|
||||
QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
ClientType &client)
|
||||
: ProjectUpdaterType(server, client)
|
||||
{
|
||||
connectToCppModelManager();
|
||||
}
|
||||
|
||||
void projectPartsUpdated(ProjectExplorer::Project *project);
|
||||
void projectPartsRemoved(const QStringList &projectPartIds);
|
||||
QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
|
||||
: ProjectUpdaterType(server)
|
||||
{
|
||||
connectToCppModelManager();
|
||||
}
|
||||
|
||||
void projectPartsUpdated(ProjectExplorer::Project *project)
|
||||
{
|
||||
ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project),
|
||||
Internal::createGeneratedFiles());
|
||||
}
|
||||
|
||||
void projectPartsRemoved(const QStringList &projectPartIds)
|
||||
{
|
||||
ProjectUpdaterType::removeProjectParts(projectPartIds);
|
||||
}
|
||||
|
||||
private:
|
||||
void connectToCppModelManager();
|
||||
void connectToCppModelManager()
|
||||
{
|
||||
QObject::connect(Internal::cppModelManager(),
|
||||
&CppTools::CppModelManager::projectPartsUpdated,
|
||||
[&] (ProjectExplorer::Project *project) { projectPartsUpdated(project); });
|
||||
QObject::connect(Internal::cppModelManager(),
|
||||
&CppTools::CppModelManager::projectPartsRemoved,
|
||||
[&] (const QStringList &projectPartIds) { projectPartsRemoved(projectPartIds); });
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ClangPchManager
|
||||
|
@@ -11,7 +11,8 @@ HEADERS += \
|
||||
$$PWD/clangqueryexamplehighlightmarker.h \
|
||||
$$PWD/clangqueryhighlightmarker.h \
|
||||
$$PWD/clangqueryexamplehighlighter.h \
|
||||
$$PWD/clangqueryhighlighter.h
|
||||
$$PWD/clangqueryhighlighter.h \
|
||||
$$PWD/refactoringprojectupdater.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/refactoringengine.cpp \
|
||||
@@ -22,4 +23,5 @@ SOURCES += \
|
||||
$$PWD/projectpartutilities.cpp \
|
||||
$$PWD/clangqueryprojectsfindfilter.cpp \
|
||||
$$PWD/clangqueryexamplehighlighter.cpp \
|
||||
$$PWD/clangqueryhighlighter.cpp
|
||||
$$PWD/clangqueryhighlighter.cpp \
|
||||
$$PWD/refactoringprojectupdater.cpp
|
||||
|
@@ -5,4 +5,5 @@ QTC_LIB_DEPENDS += \
|
||||
QTC_PLUGIN_DEPENDS += \
|
||||
coreplugin \
|
||||
cpptools \
|
||||
texteditor
|
||||
texteditor \
|
||||
clangpchmanager
|
||||
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "clangrefactoringplugin.h"
|
||||
|
||||
#include <clangpchmanager/qtcreatorprojectupdater.h>
|
||||
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -50,6 +52,7 @@ std::unique_ptr<ClangRefactoringPluginData> ClangRefactoringPlugin::d;
|
||||
|
||||
class ClangRefactoringPluginData
|
||||
{
|
||||
using ProjectUpdater = ClangPchManager::QtCreatorProjectUpdater<ClangPchManager::ProjectUpdater>;
|
||||
public:
|
||||
RefactoringClient refactoringClient;
|
||||
ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient};
|
||||
@@ -58,6 +61,9 @@ public:
|
||||
QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(),
|
||||
qtCreatorSearch,
|
||||
refactoringClient};
|
||||
ProjectUpdater projectUpdate{connectionClient.serverProxy()};
|
||||
|
||||
|
||||
};
|
||||
|
||||
ClangRefactoringPlugin::ClangRefactoringPlugin()
|
||||
|
37
src/plugins/clangrefactoring/refactoringprojectupdater.cpp
Normal file
37
src/plugins/clangrefactoring/refactoringprojectupdater.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "refactoringprojectupdater.h"
|
||||
|
||||
namespace ClangRefactoring {
|
||||
|
||||
RefactoringProjectUpdater::RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
RefactoringClient &)
|
||||
: ClangPchManager::ProjectUpdater(server)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace ClangRefactoring
|
41
src/plugins/clangrefactoring/refactoringprojectupdater.h
Normal file
41
src/plugins/clangrefactoring/refactoringprojectupdater.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 <clangpchmanager/projectupdater.h>
|
||||
|
||||
namespace ClangRefactoring {
|
||||
|
||||
class RefactoringClient;
|
||||
|
||||
class RefactoringProjectUpdater : public ClangPchManager::ProjectUpdater
|
||||
{
|
||||
public:
|
||||
RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
|
||||
RefactoringClient &client);
|
||||
};
|
||||
|
||||
} // namespace ClangRefactoring
|
@@ -50,6 +50,13 @@ public:
|
||||
Utils::PathString sourcePath;
|
||||
};
|
||||
|
||||
enum LocationGetter
|
||||
{
|
||||
SourceId = 0,
|
||||
Line,
|
||||
Column
|
||||
};
|
||||
|
||||
std::vector<Location> locations;
|
||||
std::unordered_map<qint64, Utils::PathString> sources;
|
||||
};
|
||||
|
@@ -26,14 +26,19 @@
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QLoggingCategory>
|
||||
#include <QDir>
|
||||
|
||||
#include <connectionserver.h>
|
||||
#include <stringcache.h>
|
||||
#include <refactoringserver.h>
|
||||
#include <refactoringclientproxy.h>
|
||||
#include <symbolindexing.h>
|
||||
|
||||
using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::RefactoringClientProxy;
|
||||
using ClangBackEnd::RefactoringServer;
|
||||
using ClangBackEnd::ConnectionServer;
|
||||
using ClangBackEnd::SymbolIndexing;
|
||||
|
||||
QString processArguments(QCoreApplication &application)
|
||||
{
|
||||
@@ -52,7 +57,7 @@ QString processArguments(QCoreApplication &application)
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try {
|
||||
//QLoggingCategory::setFilterRules(QStringLiteral("*.debug=false"));
|
||||
|
||||
QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
|
||||
@@ -64,13 +69,17 @@ int main(int argc, char *argv[])
|
||||
|
||||
const QString connection = processArguments(application);
|
||||
|
||||
RefactoringServer clangCodeModelServer;
|
||||
FilePathCache<std::mutex> filePathCache;
|
||||
SymbolIndexing symbolIndexing{filePathCache, Utils::PathString{QDir::tempPath() + "/symbol.db"}};
|
||||
RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache};
|
||||
ConnectionServer<RefactoringServer, RefactoringClientProxy> connectionServer(connection);
|
||||
connectionServer.start();
|
||||
connectionServer.setServer(&clangCodeModelServer);
|
||||
|
||||
|
||||
return application.exec();
|
||||
} catch (const Sqlite::SqliteException &exception) {
|
||||
exception.printWarning();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -9,7 +9,9 @@ HEADERS += \
|
||||
$$PWD/symbolscollectorinterface.h \
|
||||
$$PWD/symbolstorageinterface.h \
|
||||
$$PWD/symbolstorage.h \
|
||||
$$PWD/storagesqlitestatementfactory.h
|
||||
$$PWD/storagesqlitestatementfactory.h \
|
||||
$$PWD/symbolindexing.h \
|
||||
$$PWD/symbolindexinginterface.h
|
||||
|
||||
!isEmpty(LIBTOOLING_LIBS) {
|
||||
SOURCES += \
|
||||
@@ -55,4 +57,5 @@ SOURCES += \
|
||||
$$PWD/symbolindexer.cpp \
|
||||
$$PWD/symbolentry.cpp \
|
||||
$$PWD/sourcelocationentry.cpp \
|
||||
$$PWD/symbolstorage.cpp
|
||||
$$PWD/symbolstorage.cpp \
|
||||
$$PWD/symbolindexing.cpp
|
||||
|
@@ -110,4 +110,11 @@ private:
|
||||
std::vector<UnsavedFileContent> m_unsavedFileContents;
|
||||
};
|
||||
|
||||
extern template
|
||||
void ClangTool::addFiles<Utils::SmallStringVector>(const Utils::SmallStringVector &filePaths,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
extern template
|
||||
void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector &filePaths,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -35,12 +35,14 @@
|
||||
|
||||
#include <clang/Frontend/FrontendAction.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class CollectSymbolsAction
|
||||
{
|
||||
public:
|
||||
CollectSymbolsAction(FilePathCache<> &filePathCache)
|
||||
CollectSymbolsAction(FilePathCache<std::mutex> &filePathCache)
|
||||
: m_filePathCache(filePathCache)
|
||||
{}
|
||||
|
||||
@@ -64,7 +66,7 @@ public:
|
||||
private:
|
||||
SymbolEntries m_symbolEntries;
|
||||
SourceLocationEntries m_sourceLocationEntries;
|
||||
FilePathCache<> &m_filePathCache;
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -50,7 +50,7 @@ class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbol
|
||||
public:
|
||||
CollectSymbolsASTVisitor(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathCache<> &filePathCache,
|
||||
FilePathCache<std::mutex> &filePathCache,
|
||||
const clang::SourceManager &sourceManager)
|
||||
: m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
@@ -58,8 +58,16 @@ public:
|
||||
m_sourceManager(sourceManager)
|
||||
{}
|
||||
|
||||
bool shouldVisitTemplateInstantiations() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitNamedDecl(const clang::NamedDecl *declaration)
|
||||
{
|
||||
if (!declaration->getIdentifier())
|
||||
return true;
|
||||
|
||||
SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
|
||||
auto sourceLocation = declaration->getLocation();
|
||||
|
||||
@@ -141,7 +149,7 @@ private:
|
||||
SymbolEntries &m_symbolEntries;
|
||||
std::unordered_map<uint, FilePathIndex> m_filePathIndices;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathCache<> &m_filePathCache;
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
const clang::SourceManager &m_sourceManager;
|
||||
};
|
||||
|
||||
|
@@ -40,13 +40,14 @@ class CollectSymbolsConsumer : public clang::ASTConsumer
|
||||
public:
|
||||
CollectSymbolsConsumer(SymbolEntries &symbolEntries,
|
||||
SourceLocationEntries &sourceLocationEntries,
|
||||
FilePathCache<> &filePathCache)
|
||||
FilePathCache<std::mutex> &filePathCache)
|
||||
: m_symbolEntries(symbolEntries),
|
||||
m_sourceLocationEntries(sourceLocationEntries),
|
||||
m_filePathCache(filePathCache)
|
||||
{}
|
||||
|
||||
void HandleTranslationUnit(clang::ASTContext &astContext) override {
|
||||
void HandleTranslationUnit(clang::ASTContext &astContext) override
|
||||
{
|
||||
CollectSymbolsASTVisitor visitor{m_symbolEntries,
|
||||
m_sourceLocationEntries,
|
||||
m_filePathCache,
|
||||
@@ -54,9 +55,20 @@ public:
|
||||
visitor.TraverseDecl(astContext.getTranslationUnitDecl());
|
||||
}
|
||||
|
||||
bool shouldSkipFunctionBody(clang::Decl *declation) override
|
||||
{
|
||||
const clang::SourceManager &sourceManager = declation->getASTContext().getSourceManager();
|
||||
const clang::SourceLocation location = declation->getLocation();
|
||||
|
||||
if (sourceManager.isInSystemHeader(location))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolEntries &m_symbolEntries;
|
||||
SourceLocationEntries &m_sourceLocationEntries;
|
||||
FilePathCache<> &m_filePathCache;
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
};
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "symbolfinder.h"
|
||||
#include "clangquery.h"
|
||||
#include "symbolindexing.h"
|
||||
|
||||
#include <refactoringclientinterface.h>
|
||||
#include <clangrefactoringmessages.h>
|
||||
@@ -38,7 +39,10 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
RefactoringServer::RefactoringServer()
|
||||
RefactoringServer::RefactoringServer(SymbolIndexingInterface &symbolIndexing,
|
||||
FilePathCache<std::mutex> &filePathCache)
|
||||
: m_symbolIndexing(symbolIndexing),
|
||||
m_filePathCache(filePathCache)
|
||||
{
|
||||
m_pollTimer.setInterval(100);
|
||||
|
||||
@@ -88,7 +92,17 @@ void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesFo
|
||||
{
|
||||
gatherSourceRangesForQueryMessages(message.takeSources(),
|
||||
message.takeUnsavedContent(),
|
||||
message.takeQuery());
|
||||
message.takeQuery());
|
||||
}
|
||||
|
||||
void RefactoringServer::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
|
||||
{
|
||||
m_symbolIndexing.updateProjectParts(message.takeProjectsParts(), message.takeGeneratedFiles());
|
||||
}
|
||||
|
||||
void RefactoringServer::removePchProjectParts(RemovePchProjectPartsMessage &&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RefactoringServer::cancel()
|
||||
|
@@ -42,6 +42,7 @@
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SourceRangesForQueryMessage;
|
||||
class SymbolIndexingInterface;
|
||||
|
||||
namespace V2 {
|
||||
class FileContainer;
|
||||
@@ -52,12 +53,15 @@ class RefactoringServer : public RefactoringServerInterface,
|
||||
{
|
||||
using Future = std::future<SourceRangesForQueryMessage>;
|
||||
public:
|
||||
RefactoringServer();
|
||||
RefactoringServer(SymbolIndexingInterface &symbolIndexing,
|
||||
FilePathCache<std::mutex> &filePathCache);
|
||||
|
||||
void end() override;
|
||||
void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
|
||||
void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
|
||||
void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
|
||||
void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
|
||||
void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
|
||||
void cancel() override;
|
||||
|
||||
bool isCancelingJobs() const;
|
||||
@@ -75,9 +79,10 @@ private:
|
||||
Utils::SmallString &&query);
|
||||
|
||||
private:
|
||||
FilePathCache<std::mutex> m_filePathCache;
|
||||
ClangQueryGatherer m_gatherer;
|
||||
QTimer m_pollTimer;
|
||||
SymbolIndexingInterface &m_symbolIndexing;
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -53,8 +53,9 @@ public:
|
||||
table.setUseIfNotExists(true);
|
||||
table.setName("symbols");
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
|
||||
table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||
const Sqlite::SqliteColumn &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||
table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||
table.addIndex({usrColumn});
|
||||
|
||||
Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
|
||||
table.initialize(database);
|
||||
@@ -71,7 +72,8 @@ public:
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("line", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("column", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
const Sqlite::SqliteColumn &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
table.addIndex({sourceIdColumn});
|
||||
|
||||
Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
|
||||
table.initialize(database);
|
||||
@@ -101,9 +103,11 @@ public:
|
||||
table.setName("newSymbols");
|
||||
table.setUseTemporaryTable(true);
|
||||
table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||
table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||
const Sqlite::SqliteColumn &symbolIdColumn = table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||
const Sqlite::SqliteColumn &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
|
||||
const Sqlite::SqliteColumn &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
|
||||
table.addIndex({usrColumn, symbolNameColumn});
|
||||
table.addIndex({symbolIdColumn});
|
||||
|
||||
Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
|
||||
table.initialize(database);
|
||||
@@ -121,7 +125,8 @@ public:
|
||||
table.addColumn("symbolId", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("line", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("column", Sqlite::ColumnType::Integer);
|
||||
table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
const Sqlite::SqliteColumn &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
|
||||
table.addIndex({sourceIdColumn});
|
||||
|
||||
Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
|
||||
table.initialize(database);
|
||||
@@ -142,39 +147,49 @@ public:
|
||||
database};
|
||||
WriteStatement insertLocationsToNewLocationsStatement{
|
||||
"INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
// WriteStatement syncNewLocationsToLocationsStatement{
|
||||
// "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
|
||||
// database};
|
||||
ReadStatement selectNewSourceIdsStatement{
|
||||
"SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement addNewSymbolsToSymbolsStatement{
|
||||
"INSERT INTO symbols(usr, symbolname) "
|
||||
"SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS "
|
||||
"(SELECT usr FROM symbols WHERE usr == newsymbols.usr)",
|
||||
database};
|
||||
"INSERT INTO symbols(usr, symbolName) "
|
||||
"SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS "
|
||||
"(SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)",
|
||||
database
|
||||
};
|
||||
WriteStatement insertSourcesStatement{
|
||||
"INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement syncNewSymbolsFromSymbolsStatement{
|
||||
"UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement syncSymbolsIntoNewLocationsStatement{
|
||||
"UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement deleteAllLocationsFromUpdatedFilesStatement{
|
||||
"DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement insertNewLocationsInLocationsStatement{
|
||||
"INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement deleteNewSymbolsTableStatement{
|
||||
"DELETE FROM newSymbols",
|
||||
database};
|
||||
database
|
||||
};
|
||||
WriteStatement deleteNewLocationsTableStatement{
|
||||
"DELETE FROM newLocations",
|
||||
database};
|
||||
database
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -33,11 +33,14 @@ SymbolIndexer::SymbolIndexer(SymbolsCollectorInterface &symbolsCollector, Symbol
|
||||
{
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts)
|
||||
void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles)
|
||||
{
|
||||
for (const V2::ProjectPartContainer &projectPart : projectParts)
|
||||
m_symbolsCollector.addFiles(projectPart.sourcePaths(), projectPart.arguments());
|
||||
|
||||
m_symbolsCollector.addUnsavedFiles(generatedFiles);
|
||||
|
||||
m_symbolsCollector.collectSymbols();
|
||||
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(),
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "symbolstorageinterface.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -38,7 +39,8 @@ public:
|
||||
SymbolIndexer(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage);
|
||||
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts);
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles);
|
||||
|
||||
private:
|
||||
SymbolsCollectorInterface &m_symbolsCollector;
|
||||
|
30
src/tools/clangrefactoringbackend/source/symbolindexing.cpp
Normal file
30
src/tools/clangrefactoringbackend/source/symbolindexing.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "symbolindexing.h"
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
} // namespace ClangBackEnd
|
84
src/tools/clangrefactoringbackend/source/symbolindexing.h
Normal file
84
src/tools/clangrefactoringbackend/source/symbolindexing.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "symbolindexinginterface.h"
|
||||
|
||||
#include "storagesqlitestatementfactory.h"
|
||||
#include "symbolindexer.h"
|
||||
#include "symbolscollector.h"
|
||||
#include "symbolstorage.h"
|
||||
|
||||
#include <stringcache.h>
|
||||
|
||||
#include <sqlitedatabase.h>
|
||||
#include <sqlitereadstatement.h>
|
||||
#include <sqlitewritestatement.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolIndexing final : public SymbolIndexingInterface
|
||||
{
|
||||
public:
|
||||
using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<Sqlite::SqliteDatabase,
|
||||
Sqlite::SqliteReadStatement,
|
||||
Sqlite::SqliteWriteStatement>;
|
||||
using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
|
||||
|
||||
SymbolIndexing(FilePathCache<std::mutex> &filePathCache,
|
||||
Utils::PathString &&databaseFilePath)
|
||||
: m_filePathCache(filePathCache),
|
||||
m_database(std::move(databaseFilePath))
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
SymbolIndexer &indexer()
|
||||
{
|
||||
return m_indexer;
|
||||
}
|
||||
|
||||
Sqlite::SqliteDatabase &database()
|
||||
{
|
||||
return m_database;
|
||||
}
|
||||
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles)
|
||||
{
|
||||
m_indexer.updateProjectParts(std::move(projectParts), std::move(generatedFiles));
|
||||
}
|
||||
|
||||
private:
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
Sqlite::SqliteDatabase m_database;
|
||||
SymbolsCollector m_collector{m_filePathCache};
|
||||
StatementFactory m_statementFactory{m_database};
|
||||
Storage m_symbolStorage{m_statementFactory, m_filePathCache};
|
||||
SymbolIndexer m_indexer{m_collector, m_symbolStorage};
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 <projectpartcontainerv2.h>
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolIndexingInterface
|
||||
{
|
||||
public:
|
||||
virtual void updateProjectParts(V2::ProjectPartContainers &&projectParts,
|
||||
V2::FileContainers &&generatedFiles) = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
SymbolsCollector::SymbolsCollector(FilePathCache<> &filePathCache)
|
||||
SymbolsCollector::SymbolsCollector(FilePathCache<std::mutex> &filePathCache)
|
||||
: m_collectSymbolsAction(filePathCache)
|
||||
{
|
||||
}
|
||||
@@ -37,6 +37,11 @@ void SymbolsCollector::addFiles(const Utils::PathStringVector &filePaths, const
|
||||
ClangTool::addFiles(filePaths, arguments);
|
||||
}
|
||||
|
||||
void SymbolsCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
|
||||
{
|
||||
ClangTool::addUnsavedFiles(unsavedFiles);
|
||||
}
|
||||
|
||||
void SymbolsCollector::collectSymbols()
|
||||
{
|
||||
auto tool = createTool();
|
||||
|
@@ -37,11 +37,13 @@ namespace ClangBackEnd {
|
||||
class SymbolsCollector : public ClangTool, public SymbolsCollectorInterface
|
||||
{
|
||||
public:
|
||||
SymbolsCollector(FilePathCache<> &filePathCache);
|
||||
SymbolsCollector(FilePathCache<std::mutex> &filePathCache);
|
||||
|
||||
void addFiles(const Utils::PathStringVector &filePaths,
|
||||
const Utils::SmallStringVector &arguments) override;
|
||||
|
||||
void addUnsavedFiles(const V2::FileContainers &unsavedFiles) override;
|
||||
|
||||
void collectSymbols() override;
|
||||
|
||||
const SymbolEntries &symbols() const override;
|
||||
|
@@ -28,6 +28,8 @@
|
||||
#include "symbolentry.h"
|
||||
#include "sourcelocationentry.h"
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <string>
|
||||
@@ -41,6 +43,8 @@ public:
|
||||
virtual void addFiles(const Utils::PathStringVector &filePaths,
|
||||
const Utils::SmallStringVector &arguments) = 0;
|
||||
|
||||
virtual void addUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
|
||||
|
||||
virtual void collectSymbols() = 0;
|
||||
|
||||
virtual const SymbolEntries &symbols() const = 0;
|
||||
|
@@ -27,9 +27,12 @@
|
||||
|
||||
#include "symbolstorageinterface.h"
|
||||
|
||||
#include <sqliteexception.h>
|
||||
#include <sqlitetransaction.h>
|
||||
#include <stringcache.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
template <typename StatementFactory>
|
||||
@@ -42,7 +45,7 @@ class SymbolStorage : public SymbolStorageInterface
|
||||
|
||||
public:
|
||||
SymbolStorage(StatementFactory &statementFactory,
|
||||
FilePathCache<> &filePathCache)
|
||||
FilePathCache<std::mutex> &filePathCache)
|
||||
: m_statementFactory(statementFactory),
|
||||
m_filePathCache(filePathCache)
|
||||
{
|
||||
@@ -149,7 +152,7 @@ public:
|
||||
|
||||
private:
|
||||
StatementFactory &m_statementFactory;
|
||||
FilePathCache<> &m_filePathCache;
|
||||
FilePathCache<std::mutex> &m_filePathCache;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
36
tests/unit/unittest/data/symbolindexing_main1.cpp
Normal file
36
tests/unit/unittest/data/symbolindexing_main1.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
void function();
|
||||
|
||||
void function()
|
||||
{
|
||||
int x;
|
||||
x = 20;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T templateFunction(T t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template <>
|
||||
int templateFunction(int t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
extern template double templateFunction<double>(double);
|
||||
template double templateFunction<double>(double);
|
||||
|
||||
template<typename T>
|
||||
using TemplateFunctionType = T(&)(T);
|
||||
|
||||
|
||||
TemplateFunctionType<int> aliasToTemplateFunction = templateFunction<int>;
|
||||
|
||||
void f()
|
||||
{
|
||||
aliasToTemplateFunction(1);
|
||||
}
|
||||
|
||||
void f(int);
|
||||
void f(double);
|
1
tests/unit/unittest/data/symbolscollector_unsaved.cpp
Normal file
1
tests/unit/unittest/data/symbolscollector_unsaved.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "symbolscollector_generated_file.h"
|
@@ -25,6 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/smallstringio.h>
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <iosfwd>
|
||||
|
@@ -44,6 +44,12 @@ public:
|
||||
MOCK_METHOD1(requestSourceRangesForQueryMessage,
|
||||
void (const ClangBackEnd::RequestSourceRangesForQueryMessage&));
|
||||
|
||||
MOCK_METHOD1(updatePchProjectParts,
|
||||
void (const ClangBackEnd::UpdatePchProjectPartsMessage&));
|
||||
|
||||
MOCK_METHOD1(removePchProjectParts,
|
||||
void (const ClangBackEnd::RemovePchProjectPartsMessage&));
|
||||
|
||||
MOCK_METHOD0(cancel,
|
||||
void());
|
||||
|
||||
@@ -61,4 +67,14 @@ public:
|
||||
{
|
||||
requestSourceRangesForQueryMessage(message);
|
||||
}
|
||||
|
||||
void updatePchProjectParts(ClangBackEnd::UpdatePchProjectPartsMessage &&message) override
|
||||
{
|
||||
updatePchProjectParts(message);
|
||||
}
|
||||
|
||||
void removePchProjectParts(ClangBackEnd::RemovePchProjectPartsMessage &&message) override
|
||||
{
|
||||
removePchProjectParts(message);
|
||||
}
|
||||
};
|
||||
|
45
tests/unit/unittest/mocksymbolindexing.h
Normal file
45
tests/unit/unittest/mocksymbolindexing.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "googletest.h"
|
||||
|
||||
#include <symbolindexinginterface.h>
|
||||
|
||||
class MockSymbolIndexing : public ClangBackEnd::SymbolIndexingInterface
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2(updateProjectParts,
|
||||
void(const ClangBackEnd::V2::ProjectPartContainers &projectParts,
|
||||
const ClangBackEnd::V2::FileContainers &generatedFiles));
|
||||
|
||||
void updateProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts,
|
||||
ClangBackEnd::V2::FileContainers &&generatedFiles) override
|
||||
{
|
||||
updateProjectParts(projectParts, generatedFiles);
|
||||
}
|
||||
};
|
||||
|
@@ -39,6 +39,9 @@ public:
|
||||
void(const Utils::PathStringVector &filePaths,
|
||||
const Utils::SmallStringVector &arguments));
|
||||
|
||||
MOCK_METHOD1(addUnsavedFiles,
|
||||
void(const ClangBackEnd::V2::FileContainers &unsavedFiles));
|
||||
|
||||
MOCK_CONST_METHOD0(symbols,
|
||||
const ClangBackEnd::SymbolEntries &());
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "mockpchmanagerserver.h"
|
||||
|
||||
#include <pchmanagerclient.h>
|
||||
#include <projectupdater.h>
|
||||
#include <pchmanagerprojectupdater.h>
|
||||
|
||||
#include <precompiledheadersupdatedmessage.h>
|
||||
#include <removepchprojectpartsmessage.h>
|
||||
@@ -49,7 +49,7 @@ protected:
|
||||
MockPchManagerServer mockPchManagerServer;
|
||||
ClangPchManager::PchManagerClient client;
|
||||
MockPchManagerNotifier mockPchManagerNotifier{client};
|
||||
ClangPchManager::ProjectUpdater projectUpdater{mockPchManagerServer, client};
|
||||
ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client};
|
||||
Utils::SmallString projectPartId{"projectPartId"};
|
||||
Utils::SmallString pchFilePath{"/path/to/pch"};
|
||||
PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone()}}};
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "mockpchmanagernotifier.h"
|
||||
#include "mockpchmanagerserver.h"
|
||||
|
||||
#include <projectupdater.h>
|
||||
#include <pchmanagerprojectupdater.h>
|
||||
|
||||
#include <pchmanagerclient.h>
|
||||
#include <precompiledheadersupdatedmessage.h>
|
||||
@@ -60,7 +60,7 @@ protected:
|
||||
ClangPchManager::PchManagerClient pchManagerClient;
|
||||
MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
|
||||
NiceMock<MockPchManagerServer> mockPchManagerServer;
|
||||
ClangPchManager::ProjectUpdater updater{mockPchManagerServer, pchManagerClient};
|
||||
ClangPchManager::ProjectUpdater updater{mockPchManagerServer};
|
||||
Utils::SmallString projectPartId{"project1"};
|
||||
Utils::SmallString projectPartId2{"project2"};
|
||||
Utils::PathStringVector headerPaths = {"/path/to/header1.h", "/path/to/header2.h"};
|
||||
@@ -87,7 +87,7 @@ TEST_F(ProjectUpdater, CallUpdatePchProjectParts)
|
||||
|
||||
TEST_F(ProjectUpdater, CallRemovePchProjectParts)
|
||||
{
|
||||
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(_)).Times(AnyNumber());
|
||||
|
||||
ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
|
||||
|
||||
EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message));
|
||||
@@ -95,14 +95,15 @@ TEST_F(ProjectUpdater, CallRemovePchProjectParts)
|
||||
updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
|
||||
}
|
||||
|
||||
TEST_F(ProjectUpdater, CallPrecompiledHeaderRemoved)
|
||||
TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
|
||||
{
|
||||
ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer, pchManagerClient};
|
||||
ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
|
||||
|
||||
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString()));
|
||||
EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId2.toQString()));
|
||||
|
||||
updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
|
||||
pchUpdater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
|
||||
}
|
||||
|
||||
TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
|
||||
|
@@ -47,6 +47,11 @@ using ::testing::Args;
|
||||
using ::testing::Property;
|
||||
using ::testing::Eq;
|
||||
|
||||
using ClangBackEnd::UpdatePchProjectPartsMessage;
|
||||
using ClangBackEnd::V2::FileContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::RemovePchProjectPartsMessage;
|
||||
|
||||
class RefactoringClientServerInProcess : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@@ -169,6 +174,31 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage)
|
||||
scheduleServerMessages();
|
||||
}
|
||||
|
||||
TEST_F(RefactoringClientServerInProcess, SendUpdatePchProjectPartsMessage)
|
||||
{
|
||||
ProjectPartContainer projectPart2{"projectPartId",
|
||||
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{TESTDATA_DIR "/includecollector_header.h"},
|
||||
{TESTDATA_DIR "/includecollector_main.cpp"}};
|
||||
FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
|
||||
UpdatePchProjectPartsMessage message{{projectPart2}, {fileContainer}};
|
||||
|
||||
EXPECT_CALL(mockRefactoringServer, updatePchProjectParts(message));
|
||||
|
||||
serverProxy.updatePchProjectParts(message.clone());
|
||||
scheduleServerMessages();
|
||||
}
|
||||
|
||||
TEST_F(RefactoringClientServerInProcess, SendRemovePchProjectPartsMessage)
|
||||
{
|
||||
RemovePchProjectPartsMessage message{{"projectPartId1", "projectPartId2"}};
|
||||
|
||||
EXPECT_CALL(mockRefactoringServer, removePchProjectParts(message));
|
||||
|
||||
serverProxy.removePchProjectParts(message.clone());
|
||||
scheduleServerMessages();
|
||||
}
|
||||
|
||||
TEST_F(RefactoringClientServerInProcess, CancelMessage)
|
||||
{
|
||||
EXPECT_CALL(mockRefactoringServer, cancel());
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "filesystem-utilities.h"
|
||||
#include "mockrefactoringclient.h"
|
||||
#include "mocksymbolindexing.h"
|
||||
#include "sourcerangecontainer-matcher.h"
|
||||
|
||||
#include <refactoringserver.h>
|
||||
@@ -57,6 +58,9 @@ using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
|
||||
using ClangBackEnd::SourceRangesForQueryMessage;
|
||||
using ClangBackEnd::SourceRangesContainer;
|
||||
using ClangBackEnd::V2::FileContainer;
|
||||
using ClangBackEnd::V2::FileContainers;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainers;
|
||||
|
||||
MATCHER_P2(IsSourceLocation, line, column,
|
||||
std::string(negation ? "isn't " : "is ")
|
||||
@@ -76,8 +80,10 @@ protected:
|
||||
void TearDown() override;
|
||||
|
||||
protected:
|
||||
ClangBackEnd::RefactoringServer refactoringServer;
|
||||
NiceMock<MockRefactoringClient> mockRefactoringClient;
|
||||
NiceMock<MockSymbolIndexing> mockSymbolIndexing;
|
||||
ClangBackEnd::FilePathCache<std::mutex> filePathCache;
|
||||
ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing, filePathCache};
|
||||
Utils::SmallString sourceContent{"void f()\n {}"};
|
||||
FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
|
||||
sourceContent.clone(),
|
||||
@@ -283,6 +289,23 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
|
||||
refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
|
||||
}
|
||||
|
||||
TEST_F(RefactoringServer, UpdatePchProjectPartsCallsSymbolIndexingUpdateProjectParts)
|
||||
{
|
||||
ProjectPartContainers projectParts{{{"projectPartId",
|
||||
{"-I", TESTDATA_DIR},
|
||||
{"header1.h"},
|
||||
{"main.cpp"}}}};
|
||||
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||
"void f();",
|
||||
{}}};
|
||||
|
||||
|
||||
EXPECT_CALL(mockSymbolIndexing,
|
||||
updateProjectParts(projectParts, unsaved));
|
||||
|
||||
refactoringServer.updatePchProjectParts({Utils::clone(projectParts), Utils::clone(unsaved)});
|
||||
}
|
||||
|
||||
void RefactoringServer::SetUp()
|
||||
{
|
||||
temporaryFile.open();
|
||||
|
@@ -96,6 +96,18 @@ TEST_F(SqliteDatabase, AddTable)
|
||||
ASSERT_THAT(database.tables(), Contains(sqliteTable));
|
||||
}
|
||||
|
||||
TEST_F(SqliteDatabase, TableIsReadyAfterOpenDatabase)
|
||||
{
|
||||
database.close();
|
||||
auto &table = database.addTable();
|
||||
table.setName("foo");
|
||||
table.addColumn("name");
|
||||
|
||||
database.open();
|
||||
|
||||
ASSERT_TRUE(table.isReady());
|
||||
}
|
||||
|
||||
void SqliteDatabase::SetUp()
|
||||
{
|
||||
database.setJournalMode(JournalMode::Memory);
|
||||
|
66
tests/unit/unittest/sqliteindex-test.cpp
Normal file
66
tests/unit/unittest/sqliteindex-test.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "googletest.h"
|
||||
|
||||
#include <sqliteindex.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::SqliteException;
|
||||
using Sqlite::SqliteIndex;
|
||||
|
||||
TEST(SqliteIndex, OneColumn)
|
||||
{
|
||||
SqliteIndex index{"tableName", {"column1"}};
|
||||
|
||||
auto sqlStatement = index.sqlStatement();
|
||||
|
||||
ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)"));
|
||||
}
|
||||
|
||||
TEST(SqliteIndex, TwoColumn)
|
||||
{
|
||||
SqliteIndex index{"tableName", {"column1", "column2"}};
|
||||
|
||||
auto sqlStatement = index.sqlStatement();
|
||||
|
||||
ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1_column2 ON tableName(column1, column2)"));
|
||||
}
|
||||
|
||||
TEST(SqliteIndex, EmptyTableName)
|
||||
{
|
||||
SqliteIndex index{"", {"column1", "column2"}};
|
||||
|
||||
ASSERT_THROW(index.sqlStatement(), SqliteException);
|
||||
}
|
||||
|
||||
TEST(SqliteIndex, EmptyColumns)
|
||||
{
|
||||
SqliteIndex index{"tableName", {}};
|
||||
|
||||
ASSERT_THROW(index.sqlStatement(), SqliteException);
|
||||
}
|
||||
}
|
@@ -27,7 +27,7 @@
|
||||
#include "spydummy.h"
|
||||
|
||||
#include <sqlitecolumn.h>
|
||||
#include <sqlitedatabase.h>
|
||||
#include <mocksqlitedatabase.h>
|
||||
#include <sqlitetable.h>
|
||||
|
||||
namespace {
|
||||
@@ -41,13 +41,8 @@ using Sqlite::SqliteDatabase;
|
||||
class SqliteTable : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
protected:
|
||||
SpyDummy spyDummy;
|
||||
SqliteDatabase database;
|
||||
Sqlite::SqliteTable &table = database.addTable();
|
||||
NiceMock<MockSqliteDatabase> mockDatabase;
|
||||
Sqlite::SqliteTable table;
|
||||
Utils::SmallString tableName = "testTable";
|
||||
};
|
||||
|
||||
@@ -73,26 +68,46 @@ TEST_F(SqliteTable, SetUseWithoutRowid)
|
||||
ASSERT_TRUE(table.useWithoutRowId());
|
||||
}
|
||||
|
||||
TEST_F(SqliteTable, TableIsReadyAfterOpenDatabase)
|
||||
TEST_F(SqliteTable, AddIndex)
|
||||
{
|
||||
table.setName(tableName.clone());
|
||||
auto &column = table.addColumn("name");
|
||||
auto &column2 = table.addColumn("value");
|
||||
|
||||
auto index = table.addIndex({column, column2});
|
||||
|
||||
ASSERT_THAT(Utils::SmallStringView(index.sqlStatement()),
|
||||
Eq("CREATE INDEX IF NOT EXISTS index_testTable_name_value ON testTable(name, value)"));
|
||||
}
|
||||
|
||||
TEST_F(SqliteTable, InitializeTable)
|
||||
{
|
||||
table.setName(tableName.clone());
|
||||
table.setUseIfNotExists(true);
|
||||
table.setUseTemporaryTable(true);
|
||||
table.setUseWithoutRowId(true);
|
||||
table.addColumn("name");
|
||||
table.addColumn("value");
|
||||
|
||||
database.open();
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE IF NOT EXISTS testTable(name NUMERIC, value NUMERIC) WITHOUT ROWID")));
|
||||
|
||||
ASSERT_TRUE(table.isReady());
|
||||
table.initialize(mockDatabase);
|
||||
}
|
||||
|
||||
void SqliteTable::SetUp()
|
||||
TEST_F(SqliteTable, InitializeTableWithIndex)
|
||||
{
|
||||
database.setJournalMode(JournalMode::Memory);
|
||||
database.setDatabaseFilePath( QStringLiteral(":memory:"));
|
||||
}
|
||||
InSequence sequence;
|
||||
table.setName(tableName.clone());
|
||||
auto &column = table.addColumn("name");
|
||||
auto &column2 = table.addColumn("value");
|
||||
table.addIndex({column});
|
||||
table.addIndex({column2});
|
||||
|
||||
void SqliteTable::TearDown()
|
||||
{
|
||||
if (database.isOpen())
|
||||
database.close();
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE testTable(name NUMERIC, value NUMERIC)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value)")));
|
||||
|
||||
table.initialize(mockDatabase);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -52,6 +52,7 @@ TEST_F(StorageSqliteStatementFactory, AddSymbolsTable)
|
||||
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
|
||||
|
||||
factory.createSymbolsTable();
|
||||
@@ -63,6 +64,7 @@ TEST_F(StorageSqliteStatementFactory, AddLocationsTable)
|
||||
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId ON locations(sourceId)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
|
||||
|
||||
factory.createLocationsTable();
|
||||
@@ -85,6 +87,8 @@ TEST_F(StorageSqliteStatementFactory, AddNewSymbolsTable)
|
||||
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
|
||||
|
||||
factory.createNewSymbolsTable();
|
||||
@@ -97,6 +101,7 @@ TEST_F(StorageSqliteStatementFactory, AddNewLocationsTable)
|
||||
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
|
||||
|
||||
factory.createNewLocationsTable();
|
||||
@@ -108,10 +113,15 @@ TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor)
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))).Times(5);
|
||||
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId ON locations(sourceId)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
|
||||
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)")));
|
||||
|
||||
StatementFactory factory{mockDatabase};
|
||||
}
|
||||
@@ -137,7 +147,7 @@ TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement)
|
||||
TEST_F(StorageSqliteStatementFactory, AddNewSymbolsToSymbolsStatement)
|
||||
{
|
||||
ASSERT_THAT(factory.addNewSymbolsToSymbolsStatement.sqlStatement,
|
||||
Eq("INSERT INTO symbols(usr, symbolname) SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE usr == newsymbols.usr)"));
|
||||
Eq("INSERT INTO symbols(usr, symbolName) SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)"));
|
||||
}
|
||||
|
||||
TEST_F(StorageSqliteStatementFactory, InsertSourcesStatement)
|
||||
|
@@ -46,6 +46,7 @@ using testing::Sequence;
|
||||
using Utils::PathString;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainers;
|
||||
using ClangBackEnd::V2::FileContainers;
|
||||
using ClangBackEnd::SymbolEntries;
|
||||
using ClangBackEnd::SymbolEntry;
|
||||
using ClangBackEnd::SourceLocationEntries;
|
||||
@@ -72,6 +73,9 @@ protected:
|
||||
{"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"},
|
||||
{header2Path.clone()},
|
||||
{main2Path.clone()}};
|
||||
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
|
||||
"void f();",
|
||||
{}}};
|
||||
SymbolEntries symbolEntries{{1, {"function", "function"}}};
|
||||
SourceLocationEntries sourceLocations{{1, 1, {42, 23}, SymbolType::Declaration}};
|
||||
NiceMock<MockSymbolsCollector> mockCollector;
|
||||
@@ -83,7 +87,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector)
|
||||
{
|
||||
EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePaths(), projectPart1.arguments()));
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollectorForEveryProjectPart)
|
||||
@@ -91,7 +95,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollectorForEveryProjectP
|
||||
EXPECT_CALL(mockCollector, addFiles(_, _))
|
||||
.Times(2);
|
||||
|
||||
indexer.updateProjectParts({projectPart1, projectPart2});
|
||||
indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEveryProjectParts)
|
||||
@@ -99,48 +103,54 @@ TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEv
|
||||
EXPECT_CALL(mockCollector, addFiles(_, _))
|
||||
.Times(0);
|
||||
|
||||
indexer.updateProjectParts({});
|
||||
indexer.updateProjectParts({}, {});
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallscollectSymbolsInCollector)
|
||||
{
|
||||
EXPECT_CALL(mockCollector, collectSymbols());
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsSymbolsInCollector)
|
||||
{
|
||||
EXPECT_CALL(mockCollector, symbols());
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsSourceLocationsInCollector)
|
||||
{
|
||||
EXPECT_CALL(mockCollector, sourceLocations());
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddUnsavedFilesInCollector)
|
||||
{
|
||||
EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved));
|
||||
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddSymbolsAndSourceLocationsInStorage)
|
||||
{
|
||||
EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder)
|
||||
{
|
||||
Sequence sequence;
|
||||
|
||||
EXPECT_CALL(mockCollector, addFiles(_, _));
|
||||
EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved));
|
||||
EXPECT_CALL(mockCollector, collectSymbols());
|
||||
EXPECT_CALL(mockCollector, symbols());
|
||||
EXPECT_CALL(mockCollector, sourceLocations());
|
||||
EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
|
||||
|
||||
indexer.updateProjectParts({projectPart1});
|
||||
indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
|
||||
}
|
||||
|
||||
void SymbolIndexer::SetUp()
|
||||
|
112
tests/unit/unittest/symbolindexing-test.cpp
Normal file
112
tests/unit/unittest/symbolindexing-test.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 "googletest.h"
|
||||
|
||||
#include <projectpartcontainerv2.h>
|
||||
|
||||
#include <symbolindexing.h>
|
||||
#include <symbolquery.h>
|
||||
#include <querysqlitestatementfactory.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
namespace {
|
||||
|
||||
using Sqlite::SqliteDatabase;
|
||||
using Sqlite::SqliteReadStatement;
|
||||
using ClangBackEnd::SymbolIndexer;
|
||||
using ClangBackEnd::SymbolsCollector;
|
||||
using ClangBackEnd::SymbolStorage;
|
||||
using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangBackEnd::V2::ProjectPartContainer;
|
||||
using ClangRefactoring::SymbolQuery;
|
||||
using ClangRefactoring::QuerySqliteStatementFactory;
|
||||
using Utils::PathString;
|
||||
using SL = ClangRefactoring::SourceLocations;
|
||||
|
||||
using StatementFactory = QuerySqliteStatementFactory<SqliteDatabase, SqliteReadStatement>;
|
||||
using Query = SymbolQuery<StatementFactory>;
|
||||
|
||||
MATCHER_P3(IsLocation, sourceId, line, column,
|
||||
std::string(negation ? "isn't" : "is")
|
||||
+ " source id " + PrintToString(sourceId)
|
||||
+ " line " + PrintToString(line)
|
||||
+ " and column " + PrintToString(column)
|
||||
)
|
||||
{
|
||||
const SL::Location &location = arg;
|
||||
|
||||
return location.sourceId == sourceId
|
||||
&& location.line == line
|
||||
&& location.column == column;
|
||||
};
|
||||
|
||||
class SymbolIndexing : public testing::Test
|
||||
{
|
||||
protected:
|
||||
FilePathCache<std::mutex> filePathCache;
|
||||
ClangBackEnd::SymbolIndexing indexing{filePathCache, QDir::tempPath() + "/symbol.db"};
|
||||
StatementFactory queryFactory{indexing.database()};
|
||||
Query query{queryFactory};
|
||||
PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp";
|
||||
ProjectPartContainer projectPart1{"project1",
|
||||
{"cc", "-I", TESTDATA_DIR, "-std=c++1z"},
|
||||
{},
|
||||
{main1Path.clone()}};
|
||||
};
|
||||
|
||||
TEST_F(SymbolIndexing, Locations)
|
||||
{
|
||||
indexing.indexer().updateProjectParts({projectPart1}, {});
|
||||
|
||||
auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 6, 5);
|
||||
ASSERT_THAT(locations.locations,
|
||||
ElementsAre(
|
||||
IsLocation(0, 5, 9),
|
||||
IsLocation(0, 6, 5)));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexing, Sources)
|
||||
{
|
||||
indexing.indexer().updateProjectParts({projectPart1}, {});
|
||||
|
||||
auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 6, 5);
|
||||
ASSERT_THAT(locations.sources, ElementsAre(Pair(0, Eq(TESTDATA_DIR "/symbolindexing_main1.cpp"))));
|
||||
}
|
||||
|
||||
TEST_F(SymbolIndexing, DISABLED_TemplateFunction)
|
||||
{
|
||||
indexing.indexer().updateProjectParts({projectPart1}, {});
|
||||
|
||||
auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 21, 24);
|
||||
ASSERT_THAT(locations.locations,
|
||||
ElementsAre(
|
||||
IsLocation(0, 5, 9),
|
||||
IsLocation(0, 6, 5)));
|
||||
}
|
||||
}
|
@@ -39,6 +39,7 @@ using testing::Pair;
|
||||
using testing::Value;
|
||||
using testing::_;
|
||||
|
||||
using ClangBackEnd::V2::FileContainers;
|
||||
using ClangBackEnd::SourceLocationEntry;
|
||||
using ClangBackEnd::SymbolEntry;
|
||||
using ClangBackEnd::SymbolType;
|
||||
@@ -57,7 +58,7 @@ protected:
|
||||
SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName);
|
||||
|
||||
protected:
|
||||
ClangBackEnd::FilePathCache<> filePathCache;
|
||||
ClangBackEnd::FilePathCache<std::mutex> filePathCache;
|
||||
ClangBackEnd::SymbolsCollector collector{filePathCache};
|
||||
};
|
||||
|
||||
@@ -150,6 +151,21 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
|
||||
Field(&SourceLocationEntry::column, 5))));
|
||||
}
|
||||
|
||||
TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile))
|
||||
{
|
||||
FileContainers unsaved{{{TESTDATA_DIR, "symbolscollector_generated_file.h"},
|
||||
"void function();",
|
||||
{}}};
|
||||
collector.addFile(TESTDATA_DIR, "symbolscollector_unsaved.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_unsaved.cpp"});
|
||||
collector.addUnsavedFiles(std::move(unsaved));
|
||||
|
||||
collector.collectSymbols();
|
||||
|
||||
ASSERT_THAT(collector.symbols(),
|
||||
Contains(
|
||||
Pair(_, Field(&SymbolEntry::symbolName, "function"))));
|
||||
}
|
||||
|
||||
SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName)
|
||||
{
|
||||
for (const auto &entry : collector.symbols()) {
|
||||
|
@@ -58,7 +58,7 @@ protected:
|
||||
void SetUp();
|
||||
|
||||
protected:
|
||||
FilePathCache<> filePathCache;
|
||||
FilePathCache<std::mutex> filePathCache;
|
||||
NiceMock<MockSqliteDatabase> mockDatabase;
|
||||
StatementFactory statementFactory{mockDatabase};
|
||||
|
||||
|
@@ -74,7 +74,9 @@ SOURCES += \
|
||||
mocksqlitereadstatement.cpp \
|
||||
symbolquery-test.cpp \
|
||||
storagesqlitestatementfactory-test.cpp \
|
||||
querysqlitestatementfactory-test.cpp
|
||||
querysqlitestatementfactory-test.cpp \
|
||||
symbolindexing-test.cpp \
|
||||
sqliteindex-test.cpp
|
||||
|
||||
!isEmpty(LIBCLANG_LIBS) {
|
||||
SOURCES += \
|
||||
@@ -197,7 +199,8 @@ HEADERS += \
|
||||
mocksqlitewritestatement.h \
|
||||
mocksqlitedatabase.h \
|
||||
mocksqlitereadstatement.h \
|
||||
google-using-declarations.h
|
||||
google-using-declarations.h \
|
||||
mocksymbolindexing.h
|
||||
|
||||
!isEmpty(LIBCLANG_LIBS) {
|
||||
HEADERS += \
|
||||
|
Reference in New Issue
Block a user