diff --git a/bin/test/data/log/test_log.txt b/bin/test/data/log/test_log.txt index 951a83d6..3ef756d5 100644 --- a/bin/test/data/log/test_log.txt +++ b/bin/test/data/log/test_log.txt @@ -1,189 +1,22 @@ -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml ConfigManager.cpp WARNING: value source/header_search_paths/header_search_path is not present in config. -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:1:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:1:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:1:11 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:1:13 CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:7:15 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:5:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:48 CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:7:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:3:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml CxxDeclNameResolver.cpp ERROR: could not resolve name of decl at: input.cc:4:20 -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml -Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml Token.cpp ERROR: Location Id was not referenced by this Token. Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class Edge.cpp ERROR: Nodes are not plain copies. diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index bb3f14e9..36fd8cdb 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -276,8 +276,8 @@ add_files( utility/solution/ISolutionParser.cpp utility/solution/ISolutionParser.h - utility/solution/SolutionParserCompilationDatabase.cpp - utility/solution/SolutionParserCompilationDatabase.h + utility/solution/SolutionParserCompilationDatabase.cpp + utility/solution/SolutionParserCompilationDatabase.h utility/solution/SolutionParserVisualStudio.cpp utility/solution/SolutionParserVisualStudio.h @@ -288,6 +288,7 @@ add_files( utility/AppPath.cpp utility/AppPath.h + utility/Cache.h utility/ConfigManager.cpp utility/ConfigManager.h utility/Property.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 63b6077f..c31c9a4b 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -322,29 +322,53 @@ std::vector CodeController::getSnippetsForActiveTokenLocation } std::vector CodeController::getSnippetsForActiveTokenLocationsInFile( - std::shared_ptr file + std::shared_ptr activeTokenLocations ) const { - std::vector fileSnippets = getSnippetsForFile(file); + std::shared_ptr fileLocations = m_storageAccess->getTokenLocationsForFile(activeTokenLocations->getFilePath().str()); - if (!file->isWholeCopy) + std::vector fileSnippets = getSnippetsForFile(activeTokenLocations, fileLocations); + + if (!activeTokenLocations->isWholeCopy) { for (CodeSnippetParams& params : fileSnippets) { - params.locationFile = m_storageAccess->getTokenLocationsForLinesInFile( - file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + params.locationFile = fileLocations->getFilteredByLines(params.startLineNumber, params.endLineNumber); } } return fileSnippets; } -std::vector CodeController::getSnippetsForFile(std::shared_ptr file) const +std::vector CodeController::getSnippetsForFile(std::shared_ptr activeTokenLocations) const { - std::shared_ptr textAccess = m_storageAccess->getFileContent(file->getFilePath()); + return getSnippetsForFile(activeTokenLocations, m_storageAccess->getTokenLocationsForFile(activeTokenLocations->getFilePath().str())); +} + +std::vector CodeController::getSnippetsForFile(std::shared_ptr activeTokenLocations, const std::shared_ptr fileLocations) const +{ + std::shared_ptr textAccess = m_storageAccess->getFileContent(activeTokenLocations->getFilePath()); + std::shared_ptr scopeLocations = std::make_shared(activeTokenLocations->getFilePath().str()); + fileLocations->forEachStartTokenLocation( + [&](TokenLocation* startLoc) -> void + { + if (startLoc->getType() == TokenLocation::LOCATION_SCOPE) + { + TokenLocation* endLoc = startLoc->getOtherTokenLocation(); + TokenLocation* scopeLoc = scopeLocations->addTokenLocation( + startLoc->getId(), + startLoc->getTokenId(), + startLoc->getLineNumber(), + startLoc->getColumnNumber(), + endLoc->getLineNumber(), + endLoc->getColumnNumber()); + scopeLoc->setType(TokenLocation::LOCATION_SCOPE); + } + } + ); std::deque ranges; - if (file->isWholeCopy) + if (activeTokenLocations->isWholeCopy) { ranges.push_back(SnippetMerger::Range( SnippetMerger::Border(1, true), @@ -355,15 +379,15 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt { SnippetMerger fileScopedMerger(1, textAccess->getLineCount()); std::map> mergers; - file->forEachStartTokenLocation( + activeTokenLocations->forEachStartTokenLocation( [&](TokenLocation* location) { - buildMergerHierarchy(location, fileScopedMerger, mergers); + buildMergerHierarchy(location, scopeLocations, fileScopedMerger, mergers); } ); std::vector atomicRanges; - m_storageAccess->getCommentLocationsInFile(file->getFilePath())->forEachStartTokenLocation( + m_storageAccess->getCommentLocationsInFile(activeTokenLocations->getFilePath())->forEachStartTokenLocation( [&](TokenLocation* location) { atomicRanges.push_back(SnippetMerger::Range( @@ -378,19 +402,19 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt } const int snippetExpandRange = ApplicationSettings::getInstance()->getCodeSnippetExpandRange(); + TimePoint fileModificationTime = m_storageAccess->getFileModificationTime(activeTokenLocations->getFilePath()); std::vector snippets; for (const SnippetMerger::Range& range: ranges) { CodeSnippetParams params; - params.locationFile = file; - params.refCount = file->getUnscopedStartTokenLocationCount(); + params.locationFile = activeTokenLocations; + params.refCount = activeTokenLocations->getUnscopedStartTokenLocationCount(); params.startLineNumber = std::max(1, range.start.row - (range.start.strong ? 0 : snippetExpandRange)); params.endLineNumber = std::min(textAccess->getLineCount(), range.end.row + (range.end.strong ? 0 : snippetExpandRange)); - params.modificationTime = m_storageAccess->getFileModificationTime(file->getFilePath()); - + params.modificationTime = fileModificationTime; std::shared_ptr tempFile = - m_storageAccess->getTokenLocationsForLinesInFile(file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + m_storageAccess->getTokenLocationsForLinesInFile(activeTokenLocations->getFilePath().str(), params.startLineNumber, params.endLineNumber); TokenLocationLine* firstUsedLine = nullptr; for (size_t i = params.startLineNumber; i <= params.endLineNumber && firstUsedLine == nullptr; i++) { @@ -400,8 +424,9 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt params.titleId = 0; if (firstUsedLine && firstUsedLine->getTokenLocations().size()) { - m_storageAccess->getTokenLocationOfParentScope( - firstUsedLine->getTokenLocations().begin()->second.get() + getTokenLocationOfParentScope( + firstUsedLine->getTokenLocations().begin()->second.get(), + scopeLocations )->forEachStartTokenLocation( // this TokenLocationFile only contains a single StartTokenLocation. [&](TokenLocation* location) { @@ -410,9 +435,9 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt } ); } - if (!file->isWholeCopy && params.titleId == 0) + if (!activeTokenLocations->isWholeCopy && params.titleId == 0) { - params.title = file->getFilePath().str(); + params.title = activeTokenLocations->getFilePath().str(); } @@ -425,8 +450,9 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt params.footerId = 0; if (lastUsedLine && lastUsedLine->getTokenLocations().size()) { - m_storageAccess->getTokenLocationOfParentScope( - lastUsedLine->getTokenLocations().begin()->second.get() + getTokenLocationOfParentScope( + lastUsedLine->getTokenLocations().begin()->second.get(), + scopeLocations )->forEachStartTokenLocation( // this TokenLocationFile only contains a single StartTokenLocation. [&](TokenLocation* location) { @@ -448,7 +474,7 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt } std::shared_ptr CodeController::buildMergerHierarchy( - TokenLocation* location, SnippetMerger& fileScopedMerger, std::map>& mergers) const + TokenLocation* location, std::shared_ptr scopeLocations, SnippetMerger& fileScopedMerger, std::map>& mergers) const { const TokenLocation* currentLocation = location; std::shared_ptr currentMerger = std::make_shared( @@ -456,7 +482,7 @@ std::shared_ptr CodeController::buildMergerHierarchy( currentLocation->getEndTokenLocation()->getLineNumber() ); - std::shared_ptr locationFile = m_storageAccess->getTokenLocationOfParentScope(currentLocation); + std::shared_ptr locationFile = getTokenLocationOfParentScope(currentLocation, scopeLocations); if (locationFile->getTokenLocationLineCount() == 0) { fileScopedMerger.addChild(currentMerger); @@ -470,7 +496,7 @@ std::shared_ptr CodeController::buildMergerHierarchy( std::map>::iterator it = mergers.find(scopeLocation->getId()); if (it == mergers.end()) { - nextMerger = buildMergerHierarchy(scopeLocation, fileScopedMerger, mergers); + nextMerger = buildMergerHierarchy(scopeLocation, scopeLocations, fileScopedMerger, mergers); mergers[scopeLocation->getId()] = nextMerger; } else @@ -483,6 +509,39 @@ std::shared_ptr CodeController::buildMergerHierarchy( return currentMerger; } +std::shared_ptr CodeController::getTokenLocationOfParentScope(const TokenLocation* location, std::shared_ptr scopeLocations) const +{ + const TokenLocation* parent = location; + const FilePath filePath = location->getFilePath(); + + scopeLocations->forEachStartTokenLocation( + [&](TokenLocation* tokenLocation) -> void + { + if ((*tokenLocation) < *(location->getStartTokenLocation()) && + (*tokenLocation->getEndTokenLocation()) > *(location->getEndTokenLocation())) + { + if (parent == location) + { + parent = tokenLocation; + } + // since tokenLocation is a start location the > location indicates the scope that is closer to the child. + else if ((*tokenLocation) > *parent) + { + parent = tokenLocation; + } + } + } + ); + + std::shared_ptr file = std::make_shared(filePath); + if (parent != location) + { + file->addTokenLocationAsPlainCopy(parent); + file->addTokenLocationAsPlainCopy(parent->getOtherTokenLocation()); + } + return file; +} + std::vector CodeController::getSnippetsForErrorLocations( std::vector* errorMessages) const { diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index e86d1dce..2f4312b4 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -60,9 +60,12 @@ private: const TokenLocationCollection* collection, Id declarationId) const; std::vector getSnippetsForActiveTokenLocationsInFile( std::shared_ptr) const; + std::vector getSnippetsForFile( + std::shared_ptr activeTokenLocations, std::shared_ptr fileLocations) const; std::vector getSnippetsForFile(std::shared_ptr file) const; std::shared_ptr buildMergerHierarchy( - TokenLocation* location, SnippetMerger& fileScopedMerger, std::map>& mergers) const; + TokenLocation* location, std::shared_ptr context, SnippetMerger& fileScopedMerger, std::map>& mergers) const; + std::shared_ptr getTokenLocationOfParentScope(const TokenLocation* location, std::shared_ptr context) const; std::vector getSnippetsForErrorLocations(std::vector* errorMessages) const; diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index a6aab229..b23ac311 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -517,24 +517,31 @@ std::shared_ptr SqliteStorage::getTokenLocationsForFile(const } std::vector SqliteStorage::getTokenLocationsForElementId(const Id elementId) const +{ + std::vector elementIds {elementId}; + return getTokenLocationsForElementIds(elementIds); +} + +std::vector SqliteStorage::getTokenLocationsForElementIds(const std::vector elementIds) const { std::vector locations; CppSQLite3Query q = m_database.execQuery(( - "SELECT id, file_node_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE element_id == " + std::to_string(elementId) + ";" + "SELECT id, element_id, file_node_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE element_id IN (" + utility::join(utility::toStrings(elementIds), ',') + ");" ).c_str()); while (!q.eof()) { const Id id = q.getIntField(0, 0); - const Id fileNodeId = q.getIntField(1, 0); - const int startLineNumber = q.getIntField(2, -1); - const int startColNumber = q.getIntField(3, -1); - const int endLineNumber = q.getIntField(4, -1); - const int endColNumber = q.getIntField(5, -1); - const int isScope = q.getIntField(6, -1); + const Id elementId = q.getIntField(1, 0); + const Id fileNodeId = q.getIntField(2, 0); + const int startLineNumber = q.getIntField(3, -1); + const int startColNumber = q.getIntField(4, -1); + const int endLineNumber = q.getIntField(5, -1); + const int endColNumber = q.getIntField(6, -1); + const int isScope = q.getIntField(7, -1); - if (id != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1) + if (id != 0 && elementId != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1) { locations.push_back(StorageSourceLocation( id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index 0f4b295c..eda9bb42 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -86,6 +86,7 @@ public: StorageSourceLocation getSourceLocationById(const Id id) const; std::shared_ptr getTokenLocationsForFile(const FilePath& filePath) const; std::vector getTokenLocationsForElementId(const Id elementId) const; + std::vector getTokenLocationsForElementIds(const std::vector elementIds) const; Id getElementIdByLocationId(Id locationId) const; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index e641ad73..a7f49ec5 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -11,6 +11,7 @@ #include "utility/utility.h" #include "utility/utilityString.h" #include "utility/Version.h" +#include "utility/Cache.h" #include "data/graph/token_component/TokenComponentAggregation.h" #include "data/graph/token_component/TokenComponentSignature.h" @@ -957,37 +958,52 @@ std::shared_ptr Storage::getTokenLocationsForTokenIds(c { std::shared_ptr collection = std::make_shared(); - for (Id elementId: tokenIds) + std::vector fileIds; + std::vector nonFileIds; + for (size_t i = 0; i < tokenIds.size(); i++) { - if (m_sqliteStorage.isFile(elementId)) + if (m_sqliteStorage.isFile(tokenIds[i])) { - StorageFile storageFile = m_sqliteStorage.getFileById(elementId); - collection->addTokenLocationFileAsPlainCopy(m_sqliteStorage.getTokenLocationsForFile(storageFile.filePath).get()); + fileIds.push_back(tokenIds[i]); } else { - std::vector locations = m_sqliteStorage.getTokenLocationsForElementId(elementId); - for (size_t i = 0; i < locations.size(); i++) - { - // TODO: optimize: fileNodeId to name in a separate map - const StorageSourceLocation& location = locations[i]; - StorageFile storageFile = m_sqliteStorage.getFileById(location.fileNodeId); + nonFileIds.push_back(tokenIds[i]); + } + } - TokenLocation* loc = collection->addTokenLocation( - location.id, - location.elementId, - storageFile.filePath, - location.startLine, - location.startCol, - location.endLine, - location.endCol - ); + for (Id fileId: fileIds) + { + StorageFile storageFile = m_sqliteStorage.getFileById(fileId); + collection->addTokenLocationFileAsPlainCopy(m_sqliteStorage.getTokenLocationsForFile(storageFile.filePath).get()); + } - if (loc) - { - loc->setType(location.isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN); - } - } + Cache filePathCache( + [this](Id id) -> std::string + { + return m_sqliteStorage.getFileById(id).filePath; + } + ); + + std::vector locations = m_sqliteStorage.getTokenLocationsForElementIds(nonFileIds); + for (size_t i = 0; i < locations.size(); i++) + { + const StorageSourceLocation& location = locations[i]; + std::string filePath = filePathCache.getValue(location.fileNodeId); + + TokenLocation* loc = collection->addTokenLocation( + location.id, + location.elementId, + filePath, + location.startLine, + location.startCol, + location.endLine, + location.endCol + ); + + if (loc) + { + loc->setType(location.isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN); } } @@ -1026,57 +1042,7 @@ std::shared_ptr Storage::getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const { - std::shared_ptr ret = std::make_shared(filePath); - - std::shared_ptr locationFile = m_sqliteStorage.getTokenLocationsForFile(filePath); - if (!locationFile->getTokenLocationLines().size()) - { - return ret; - } - - uint endLineNumber = locationFile->getTokenLocationLines().rbegin()->first; - std::set addedLocationIds; - for (uint i = firstLineNumber; i <= endLineNumber; i++) - { - TokenLocationLine* locationLine = locationFile->findTokenLocationLineByNumber(i); - if (!locationLine) - { - continue; - } - - if (locationLine->getLineNumber() <= lastLineNumber) - { - locationLine->forEachTokenLocation( - [&](TokenLocation* tokenLocation) -> void - { - const Id tokenId = tokenLocation->getId(); - if (addedLocationIds.find(tokenId) == addedLocationIds.end()) - { - ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); - ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); - addedLocationIds.insert(tokenId); - } - } - ); - } - else - { - // Save start locations of TokenLocations that span accross the line range. - locationLine->forEachTokenLocation( - [&](TokenLocation* tokenLocation) -> void - { - if (tokenLocation->isEndTokenLocation() && - tokenLocation->getStartTokenLocation()->getLineNumber() < firstLineNumber) - { - ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); - ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); - } - } - ); - } - } - - return ret; + return m_sqliteStorage.getTokenLocationsForFile(filePath)->getFilteredByLines(firstLineNumber, lastLineNumber); } TokenLocationCollection Storage::getErrorTokenLocations(std::vector* errorMessages) const @@ -1095,41 +1061,6 @@ TokenLocationCollection Storage::getErrorTokenLocations(std::vector return errorCollection; } -std::shared_ptr Storage::getTokenLocationOfParentScope(const TokenLocation* child) const -{ - const TokenLocation* parent = child; - const FilePath filePath = child->getFilePath(); - - std::shared_ptr locationFile = m_sqliteStorage.getTokenLocationsForFile(filePath); // TODO: sqlite should not know TokenLocationFile! - locationFile->forEachStartTokenLocation( - [&](TokenLocation* tokenLocation) -> void - { - if (tokenLocation->getType() == TokenLocation::LOCATION_SCOPE && - (*tokenLocation) < *(child->getStartTokenLocation()) && - (*tokenLocation->getEndTokenLocation()) > *(child->getEndTokenLocation())) - { - if (parent == child) - { - parent = tokenLocation; - } - // since tokenLocation is a start location the > location indicates the scope that is closer to the child. - else if ((*tokenLocation) > *parent) - { - parent = tokenLocation; - } - } - } - ); - - std::shared_ptr file = std::make_shared(filePath); - if (parent != child) - { - file->addTokenLocationAsPlainCopy(parent); - file->addTokenLocationAsPlainCopy(parent->getOtherTokenLocation()); - } - return file; -} - std::shared_ptr Storage::getCommentLocationsInFile(const FilePath& filePath) const { std::shared_ptr file = std::make_shared(filePath); diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 1a279723..d599bddb 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -147,7 +147,6 @@ public: ) const; virtual TokenLocationCollection getErrorTokenLocations(std::vector* errorMessages) const; - virtual std::shared_ptr getTokenLocationOfParentScope(const TokenLocation* child) const; virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const; virtual std::shared_ptr getFileContent(const FilePath& filePath) const; diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index e03f5af7..eee6f96c 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -57,7 +57,6 @@ public: const std::string& filePath, uint firstLineNumber, uint lastLineNumber) const = 0; virtual TokenLocationCollection getErrorTokenLocations(std::vector* errorMessages) const = 0; - virtual std::shared_ptr getTokenLocationOfParentScope(const TokenLocation* child) const = 0; virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const = 0; virtual std::shared_ptr getFileContent(const FilePath& filePath) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 232e3c34..a24e6c8b 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -245,16 +245,6 @@ TokenLocationCollection StorageAccessProxy::getErrorTokenLocations(std::vector StorageAccessProxy::getTokenLocationOfParentScope(const TokenLocation* child) const -{ - if (hasSubject()) - { - return m_subject->getTokenLocationOfParentScope(child); - } - - return std::make_shared(""); -} - std::shared_ptr StorageAccessProxy::getCommentLocationsInFile(const FilePath& filePath) const { if (hasSubject()) diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index 1a23e969..ff5137b7 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -46,7 +46,6 @@ public: ) const; virtual TokenLocationCollection getErrorTokenLocations(std::vector* errorMessages) const; - virtual std::shared_ptr getTokenLocationOfParentScope(const TokenLocation* child) const; virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const; virtual std::shared_ptr getFileContent(const FilePath& filePath) const; diff --git a/src/lib/data/location/TokenLocationFile.cpp b/src/lib/data/location/TokenLocationFile.cpp index 44c5475a..577fcaf5 100644 --- a/src/lib/data/location/TokenLocationFile.cpp +++ b/src/lib/data/location/TokenLocationFile.cpp @@ -1,6 +1,9 @@ #include "data/location/TokenLocationFile.h" +#include + #include "utility/logging/logging.h" +#include "utility/types.h" #include "data/location/TokenLocation.h" #include "data/location/TokenLocationLine.h" @@ -164,6 +167,60 @@ TokenLocation* TokenLocationFile::addTokenLocationAsPlainCopy(const TokenLocatio return copy; } +std::shared_ptr TokenLocationFile::getFilteredByLines(unsigned int firstLineNumber, unsigned int lastLineNumber) const +{ + std::shared_ptr ret = std::make_shared(getFilePath().str()); + + if (getTokenLocationLines().size() == 0) + { + return ret; + } + + uint endLineNumber = getTokenLocationLines().rbegin()->first; + std::set addedLocationIds; + for (uint i = firstLineNumber; i <= endLineNumber; i++) + { + TokenLocationLine* locationLine = findTokenLocationLineByNumber(i); + if (!locationLine) + { + continue; + } + + if (locationLine->getLineNumber() <= lastLineNumber) + { + locationLine->forEachTokenLocation( + [&](TokenLocation* tokenLocation) -> void + { + const Id tokenId = tokenLocation->getId(); + if (addedLocationIds.find(tokenId) == addedLocationIds.end()) + { + ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); + ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); + addedLocationIds.insert(tokenId); + } + } + ); + } + else + { + // Save start locations of TokenLocations that span accross the line range. + locationLine->forEachTokenLocation( + [&](TokenLocation* tokenLocation) -> void + { + if (tokenLocation->isEndTokenLocation() && + tokenLocation->getStartTokenLocation()->getLineNumber() < firstLineNumber) + { + ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); + ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); + } + } + ); + } + } + + return ret; +} + TokenLocationLine* TokenLocationFile::findTokenLocationLine(unsigned int lineNumber) const { TokenLocationLineMapType::const_iterator it = m_lines.find(lineNumber); @@ -199,3 +256,4 @@ std::ostream& operator<<(std::ostream& ostream, const TokenLocationFile& file) }); return ostream; } + diff --git a/src/lib/data/location/TokenLocationFile.h b/src/lib/data/location/TokenLocationFile.h index dbb389aa..f3d6af4d 100644 --- a/src/lib/data/location/TokenLocationFile.h +++ b/src/lib/data/location/TokenLocationFile.h @@ -43,6 +43,8 @@ public: TokenLocation* addTokenLocationAsPlainCopy(const TokenLocation* location); + std::shared_ptr getFilteredByLines(unsigned int firstLineNumber, unsigned int lastLineNumber) const; + bool isWholeCopy; private: diff --git a/src/lib/utility/Cache.h b/src/lib/utility/Cache.h new file mode 100644 index 00000000..aa6121ce --- /dev/null +++ b/src/lib/utility/Cache.h @@ -0,0 +1,38 @@ +#ifndef CACHE_H +#define CACHE_H + +#include +#include + +template +class Cache +{ +public: + Cache(std::function calculator); + ValType getValue(KeyType key); + +private: + std::function m_calculator; + std::map m_map; +}; + +template +Cache::Cache(std::function calculator) + : m_calculator(calculator) +{ +} + +template +ValType Cache::getValue(KeyType key) +{ + std::map::const_iterator it = m_map.find(key); + if (it != m_map.end()) + { + return it->second; + } + ValType val = m_calculator(key); + m_map[key] = val; + return val; +} + +#endif // CACHE_H