Clang: Don't reparse if the macros haven't changed

We have to extend that to include paths too, which will be happen in a
follow up patch.

Change-Id: I7f8ac663ae8588e647fc6a6b5d689a629a28ef65
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-02-07 16:18:16 +01:00
parent b5c3d5a40d
commit 0172631b48
13 changed files with 140 additions and 21 deletions

View File

@@ -123,10 +123,14 @@ QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(CppTools::ProjectPart *projectPart) ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(CppTools::ProjectPart *projectPart)
{ {
return Utils::transform<ClangBackEnd::CompilerMacros>(projectPart->projectMacros, auto macros = Utils::transform<ClangBackEnd::CompilerMacros>(projectPart->projectMacros,
[] (const ProjectExplorer::Macro &macro) { [] (const ProjectExplorer::Macro &macro) {
return ClangBackEnd::CompilerMacro{macro.key, macro.value}; return ClangBackEnd::CompilerMacro{macro.key, macro.value};
}); });
std::sort(macros.begin(), macros.end());
return macros;
} }
ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer( ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(

View File

@@ -18,6 +18,7 @@ HEADERS += \
$$PWD/usedmacro.h \ $$PWD/usedmacro.h \
$$PWD/sourcedependency.h \ $$PWD/sourcedependency.h \
$$PWD/filestatus.h \ $$PWD/filestatus.h \
$$PWD/projectpartartefactexception.h \
$$PWD/projectpartartefact.h $$PWD/projectpartartefact.h
!isEmpty(LIBTOOLING_LIBS) { !isEmpty(LIBTOOLING_LIBS) {

View File

@@ -221,6 +221,9 @@ public:
"SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)", "SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)",
database database
}; };
ReadStatement getProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName{
"SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartName = ?",
database
};
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -52,31 +52,32 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart,
{ {
m_symbolsCollector.clear(); m_symbolsCollector.clear();
m_symbolsCollector.addFiles(projectPart.sourcePathIds(), projectPart.arguments()); if (compilerMacrosAreDifferent(projectPart)) {
m_symbolsCollector.addFiles(projectPart.sourcePathIds(), projectPart.arguments());
m_symbolsCollector.addUnsavedFiles(generatedFiles); m_symbolsCollector.addUnsavedFiles(generatedFiles);
m_symbolsCollector.collectSymbols(); m_symbolsCollector.collectSymbols();
Sqlite::ImmediateTransaction transaction{m_transactionInterface}; Sqlite::ImmediateTransaction transaction{m_transactionInterface};
m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(), m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(),
m_symbolsCollector.sourceLocations()); m_symbolsCollector.sourceLocations());
m_symbolStorage.insertOrUpdateProjectPart(projectPart.projectPartId(), m_symbolStorage.insertOrUpdateProjectPart(projectPart.projectPartId(),
projectPart.arguments(), projectPart.arguments(),
projectPart.compilerMacros()); projectPart.compilerMacros());
m_symbolStorage.updateProjectPartSources(projectPart.projectPartId(), m_symbolStorage.updateProjectPartSources(projectPart.projectPartId(),
m_symbolsCollector.sourceFiles()); m_symbolsCollector.sourceFiles());
m_symbolStorage.insertOrUpdateUsedMacros(m_symbolsCollector.usedMacros()); m_symbolStorage.insertOrUpdateUsedMacros(m_symbolsCollector.usedMacros());
m_symbolStorage.insertFileStatuses(m_symbolsCollector.fileStatuses()); m_symbolStorage.insertFileStatuses(m_symbolsCollector.fileStatuses());
m_symbolStorage.insertOrUpdateSourceDependencies(m_symbolsCollector.sourceDependencies()); m_symbolStorage.insertOrUpdateSourceDependencies(m_symbolsCollector.sourceDependencies());
transaction.commit();
transaction.commit();
}
} }
void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &) void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &)
@@ -120,4 +121,15 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId)
} }
} }
bool SymbolIndexer::compilerMacrosAreDifferent(const V2::ProjectPartContainer &projectPart) const
{
const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(
projectPart.projectPartId());
if (optionalArtefact)
return projectPart.compilerMacros() != optionalArtefact.value().compilerMacros;
return true;
}
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -52,6 +52,8 @@ public:
void pathsChanged(const FilePathIds &filePathIds) override; void pathsChanged(const FilePathIds &filePathIds) override;
void updateChangedPath(FilePathId filePath); void updateChangedPath(FilePathId filePath);
bool compilerMacrosAreDifferent(const V2::ProjectPartContainer &projectPart) const;
private: private:
SymbolsCollectorInterface &m_symbolsCollector; SymbolsCollectorInterface &m_symbolsCollector;
SymbolStorageInterface &m_symbolStorage; SymbolStorageInterface &m_symbolStorage;

View File

