summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2017-08-17 12:44:52 +0200
committerMarco Bubke <marco.bubke@qt.io>2017-09-14 13:39:55 +0000
commit3adb71d45ebebd8c8fc2ec6beeb7a5ee67d64e4e (patch)
tree7bbe767ce3f6c39f4e19428dc67e5ddb6f6c233e
parent8488ce627b82238c7737c24909d7f6164b2061dd (diff)
downloadqt-creator-3adb71d45ebebd8c8fc2ec6beeb7a5ee67d64e4e.tar.gz
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>
-rw-r--r--src/libs/clangsupport/clangrefactoringservermessages.h2
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri3
-rw-r--r--src/libs/clangsupport/pchmanagerserverinterface.h7
-rw-r--r--src/libs/clangsupport/projectmanagementserverinterface.h42
-rw-r--r--src/libs/clangsupport/refactoringserverinterface.cpp6
-rw-r--r--src/libs/clangsupport/refactoringserverinterface.h6
-rw-r--r--src/libs/clangsupport/refactoringserverproxy.cpp10
-rw-r--r--src/libs/clangsupport/refactoringserverproxy.h2
-rw-r--r--src/libs/clangsupport/stringcache.h19
-rw-r--r--src/libs/sqlite/sqlite-lib.pri3
-rw-r--r--src/libs/sqlite/sqlitecolumn.h4
-rw-r--r--src/libs/sqlite/sqliteindex.h82
-rw-r--r--src/libs/sqlite/sqlitetable.h53
-rw-r--r--src/libs/sqlite/sqlitetransaction.h5
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager-source.pri6
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.cpp2
-rw-r--r--src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp47
-rw-r--r--src/plugins/clangpchmanager/pchmanagerprojectupdater.h44
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp9
-rw-r--r--src/plugins/clangpchmanager/projectupdater.h10
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp39
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.h56
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring-source.pri6
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring_dependencies.pri3
-rw-r--r--src/plugins/clangrefactoring/clangrefactoringplugin.cpp6
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.cpp37
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.h41
-rw-r--r--src/plugins/clangrefactoring/sourcelocations.h7
-rw-r--r--src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp13
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri7
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.h7
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsaction.h6
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h12
-rw-r--r--src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h18
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.cpp18
-rw-r--r--src/tools/clangrefactoringbackend/source/refactoringserver.h9
-rw-r--r--src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h53
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp5
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.cpp30
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h84
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexinginterface.h40
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.cpp7
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.h7
-rw-r--r--tests/unit/unittest/data/symbolindexing_main1.cpp36
-rw-r--r--tests/unit/unittest/data/symbolscollector_unsaved.cpp1
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h2
-rw-r--r--tests/unit/unittest/mockrefactoringserver.h16
-rw-r--r--tests/unit/unittest/mocksymbolindexing.h45
-rw-r--r--tests/unit/unittest/mocksymbolscollector.h3
-rw-r--r--tests/unit/unittest/pchmanagerclient-test.cpp4
-rw-r--r--tests/unit/unittest/projectupdater-test.cpp11
-rw-r--r--tests/unit/unittest/refactoringclientserverinprocess-test.cpp30
-rw-r--r--tests/unit/unittest/refactoringserver-test.cpp25
-rw-r--r--tests/unit/unittest/sqlitedatabase-test.cpp12
-rw-r--r--tests/unit/unittest/sqliteindex-test.cpp66
-rw-r--r--tests/unit/unittest/sqlitetable-test.cpp51
-rw-r--r--tests/unit/unittest/storagesqlitestatementfactory-test.cpp12
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp30
-rw-r--r--tests/unit/unittest/symbolindexing-test.cpp112
-rw-r--r--tests/unit/unittest/symbolscollector-test.cpp18
-rw-r--r--tests/unit/unittest/symbolstorage-test.cpp2
-rw-r--r--tests/unit/unittest/unittest.pro7
65 files changed, 1194 insertions, 174 deletions
diff --git a/src/libs/clangsupport/clangrefactoringservermessages.h b/src/libs/clangsupport/clangrefactoringservermessages.h
index 797b3d58ef..2be6f0d54d 100644
--- a/src/libs/clangsupport/clangrefactoringservermessages.h
+++ b/src/libs/clangsupport/clangrefactoringservermessages.h
@@ -30,3 +30,5 @@
#include "requestsourcelocationforrenamingmessage.h"
#include "requestsourcerangesanddiagnosticsforquerymessage.h"
#include "requestsourcerangesforquerymessage.h"
+#include "updatepchprojectpartsmessage.h"
+#include "removepchprojectpartsmessage.h"
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index c6584b24b0..f7bd2674ae 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -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
diff --git a/src/libs/clangsupport/pchmanagerserverinterface.h b/src/libs/clangsupport/pchmanagerserverinterface.h
index 58ce649997..6af04c91fe 100644
--- a/src/libs/clangsupport/pchmanagerserverinterface.h
+++ b/src/libs/clangsupport/pchmanagerserverinterface.h
@@ -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
diff --git a/src/libs/clangsupport/projectmanagementserverinterface.h b/src/libs/clangsupport/projectmanagementserverinterface.h
new file mode 100644
index 0000000000..5704db417c
--- /dev/null
+++ b/src/libs/clangsupport/projectmanagementserverinterface.h
@@ -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
diff --git a/src/libs/clangsupport/refactoringserverinterface.cpp b/src/libs/clangsupport/refactoringserverinterface.cpp
index d6b0f6815b..52ab7834b0 100644
--- a/src/libs/clangsupport/refactoringserverinterface.cpp
+++ b/src/libs/clangsupport/refactoringserverinterface.cpp
@@ -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;
diff --git a/src/libs/clangsupport/refactoringserverinterface.h b/src/libs/clangsupport/refactoringserverinterface.h
index 8c36a7351e..a4a3b1e6f4 100644
--- a/src/libs/clangsupport/refactoringserverinterface.h
+++ b/src/libs/clangsupport/refactoringserverinterface.h
@@ -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:
diff --git a/src/libs/clangsupport/refactoringserverproxy.cpp b/src/libs/clangsupport/refactoringserverproxy.cpp
index 0cf4473f07..cc6741b118 100644
--- a/src/libs/clangsupport/refactoringserverproxy.cpp
+++ b/src/libs/clangsupport/refactoringserverproxy.cpp
@@ -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());
diff --git a/src/libs/clangsupport/refactoringserverproxy.h b/src/libs/clangsupport/refactoringserverproxy.h
index 9b10e37529..611155b511 100644
--- a/src/libs/clangsupport/refactoringserverproxy.h
+++ b/src/libs/clangsupport/refactoringserverproxy.h
@@ -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();
diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h
index e38649488c..6d5f4e986b 100644
--- a/src/libs/clangsupport/stringcache.h
+++ b/src/libs/clangsupport/stringcache.h
@@ -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);
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
index a953a70e0a..67c8c6b937 100644
--- a/src/libs/sqlite/sqlite-lib.pri
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -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
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
index e25ee68b2d..a253aee488 100644
--- a/src/libs/sqlite/sqlitecolumn.h
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -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
diff --git a/src/libs/sqlite/sqliteindex.h b/src/libs/sqlite/sqliteindex.h
new file mode 100644
index 0000000000..a6d92432d3
--- /dev/null
+++ b/src/libs/sqlite/sqliteindex.h
@@ -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>;
+
+} //
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index d9e7d5cd16..be63e5ae5e 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -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)
@@ -117,8 +134,20 @@ public:
}
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;
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h
index 373b33fd8a..2b817123f1 100644
--- a/src/libs/sqlite/sqlitetransaction.h
+++ b/src/libs/sqlite/sqlitetransaction.h
@@ -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
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
index fd5b61a24d..25d8d63730 100644
--- a/src/plugins/clangpchmanager/clangpchmanager-source.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -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
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
index 4c53696807..086b2fce8e 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.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;
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
new file mode 100644
index 0000000000..d74ea2a7b0
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
@@ -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
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.h b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
new file mode 100644
index 0000000000..0849554751
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
@@ -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
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index 9d5d7c7577..046c5f769f 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -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)
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
index 60fd636408..e207a88971 100644
--- a/src/plugins/clangpchmanager/projectupdater.h
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -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
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
index 6ac93c747a..53b37ee2b5 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
@@ -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()
-{
- return CppTools::CppModelManager::instance();
-}
+namespace Internal {
-QtCreatorProjectUpdater::QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
- PchManagerClient &client)
- : ProjectUpdater(server, client)
+CppTools::CppModelManager *cppModelManager()
{
- connectToCppModelManager();
+ return CppTools::CppModelManager::instance();
}
-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
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
index ec99eab50e..44858ef936 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -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();
+ }
+
+ QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
+ : ProjectUpdaterType(server)
+ {
+ connectToCppModelManager();
+ }
+
+ void projectPartsUpdated(ProjectExplorer::Project *project)
+ {
+ ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project),
+ Internal::createGeneratedFiles());
+ }
- void projectPartsUpdated(ProjectExplorer::Project *project);
- void projectPartsRemoved(const QStringList &projectPartIds);
+ 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
diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri
index 24102dfd99..b08d292190 100644
--- a/src/plugins/clangrefactoring/clangrefactoring-source.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri
@@ -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
diff --git a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
index ed775ae4fc..8a08236177 100644
--- a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
@@ -5,4 +5,5 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
cpptools \
- texteditor
+ texteditor \
+ clangpchmanager
diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
index 921cc24005..ea17409fac 100644
--- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
+++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
@@ -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()
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
new file mode 100644
index 0000000000..07a9e97163
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
@@ -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
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.h b/src/plugins/clangrefactoring/refactoringprojectupdater.h
new file mode 100644
index 0000000000..3debed0c4d
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.h
@@ -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
diff --git a/src/plugins/clangrefactoring/sourcelocations.h b/src/plugins/clangrefactoring/sourcelocations.h
index e4cb1df450..fe2d3dace9 100644
--- a/src/plugins/clangrefactoring/sourcelocations.h
+++ b/src/plugins/clangrefactoring/sourcelocations.h
@@ -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;
};
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
index fca9a0c9fc..fcf6f12f1f 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
@@ -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();
}
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index 21748bb071..8ed0c6803c 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index 7957bb7044..0f436a0e37 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
index ceaf0ee85b..1ddd34b595 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
@@ -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;
};
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
index 837ede57da..fcedd6a6d0 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
@@ -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;
};
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
index 035db37ebc..0eeb7a73f2 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
@@ -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;
};
}
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index 043fa87711..84b588118e 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -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()
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h
index 33eaee2a0a..b11cf3fc21 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
index 22bd7cf5f5..8e1149ca3f 100644
--- a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
+++ b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 477c7c72f4..ed48d920a6 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -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(),
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h
index 625fc21c98..283e761da5 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h
@@ -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;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.cpp b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
new file mode 100644
index 0000000000..11e34e449f
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
new file mode 100644
index 0000000000..2986f6e4ce
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
new file mode 100644
index 0000000000..8c331aadce
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
@@ -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
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
index f83d71e1c1..c759232a04 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -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();
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
index d0eb020158..6bbdfbcf9e 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -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;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
index a34705382e..fcb909bdc8 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
@@ -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;
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
index 12163b0f25..cbe2e570da 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorage.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -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
diff --git a/tests/unit/unittest/data/symbolindexing_main1.cpp b/tests/unit/unittest/data/symbolindexing_main1.cpp
new file mode 100644
index 0000000000..58df77916a
--- /dev/null
+++ b/tests/unit/unittest/data/symbolindexing_main1.cpp
@@ -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);
diff --git a/tests/unit/unittest/data/symbolscollector_unsaved.cpp b/tests/unit/unittest/data/symbolscollector_unsaved.cpp
new file mode 100644
index 0000000000..a57a4e69f7
--- /dev/null
+++ b/tests/unit/unittest/data/symbolscollector_unsaved.cpp
@@ -0,0 +1 @@
+#include "symbolscollector_generated_file.h"
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index 7792475d8f..814130f227 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/smallstringio.h>
+
#include <QtGlobal>
#include <iosfwd>
diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h
index abafc15244..c265f88cbc 100644
--- a/tests/unit/unittest/mockrefactoringserver.h
+++ b/tests/unit/unittest/mockrefactoringserver.h
@@ -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);
+ }
};
diff --git a/tests/unit/unittest/mocksymbolindexing.h b/tests/unit/unittest/mocksymbolindexing.h
new file mode 100644
index 0000000000..8a42ebfbc9
--- /dev/null
+++ b/tests/unit/unittest/mocksymbolindexing.h
@@ -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);
+ }
+};
+
diff --git a/tests/unit/unittest/mocksymbolscollector.h b/tests/unit/unittest/mocksymbolscollector.h
index 75e7b74423..14f8f6cdf5 100644
--- a/tests/unit/unittest/mocksymbolscollector.h
+++ b/tests/unit/unittest/mocksymbolscollector.h
@@ -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 &());
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
index 3f26243cc5..53a544841d 100644
--- a/tests/unit/unittest/pchmanagerclient-test.cpp
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -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()}}};
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
index 98cb1b05d8..071f9ea5db 100644
--- a/tests/unit/unittest/projectupdater-test.cpp
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -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)
diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
index aaac7c1433..f1ce7a9f5f 100644
--- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
@@ -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());
diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp
index b07d490a12..8b2586ba0b 100644
--- a/tests/unit/unittest/refactoringserver-test.cpp
+++ b/tests/unit/unittest/refactoringserver-test.cpp
@@ -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();
diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp
index 85b8a68e80..7c9cd9cf0e 100644
--- a/tests/unit/unittest/sqlitedatabase-test.cpp
+++ b/tests/unit/unittest/sqlitedatabase-test.cpp
@@ -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);
diff --git a/tests/unit/unittest/sqliteindex-test.cpp b/tests/unit/unittest/sqliteindex-test.cpp
new file mode 100644
index 0000000000..dcf02fa02c
--- /dev/null
+++ b/tests/unit/unittest/sqliteindex-test.cpp
@@ -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);
+}
+}
diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp
index 7873181580..fc5917d296 100644
--- a/tests/unit/unittest/sqlitetable-test.cpp
+++ b/tests/unit/unittest/sqlitetable-test.cpp
@@ -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());
- table.addColumn("name");
+ auto &column = table.addColumn("name");
+ auto &column2 = table.addColumn("value");
- database.open();
+ auto index = table.addIndex({column, column2});
- ASSERT_TRUE(table.isReady());
+ ASSERT_THAT(Utils::SmallStringView(index.sqlStatement()),
+ Eq("CREATE INDEX IF NOT EXISTS index_testTable_name_value ON testTable(name, value)"));
}
-void SqliteTable::SetUp()
+TEST_F(SqliteTable, InitializeTable)
{
- database.setJournalMode(JournalMode::Memory);
- database.setDatabaseFilePath( QStringLiteral(":memory:"));
+ table.setName(tableName.clone());
+ table.setUseIfNotExists(true);
+ table.setUseTemporaryTable(true);
+ table.setUseWithoutRowId(true);
+ table.addColumn("name");
+ table.addColumn("value");
+
+ EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE IF NOT EXISTS testTable(name NUMERIC, value NUMERIC) WITHOUT ROWID")));
+
+ table.initialize(mockDatabase);
}
-void SqliteTable::TearDown()
+TEST_F(SqliteTable, InitializeTableWithIndex)
{
- if (database.isOpen())
- database.close();
+ InSequence sequence;
+ table.setName(tableName.clone());
+ auto &column = table.addColumn("name");
+ auto &column2 = table.addColumn("value");
+ table.addIndex({column});
+ table.addIndex({column2});
+
+ 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);
}
}
diff --git a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
index 98c99d908e..1553ad76f9 100644
--- a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
+++ b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
@@ -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)
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index 35a09fbef0..6684b2cddb 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -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()
diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp
new file mode 100644
index 0000000000..1ed64e6deb
--- /dev/null
+++ b/tests/unit/unittest/symbolindexing-test.cpp
@@ -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)));
+}
+}
diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp
index 4543c61e44..9b1f046cbd 100644
--- a/tests/unit/unittest/symbolscollector-test.cpp
+++ b/tests/unit/unittest/symbolscollector-test.cpp
@@ -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()) {
diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp
index ec30b9289d..fbe9ab9cc4 100644
--- a/tests/unit/unittest/symbolstorage-test.cpp
+++ b/tests/unit/unittest/symbolstorage-test.cpp
@@ -58,7 +58,7 @@ protected:
void SetUp();
protected:
- FilePathCache<> filePathCache;
+ FilePathCache<std::mutex> filePathCache;
NiceMock<MockSqliteDatabase> mockDatabase;
StatementFactory statementFactory{mockDatabase};
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index db1b818c8a..1f1b490536 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -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 += \