diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp index 3235284d963..5c9f0cbcccb 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp @@ -86,26 +86,25 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart) projectPart.arguments, projectPart.compilerMacros, projectPart.includeSearchPaths); - transaction.commit(); - if (optionalArtefact) projectPartId = optionalArtefact->projectPartId; + const Utils::optional optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(projectPartId); FilePathIds sourcePathIds = updatableFilePathIds(projectPart, optionalArtefact); + transaction.commit(); if (sourcePathIds.empty()) return; - Utils::SmallStringVector arguments = compilerArguments(projectPart, optionalArtefact); + const Utils::SmallStringVector arguments = compilerArguments(projectPart.arguments, + optionalProjectPartPch); std::vector symbolIndexerTask; symbolIndexerTask.reserve(projectPart.sourcePathIds.size()); for (FilePathId sourcePathId : projectPart.sourcePathIds) { - auto indexing = [projectPartId = projectPart.projectPartId, arguments, sourcePathId] + auto indexing = [projectPartId, arguments, sourcePathId] (SymbolsCollectorInterface &symbolsCollector, SymbolStorageInterface &symbolStorage, Sqlite::TransactionInterface &transactionInterface) { - auto id = Utils::SmallString::number(sourcePathId.filePathId); - symbolsCollector.setFile(sourcePathId, arguments); symbolsCollector.collectSymbols(); @@ -157,14 +156,18 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId, Sqlite::DeferredTransaction transaction{m_transactionInterface}; const Utils::optional optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(filePathId); + if (!optionalArtefact) + return; + + const Utils::optional optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(optionalArtefact->projectPartId); transaction.commit(); - if (optionalArtefact && !optionalArtefact.value().compilerArguments.empty()) { + if (!optionalArtefact.value().compilerArguments.empty()) { const ProjectPartArtefact &artefact = optionalArtefact.value(); - Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments, - artefact.projectPartId); + const Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments, + optionalProjectPartPch); auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId] (SymbolsCollectorInterface &symbolsCollector, @@ -233,10 +236,8 @@ FilePathIds SymbolIndexer::updatableFilePathIds(const V2::ProjectPartContainer & Utils::SmallStringVector SymbolIndexer::compilerArguments( Utils::SmallStringVector arguments, - int projectPartId) const + const Utils::optional optionalProjectPartPch) const { - Utils::optional optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(projectPartId); - if (optionalProjectPartPch) { arguments.emplace_back("-Xclang"); arguments.emplace_back("-include-pch"); @@ -247,15 +248,4 @@ Utils::SmallStringVector SymbolIndexer::compilerArguments( return arguments; } -Utils::SmallStringVector SymbolIndexer::compilerArguments( - const V2::ProjectPartContainer &projectPart, - const Utils::optional &optionalProjectPartArtefact) const -{ - if (optionalProjectPartArtefact) - return compilerArguments(projectPart.arguments, - optionalProjectPartArtefact.value().projectPartId); - - return projectPart.arguments; -} - } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h index eebea22670e..6d1a1de50b9 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h @@ -65,10 +65,8 @@ public: FilePathIds updatableFilePathIds(const V2::ProjectPartContainer &projectPart, const Utils::optional &optionalArtefact) const; - Utils::SmallStringVector compilerArguments(const V2::ProjectPartContainer &projectPart, - const Utils::optional &optionalArtefact) const; Utils::SmallStringVector compilerArguments(Utils::SmallStringVector arguments, - int projectPartId) const; + const Utils::optional optionalProjectPartPch) const; private: SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue; diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h index abea7854ae5..4de47dab1d2 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorage.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h @@ -136,15 +136,6 @@ public: m_statementFactory.deleteNewSourceDependenciesStatement.execute(); } - void updateProjectPartSources(Utils::SmallStringView projectPartName, - const FilePathIds &sourceFilePathIds) override - { - ReadStatement &getProjectPartIdStatement = m_statementFactory.getProjectPartIdStatement; - int projectPartId = getProjectPartIdStatement.template value(projectPartName).value(); - - updateProjectPartSources(projectPartId, sourceFilePathIds); - } - void updateProjectPartSources(int projectPartId, const FilePathIds &sourceFilePathIds) override { diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h index ffd85103c20..0ade62cc447 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h @@ -53,8 +53,6 @@ public: const Utils::SmallStringVector &commandLineArguments, const CompilerMacros &compilerMacros, const Utils::SmallStringVector &includeSearchPaths) = 0; - virtual void updateProjectPartSources(Utils::SmallStringView projectPartName, - const FilePathIds &sourceFilePathIds) = 0; virtual void updateProjectPartSources(int projectPartId, const FilePathIds &sourceFilePathIds) = 0; virtual void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) = 0; diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h index ca5f06a1501..aad7a51fea3 100644 --- a/tests/unit/unittest/mocksymbolstorage.h +++ b/tests/unit/unittest/mocksymbolstorage.h @@ -42,9 +42,6 @@ public: const Utils::SmallStringVector &commandLineArgument, const ClangBackEnd::CompilerMacros &compilerMacros, const Utils::SmallStringVector &includeSearchPaths)); - MOCK_METHOD2(updateProjectPartSources, - void(Utils::SmallStringView projectPartName, - const ClangBackEnd::FilePathIds &sourceFilePathIds)); MOCK_METHOD2(updateProjectPartSources, void(int projectPartId, const ClangBackEnd::FilePathIds &sourceFilePathIds)); diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 69e8927c5a6..f7364168d0b 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -96,7 +96,7 @@ protected: ON_CALL(mockCollector, fileStatuses()).WillByDefault(ReturnRef(fileStatus)); ON_CALL(mockCollector, sourceDependencies()).WillByDefault(ReturnRef(sourceDependencies)); ON_CALL(mockStorage, fetchProjectPartArtefact(A())).WillByDefault(Return(artefact)); - ON_CALL(mockStorage, fetchLowestLastModifiedTime(A())).WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A())).WillByDefault(Return(-1)); mockCollector.setIsUsed(false); @@ -176,6 +176,7 @@ protected: SourceDependencies sourceDependencies{{{1, 1}, {1, 2}}, {{1, 1}, {1, 3}}}; ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFOO\"]", "{\"FOO\":\"1\",\"BAR\":\"1\"}", "[\"/includes\"]", 74}; ClangBackEnd::ProjectPartArtefact emptyArtefact{"", "", "", 74}; + Utils::optional nullArtefact; ClangBackEnd::ProjectPartPch projectPartPch{"/path/to/pch", 4}; NiceMock mockSqliteTransactionBackend; NiceMock mockStorage; @@ -303,12 +304,24 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartsInStorage) indexer.updateProjectParts({projectPart1, projectPart2}); } -TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSources) +TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithArtifact) { - EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq("project1"), ElementsAre(IsFileId(1, 1), IsFileId(42, 23)))); - EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq("project2"), ElementsAre(IsFileId(1, 1), IsFileId(42, 23)))); + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq("project1"))).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, insertOrUpdateProjectPart(Eq("project1"), _, _, _)).WillByDefault(Return(-1)); - indexer.updateProjectParts({projectPart1, projectPart2}); + EXPECT_CALL(mockStorage, updateProjectPartSources(_, _)); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithoutArtifact) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq("project2"))).WillByDefault(Return(nullArtefact)); + ON_CALL(mockStorage, insertOrUpdateProjectPart(Eq("project2"), _, _, _)).WillByDefault(Return(3)); + + EXPECT_CALL(mockStorage, updateProjectPartSources(3, ElementsAre(IsFileId(1, 1), IsFileId(42, 23)))); + + indexer.updateProjectParts({projectPart2}); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateUsedMacros) @@ -343,19 +356,44 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsFetchProjectPartArtefacts) indexer.updateProjectParts({projectPart1, projectPart2}); } -TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) +TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact) { InSequence s; EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); - EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq(projectPart1.projectPartId))); - EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq(projectPart1.projectPartId))).WillOnce(Return(nullArtefact)); + EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))).WillOnce(Return(12)); + EXPECT_CALL(mockStorage, fetchPrecompiledHeader(Eq(12))); + EXPECT_CALL(mockStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, setFile(main1PathId, projectPart1.arguments)); EXPECT_CALL(mockCollector, collectSymbols()); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); - EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq(projectPart1.projectPartId), Eq(sourceFileIds))); + EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq(12), Eq(sourceFileIds))); + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(Eq(usedMacros))); + EXPECT_CALL(mockStorage, insertFileStatuses(Eq(fileStatus))); + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); + + indexer.updateProjectParts({projectPart1}); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact) +{ + InSequence s; + + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq(projectPart1.projectPartId))).WillRepeatedly(Return(artefact)); + EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))).WillOnce(Return(-1)); + EXPECT_CALL(mockStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); + EXPECT_CALL(mockStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).WillOnce(Return(-1)); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockCollector, setFile(Eq(main1PathId), Eq(projectPart1.arguments))); + EXPECT_CALL(mockCollector, collectSymbols()); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); + EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq(artefact.projectPartId), Eq(sourceFileIds))); EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(Eq(usedMacros))); EXPECT_CALL(mockStorage, insertFileStatuses(Eq(fileStatus))); EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); @@ -384,7 +422,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) InSequence s; EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])).WillOnce(Return(artefact)); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq(sourceFileIds[0]))).WillOnce(Return(artefact)); + EXPECT_CALL(mockStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, setFile(Eq(sourceFileIds[0]), Eq(artefact.compilerArguments))); EXPECT_CALL(mockCollector, collectSymbols()); @@ -404,8 +443,9 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) InSequence s; EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); - EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])).WillOnce(Return(emptyArtefact)); - EXPECT_CALL(mockSqliteTransactionBackend, commit()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])).WillOnce(Return(nullArtefact)); + EXPECT_CALL(mockStorage, fetchPrecompiledHeader(_)).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); EXPECT_CALL(mockCollector, setFile(_, _)).Times(0); EXPECT_CALL(mockCollector, collectSymbols()).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); @@ -489,10 +529,12 @@ TEST_F(SymbolIndexer, IncludeSearchPathsAreDifferent) TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame) { InSequence s; + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A())).WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq(projectPart1.projectPartId))).WillRepeatedly(Return(artefact)); EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))); + EXPECT_CALL(mockStorage, fetchLowestLastModifiedTime(A())).WillRepeatedly(Return(QDateTime::currentSecsSinceEpoch())); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, setFile(_, _)).Times(0); EXPECT_CALL(mockCollector, collectSymbols()).Times(0); @@ -539,6 +581,7 @@ TEST_F(SymbolIndexer, GetUpdatableFilePathIdsIfIncludeSearchPathsAreDifferent) TEST_F(SymbolIndexer, GetNoUpdatableFilePathIdsIfArtefactsAreTheSame) { ON_CALL(mockStorage, fetchProjectPartArtefact(An())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A())).WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); auto filePathIds = indexer.updatableFilePathIds(projectPart1, artefact); diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp index c35d8c7144a..66959a22de2 100644 --- a/tests/unit/unittest/symbolstorage-test.cpp +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -225,12 +225,11 @@ TEST_F(SymbolStorage, UpdateProjectPartSources) { InSequence sequence; - EXPECT_CALL(getProjectPartIdStatement, valueReturnInt32(TypedEq("project"))).WillRepeatedly(Return(42)); EXPECT_CALL(deleteAllProjectPartsSourcesWithProjectPartIdStatement, write(TypedEq(42))); EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq(42), TypedEq(1))); EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq(42), TypedEq(2))); - storage.updateProjectPartSources("project", {{1, 1}, {1, 2}}); + storage.updateProjectPartSources(42, {{1, 1}, {1, 2}}); } TEST_F(SymbolStorage, InsertOrUpdateUsedMacros)