@@ -91,6 +91,13 @@ public:
return statement.template value<ProjectPartArtefact, 3>(sourceId.filePathId); return statement.template value<ProjectPartArtefact, 3>(sourceId.filePathId);
} }
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const override
{
ReadStatement &statement = m_statementFactory.getProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName;
return statement.template value<ProjectPartArtefact, 3>(projectPartName);
}
void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) override void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) override
{ {
WriteStatement &insertStatement = m_statementFactory.insertIntoNewUsedMacrosStatement; WriteStatement &insertStatement = m_statementFactory.insertIntoNewUsedMacrosStatement;

View File

@@ -60,6 +60,7 @@ public:
virtual void insertFileStatuses(const FileStatuses &fileStatuses) = 0; virtual void insertFileStatuses(const FileStatuses &fileStatuses) = 0;
virtual void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) = 0; virtual void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) = 0;
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0; virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0;
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const = 0;
}; };
} // namespace ClangBackEnd } // namespace ClangBackEnd

View File

@@ -93,6 +93,13 @@ MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 3>(const int&
return valueReturnProjectPartArtefact(sourceId); return valueReturnProjectPartArtefact(sourceId);
} }
template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 3>(const Utils::SmallStringView &projectPartName)
{
return valueReturnProjectPartArtefact(projectPartName);
}
template <> template <>
Utils::optional<Utils::SmallString> Utils::optional<Utils::SmallString>
MockSqliteReadStatement::value<Utils::SmallString>(const int &sourceId) MockSqliteReadStatement::value<Utils::SmallString>(const int &sourceId)

View File

@@ -82,6 +82,9 @@ public:
MOCK_METHOD1(valueReturnProjectPartArtefact, MOCK_METHOD1(valueReturnProjectPartArtefact,
Utils::optional<ClangBackEnd::ProjectPartArtefact>(int)); Utils::optional<ClangBackEnd::ProjectPartArtefact>(int));
MOCK_METHOD1(valueReturnProjectPartArtefact,
Utils::optional<ClangBackEnd::ProjectPartArtefact>(Utils::SmallStringView));
template <typename ResultType, template <typename ResultType,
int ResultTypeCount = 1, int ResultTypeCount = 1,
typename... QueryType> typename... QueryType>
@@ -150,6 +153,10 @@ template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact> Utils::optional<ClangBackEnd::ProjectPartArtefact>
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 3>(const int&); MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 3>(const int&);
template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 3>(const Utils::SmallStringView&);
template <> template <>
Utils::optional<Utils::SmallString> Utils::optional<Utils::SmallString>
MockSqliteReadStatement::value<Utils::SmallString>(const int&); MockSqliteReadStatement::value<Utils::SmallString>(const int&);

View File

@@ -55,4 +55,6 @@ public:
void (const ClangBackEnd::SourceDependencies &sourceDependencies)); void (const ClangBackEnd::SourceDependencies &sourceDependencies));
MOCK_CONST_METHOD1(fetchProjectPartArtefact, MOCK_CONST_METHOD1(fetchProjectPartArtefact,
Utils::optional<ClangBackEnd::ProjectPartArtefact> (ClangBackEnd::FilePathId sourceId)); Utils::optional<ClangBackEnd::ProjectPartArtefact> (ClangBackEnd::FilePathId sourceId));
MOCK_CONST_METHOD1(fetchProjectPartArtefact,
Utils::optional<ClangBackEnd::ProjectPartArtefact> (Utils::SmallStringView projectPartName));
}; };

View File

@@ -262,4 +262,10 @@ TEST_F(StorageSqliteStatementFactory, GetProjectPartCompilerArgumentsAndCompiler
Eq("SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)")); Eq("SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)"));
} }
TEST_F(StorageSqliteStatementFactory, GetProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName)
{
ASSERT_THAT(factory.getProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName.sqlStatement,
Eq("SELECT compilerArguments, compilerMacros, projectPartId FROM projectParts WHERE projectPartName = ?"));
}
} }

View File

