diff --git a/core/include/SourcetrailDBWriter.h b/core/include/SourcetrailDBWriter.h index 84cee13..636b9fa 100644 --- a/core/include/SourcetrailDBWriter.h +++ b/core/include/SourcetrailDBWriter.h @@ -349,6 +349,26 @@ namespace sourcetrail */ bool recordReferenceLocation(int referenceId, const SourceRange& location); + /** + * Stores a location for the usage of a symbol's name as qualifier to the database + * + * This method allows to store a location where a specific symbol is used as a qualifier to the + * database. Calling this method with the same referencedSymbolId multiple times adds multiple locations + * for the respective reference. The stored location will be clickable but not displayable: When the + * reference location is clicked Sourcetrail will activate the symbol referenced by the respective + * reference. When the symbol with the specified id is activated, this location will NOT be displayed and + * highlighted by Sourcetrail. + * + * param: referencedSymbolId - the id of the symbol that is used as qualifier at the current location. + * param: location - the SourceRange that shall be recorded as location for the symbol's occurrence as + * qualifier + * + * return: true if successful. false on failure. getLastError() provides the error message. + * + * see: SourceRange + */ + bool recordQualifierLocation(int referencedSymbolId, const SourceRange& location); + /** * Stores a file to the database * diff --git a/core/src/SourcetrailDBWriter.cpp b/core/src/SourcetrailDBWriter.cpp index d2bafab..5247623 100644 --- a/core/src/SourcetrailDBWriter.cpp +++ b/core/src/SourcetrailDBWriter.cpp @@ -446,7 +446,7 @@ namespace sourcetrail { if (!m_storage) { - m_lastError = "Unable to record symbol signature location, because no database is currently open."; + m_lastError = "Unable to record symbol reference location, because no database is currently open."; return false; } @@ -462,6 +462,26 @@ namespace sourcetrail } } + bool SourcetrailDBWriter::recordQualifierLocation(int referencedSymbolId, const SourceRange& location) + { + if (!m_storage) + { + m_lastError = "Unable to record symbol qualifier location, because no database is currently open."; + return false; + } + + try + { + addSourceLocation(referencedSymbolId, location, LocationKind::QUALIFIER); + return true; + } + catch (const SourcetrailException e) + { + m_lastError = e.getMessage(); + return false; + } + } + int SourcetrailDBWriter::recordFile(const std::string& filePath) { if (!m_storage) diff --git a/core/test/test.cpp b/core/test/test.cpp index 00d63c7..0f798d2 100644 --- a/core/test/test.cpp +++ b/core/test/test.cpp @@ -276,6 +276,57 @@ namespace sourcetrail REQUIRE(writer.getLastError() == ""); } + TEST_CASE("Testing SourcetrailDBWriter records qualifier locations") + { + const std::string databasePath = "testing.db"; + + std::shared_ptr storage = DatabaseStorage::openDatabase(databasePath); + + SourcetrailDBWriter writer; + REQUIRE(writer.getLastError() == ""); + + writer.open(databasePath); + REQUIRE(writer.getLastError() == ""); + + writer.clear(); + REQUIRE(writer.getLastError() == ""); + + const NameHierarchy nameSymbol1({ "." ,{ { "", "Foo", "" } } }); + const int idSymbol1 = writer.recordSymbol(nameSymbol1); + REQUIRE(idSymbol1 != 0); + REQUIRE(writer.getLastError() == ""); + + const std::string filePath = "path/to/non_existing_file.cpp"; + const int fileId = writer.recordFile(filePath); + const int startLine = 1; + const int startCol = 2; + const int endLine = 3; + const int endCol = 4; + + const bool success = writer.recordQualifierLocation(idSymbol1, { fileId, startLine, startCol, endLine, endCol }); + REQUIRE(success); + REQUIRE(writer.getLastError() == ""); + + SECTION("database contains qualifier location after recording qualifier location") + { + const std::vector sourceLocations = storage->getAll(); + REQUIRE(sourceLocations.size() == 1); + REQUIRE(sourceLocations.front().locationKind == locationKindToInt(LocationKind::QUALIFIER)); + REQUIRE(sourceLocations.front().startLineNumber == startLine); + REQUIRE(sourceLocations.front().startColumnNumber == startCol); + REQUIRE(sourceLocations.front().endLineNumber == endLine); + REQUIRE(sourceLocations.front().endColumnNumber == endCol); + + const std::vector files = storage->getAll(); + REQUIRE(files.size() == 1); + REQUIRE(files.front().filePath == filePath); + REQUIRE(sourceLocations.front().fileNodeId == files.front().id); + } + + writer.close(); + REQUIRE(writer.getLastError() == ""); + } + TEST_CASE("Testing SourcetrailDBWriter records file") { const std::string databasePath = "testing.db"; diff --git a/examples/cpp_api_example/src/main.cpp b/examples/cpp_api_example/src/main.cpp index 49c1a1c..bae6f1d 100644 --- a/examples/cpp_api_example/src/main.cpp +++ b/examples/cpp_api_example/src/main.cpp @@ -129,11 +129,16 @@ int main(int argc, const char *argv[]) dbWriter.recordLocalSymbolLocation(localId, { fileId, 17, 13, 17, 26 }); + // record source range of "Client" as qualifier location + int qualifierId = dbWriter.recordSymbol({ "::",{ { "", "Client", "" } } }); + dbWriter.recordQualifierLocation(qualifierId, { fileId, 19, 13, 19, 18 }); + + // record function call reference to "send_signal()" int funcId = dbWriter.recordSymbol({ "::", { { "", "Client", "" }, { "", "send_signal", "()" } } }); dbWriter.recordSymbolKind(funcId, sourcetrail::SymbolKind::FUNCTION); int callId = dbWriter.recordReference(methodId, funcId, sourcetrail::ReferenceKind::CALL); - dbWriter.recordReferenceLocation(callId, { fileId, 19, 13, 19, 33 }); + dbWriter.recordReferenceLocation(callId, { fileId, 19, 21, 19, 31 }); // record error diff --git a/resources_swig/include/sourcetraildb.h b/resources_swig/include/sourcetraildb.h index 4bc9e40..d9f3e6d 100644 --- a/resources_swig/include/sourcetraildb.h +++ b/resources_swig/include/sourcetraildb.h @@ -93,6 +93,8 @@ int recordReference(int contextSymbolId, int referencedSymbolId, ReferenceKind r bool recordReferenceLocation(int referenceId, int fileId, int startLine, int startColumn, int endLine, int endColumn); +bool recordQualifierLocation(int referencedSymbolId, int fileId, int startLine, int startColumn, int endLine, int endColumn); + int recordFile(std::string filePath); bool recordFileLanguage(int fileId, std::string languageIdentifier); diff --git a/resources_swig/src/sourcetraildb.cpp b/resources_swig/src/sourcetraildb.cpp index bdf5262..74b6b8d 100644 --- a/resources_swig/src/sourcetraildb.cpp +++ b/resources_swig/src/sourcetraildb.cpp @@ -220,6 +220,11 @@ bool recordReferenceLocation(int referenceId, int fileId, int startLine, int sta return dbWriter.recordReferenceLocation(referenceId, { fileId, startLine, startColumn, endLine, endColumn }); } +bool recordQualifierLocation(int referencedSymbolId, int fileId, int startLine, int startColumn, int endLine, int endColumn) +{ + return dbWriter.recordQualifierLocation(referencedSymbolId, { fileId, startLine, startColumn, endLine, endColumn }); +} + int recordFile(std::string filePath) { return dbWriter.recordFile(filePath);