@@ -39,6 +39,7 @@ namespace {
using Utils::PathString; using Utils::PathString;
using ClangBackEnd::CompilerMacro; using ClangBackEnd::CompilerMacro;
using ClangBackEnd::FileStatuses; using ClangBackEnd::FileStatuses;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathIds; using ClangBackEnd::FilePathIds;
using ClangBackEnd::FilePathView; using ClangBackEnd::FilePathView;
using ClangBackEnd::V2::ProjectPartContainer; using ClangBackEnd::V2::ProjectPartContainer;
@@ -70,7 +71,7 @@ protected:
ON_CALL(mockCollector, usedMacros()).WillByDefault(ReturnRef(usedMacros)); ON_CALL(mockCollector, usedMacros()).WillByDefault(ReturnRef(usedMacros));
ON_CALL(mockCollector, fileStatuses()).WillByDefault(ReturnRef(fileStatus)); ON_CALL(mockCollector, fileStatuses()).WillByDefault(ReturnRef(fileStatus));
ON_CALL(mockCollector, sourceDependencies()).WillByDefault(ReturnRef(sourceDependencies)); ON_CALL(mockCollector, sourceDependencies()).WillByDefault(ReturnRef(sourceDependencies));
ON_CALL(mockStorage, fetchProjectPartArtefact(_)).WillByDefault(Return(artefact)); ON_CALL(mockStorage, fetchProjectPartArtefact(A<FilePathId>())).WillByDefault(Return(artefact));
} }
protected: protected:
@@ -218,11 +219,20 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateSourceDependencies)
indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved));
} }
TEST_F(SymbolIndexer, UpdateProjectPartsCallsFetchProjectPartArtefacts)
{
EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId())));
EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart2.projectPartId())));
indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved));
}
TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder)
{ {
InSequence s; InSequence s;
EXPECT_CALL(mockCollector, clear()); EXPECT_CALL(mockCollector, clear());
EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId())));
EXPECT_CALL(mockCollector, addFiles(_, _)); EXPECT_CALL(mockCollector, addFiles(_, _));
EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved)); EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved));
EXPECT_CALL(mockCollector, collectSymbols()); EXPECT_CALL(mockCollector, collectSymbols());
@@ -274,7 +284,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder)
TEST_F(SymbolIndexer, HandleEmptyOptionalInUpdateChangedPath) TEST_F(SymbolIndexer, HandleEmptyOptionalInUpdateChangedPath)
{ {
ON_CALL(mockStorage, fetchProjectPartArtefact(_)).WillByDefault(Return(Utils::optional<ClangBackEnd::ProjectPartArtefact>())); ON_CALL(mockStorage, fetchProjectPartArtefact(A<FilePathId>()))
.WillByDefault(Return(Utils::optional<ClangBackEnd::ProjectPartArtefact>()));
EXPECT_CALL(mockCollector, clear()); EXPECT_CALL(mockCollector, clear());
EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])); EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0]));
@@ -291,4 +302,41 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalInUpdateChangedPath)
indexer.updateChangedPath(sourceFileIds[0]); indexer.updateChangedPath(sourceFileIds[0]);
} }
TEST_F(SymbolIndexer, CompilerMacrosAreNotDifferent)
{
ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact));
auto areDifferent = indexer.compilerMacrosAreDifferent(projectPart1);
ASSERT_FALSE(areDifferent);
}
TEST_F(SymbolIndexer, CompilerMacrosAreDifferent)
{
ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact));
auto areDifferent = indexer.compilerMacrosAreDifferent(projectPart2);
ASSERT_TRUE(areDifferent);
}
TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame)
{
ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact));
EXPECT_CALL(mockCollector, clear());
EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId())));
EXPECT_CALL(mockCollector, addFiles(_, _)).Times(0);
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(_, _)).Times(0);
EXPECT_CALL(mockStorage, updateProjectPartSources(An<int>(), _)).Times(0);
EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(_)).Times(0);
EXPECT_CALL(mockStorage, insertFileStatuses(_)).Times(0);
EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(_)).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
indexer.updateProjectPart(std::move(projectPart1), {});
}
} }

View File

@@ -86,6 +86,7 @@ protected:
MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = statementFactory.deleteOutdatedSourceDependenciesStatement; MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = statementFactory.deleteOutdatedSourceDependenciesStatement;
MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = statementFactory.deleteNewSourceDependenciesStatement; MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = statementFactory.deleteNewSourceDependenciesStatement;
MockSqliteReadStatement &getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId = statementFactory.getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId; MockSqliteReadStatement &getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId = statementFactory.getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId;
MockSqliteReadStatement &getProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName = statementFactory.getProjectPartCompilerArgumentsAndCompilerMacrosByProjectPartName;
SymbolEntries symbolEntries{{1, {"functionUSR", "function"}}, SymbolEntries symbolEntries{{1, {"functionUSR", "function"}},
{2, {"function2USR", "function2"}}}; {2, {"function2USR", "function2"}}};
SourceLocationEntries sourceLocations{{1, {1, 3}, {42, 23}, SymbolType::Declaration}, SourceLocationEntries sourceLocations{{1, {1, 3}, {42, 23}, SymbolType::Declaration},
@@ -277,5 +278,23 @@ TEST_F(SymbolStorage, FetchProjectPartArtefactBySourceIdReturnArtefact)
ASSERT_THAT(result, Eq(artefact)); ASSERT_THAT(result, Eq(artefact));
} }
TEST_F(SymbolStorage, FetchProjectPartArtefactByProjectNameCallsValueInStatement)
{
EXPECT_CALL(getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId, valueReturnProjectPartArtefact(1))
.WillRepeatedly(Return(artefact));
storage.fetchProjectPartArtefact({2, 1});
}
TEST_F(SymbolStorage, FetchProjectPartArtefactByProjectNameReturnArtefact)
{
EXPECT_CALL(getProjectPartCompilerArgumentsAndCompilerMacrosBySourceId, valueReturnProjectPartArtefact(1))
.WillRepeatedly(Return(artefact));
auto result = storage.fetchProjectPartArtefact({2, 1});
ASSERT_THAT(result, Eq(artefact));
}
} }