diff --git a/bin/app/data/color_schemes/bad_rainbow.xml b/bin/app/data/color_schemes/bad_rainbow.xml index 85a676af..7e6a73a3 100644 --- a/bin/app/data/color_schemes/bad_rainbow.xml +++ b/bin/app/data/color_schemes/bad_rainbow.xml @@ -87,7 +87,7 @@ - + transparent transparent @@ -100,7 +100,21 @@ #B2B2B2 #4A4A4A - + + + + transparent + transparent + + + #FF9C3C + transparent + + + #FF9C3C + #695540 + + transparent diff --git a/bin/app/data/color_schemes/bright.xml b/bin/app/data/color_schemes/bright.xml index 53660827..03ab3d97 100644 --- a/bin/app/data/color_schemes/bright.xml +++ b/bin/app/data/color_schemes/bright.xml @@ -87,7 +87,7 @@ - + transparent transparent @@ -100,7 +100,21 @@ #B2B2B2 #EDEDED - + + + + transparent + transparent + + + #FF9C3C + transparent + + + #FF9C3C + #FFDFC0 + + transparent diff --git a/bin/app/data/color_schemes/dark.xml b/bin/app/data/color_schemes/dark.xml index 6f49c946..a521c44f 100644 --- a/bin/app/data/color_schemes/dark.xml +++ b/bin/app/data/color_schemes/dark.xml @@ -87,7 +87,7 @@ - + transparent transparent @@ -100,7 +100,21 @@ #B2B2B2 #4A4A4A - + + + + transparent + transparent + + + #FF9C3C + transparent + + + #FF9C3C + #695540 + + transparent diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 407907b4..018feae7 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -107,6 +107,8 @@ add_files( data/graph/Token.cpp data/graph/Token.h + data/location/LocationType.cpp + data/location/LocationType.h data/location/TokenLocation.cpp data/location/TokenLocation.h data/location/TokenLocationCollection.cpp @@ -215,6 +217,7 @@ add_files( utility/messaging/type/MessageActivateAll.h utility/messaging/type/MessageActivateEdge.h utility/messaging/type/MessageActivateFile.h + utility/messaging/type/MessageActivateLocalSymbols.h utility/messaging/type/MessageActivateNodes.h utility/messaging/type/MessageActivateTokenLocations.h utility/messaging/type/MessageActivateTokenIds.h diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index bcb6b58f..fb4d0a2a 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -86,6 +86,12 @@ void CodeController::handleMessage(MessageActivateAll* message) showContents(message); } +void CodeController::handleMessage(MessageActivateLocalSymbols* message) +{ + CodeView* view = getView(); + view->showActiveLocalSymbolIds(message->symbolIds); +} + void CodeController::handleMessage(MessageActivateTokens* message) { CodeView* view = getView(); @@ -358,7 +364,7 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt fileLocations->forEachStartTokenLocation( [&](TokenLocation* startLoc) -> void { - if (startLoc->getType() == TokenLocation::LOCATION_SCOPE) + if (startLoc->getType() == LOCATION_SCOPE) { TokenLocation* endLoc = startLoc->getOtherTokenLocation(); TokenLocation* scopeLoc = scopeLocations->addTokenLocation( @@ -368,7 +374,7 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt startLoc->getColumnNumber(), endLoc->getLineNumber(), endLoc->getColumnNumber()); - scopeLoc->setType(TokenLocation::LOCATION_SCOPE); + scopeLoc->setType(LOCATION_SCOPE); } } ); diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index 2f4312b4..96b952d0 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -6,6 +6,7 @@ #include "utility/messaging/MessageListener.h" #include "utility/messaging/type/MessageActivateAll.h" +#include "utility/messaging/type/MessageActivateLocalSymbols.h" #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageChangeFileView.h" #include "utility/messaging/type/MessageFlushUpdates.h" @@ -27,6 +28,7 @@ class TokenLocationFile; class CodeController : public Controller , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -44,6 +46,7 @@ private: static const uint s_lineRadius; virtual void handleMessage(MessageActivateAll* message); + virtual void handleMessage(MessageActivateLocalSymbols* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageChangeFileView* message); virtual void handleMessage(MessageFlushUpdates* message); diff --git a/src/lib/component/controller/FeatureController.cpp b/src/lib/component/controller/FeatureController.cpp index b76713eb..91897b7d 100644 --- a/src/lib/component/controller/FeatureController.cpp +++ b/src/lib/component/controller/FeatureController.cpp @@ -72,7 +72,7 @@ void FeatureController::handleMessage(MessageActivateTokenLocations* message) nodeId, m_storageAccess->getNodeTypeForNodeWithId(nodeId), m_storageAccess->getNameHierarchyForNodeWithId(nodeId) - ); + ); } m.dispatchImmediately(); } diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index 2dc7d1cd..b866bc6a 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -3,6 +3,7 @@ #include "utility/logging/logging.h" #include "utility/messaging/type/MessageActivateTokens.h" #include "utility/messaging/type/MessageFlushUpdates.h" +#include "utility/utility.h" #include "component/view/UndoRedoView.h" #include "data/access/StorageAccess.h" @@ -52,10 +53,26 @@ void UndoRedoController::handleMessage(MessageActivateFile* message) processCommand(command); } +void UndoRedoController::handleMessage(MessageActivateLocalSymbols* message) +{ + if (m_lastCommand.message && + m_lastCommand.message->getType() == message->getType() && + utility::isPermutation( + message->symbolIds, + static_cast(m_lastCommand.message.get())->symbolIds) + ) + { + return; + } + + Command command(std::make_shared(*message), 1); + processCommand(command); +} + void UndoRedoController::handleMessage(MessageActivateNodes* message) { - if (m_lastCommand.message && - m_lastCommand.message->getType() == message->getType() && + if (m_lastCommand.message && + m_lastCommand.message->getType() == message->getType() && message->nodes.size() && static_cast(m_lastCommand.message.get())->nodes.size() == message->nodes.size() && static_cast(m_lastCommand.message.get())->nodes[0].nameHierarchy.getQualifiedNameWithSignature() == diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index cce664bd..911f3947 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -7,6 +7,7 @@ #include "utility/messaging/MessageListener.h" #include "utility/messaging/type/MessageActivateEdge.h" #include "utility/messaging/type/MessageActivateFile.h" +#include "utility/messaging/type/MessageActivateLocalSymbols.h" #include "utility/messaging/type/MessageActivateNodes.h" #include "utility/messaging/type/MessageActivateTokenIds.h" #include "utility/messaging/type/MessageChangeFileView.h" @@ -32,6 +33,7 @@ class UndoRedoController : public Controller , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -65,6 +67,7 @@ private: virtual void handleMessage(MessageActivateEdge* message); virtual void handleMessage(MessageActivateFile* message); + virtual void handleMessage(MessageActivateLocalSymbols* message); virtual void handleMessage(MessageActivateNodes* message); virtual void handleMessage(MessageActivateTokenIds* message); virtual void handleMessage(MessageChangeFileView* message); diff --git a/src/lib/component/view/CodeView.h b/src/lib/component/view/CodeView.h index 66467d05..d4b86aa9 100644 --- a/src/lib/component/view/CodeView.h +++ b/src/lib/component/view/CodeView.h @@ -39,6 +39,7 @@ public: virtual void showFirstActiveSnippet(const std::vector& activeTokenIds, bool scrollTo) = 0; virtual void showActiveTokenIds(const std::vector& activeTokenIds) = 0; + virtual void showActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds) = 0; virtual void focusTokenIds(const std::vector& focusedTokenIds) = 0; virtual void defocusTokenIds() = 0; diff --git a/src/lib/data/IntermediateStorage.cpp b/src/lib/data/IntermediateStorage.cpp index bc4a5ffe..f1e0fd01 100644 --- a/src/lib/data/IntermediateStorage.cpp +++ b/src/lib/data/IntermediateStorage.cpp @@ -108,7 +108,25 @@ Id IntermediateStorage::addFile(const std::string& filePath) return id; } -void IntermediateStorage::addSourceLocation(Id elementId, const ParseLocation& location, bool isScope) +Id IntermediateStorage::addLocalSymbol(const std::string& name) +{ + std::shared_ptr localSymbol = std::make_shared(0, name); + + std::string serialized = serialize(*(localSymbol.get())); + std::unordered_map::const_iterator it = m_localSymbolNamesToIds.find(serialized); + if (it != m_localSymbolNamesToIds.end()) + { + return it->second; + } + + Id id = m_nextId++; + m_localSymbolNamesToIds[serialized] = id; + m_localSymbolIdsToData[id] = localSymbol; + + return id; +} + +void IntermediateStorage::addSourceLocation(Id elementId, const ParseLocation& location, int type) { Id fileNodeId = addFile(location.filePath.str()); m_sourceLocations.push_back(StorageSourceLocation( @@ -119,7 +137,7 @@ void IntermediateStorage::addSourceLocation(Id elementId, const ParseLocation& l location.startColumnNumber, location.endLineNumber, location.endColumnNumber, - isScope + type )); } @@ -238,6 +256,18 @@ void IntermediateStorage::transferToStorage(SqliteStorage& storage) clientIdToStorageId[it->first] = edgeId; } + for (std::map>::const_iterator it = m_localSymbolIdsToData.begin(); it != m_localSymbolIdsToData.end(); it++) + { + StorageLocalSymbol clientLocalSymbol = *(it->second.get()); + StorageLocalSymbol storageLocalSymbol = storage.getLocalSymbolByName(clientLocalSymbol.name); + Id storageLocalSymbolId = storageLocalSymbol.id; + if (storageLocalSymbolId == 0) + { + storageLocalSymbolId = storage.addLocalSymbol(clientLocalSymbol.name); + } + clientIdToStorageId[it->first] = storageLocalSymbolId; + } + for (size_t i = 0; i < m_sourceLocations.size(); i++) { StorageSourceLocation sourceLocation = m_sourceLocations[i]; @@ -263,7 +293,7 @@ void IntermediateStorage::transferToStorage(SqliteStorage& storage) sourceLocation.startCol, sourceLocation.endLine, sourceLocation.endCol, - sourceLocation.isScope + sourceLocation.type ); } @@ -393,3 +423,8 @@ std::string IntermediateStorage::serialize(const StorageFile& file) { return file.filePath; } + +std::string IntermediateStorage::serialize(const StorageLocalSymbol& localSymbol) +{ + return localSymbol.name; +} diff --git a/src/lib/data/IntermediateStorage.h b/src/lib/data/IntermediateStorage.h index 88ba96a6..d2fb9567 100644 --- a/src/lib/data/IntermediateStorage.h +++ b/src/lib/data/IntermediateStorage.h @@ -21,7 +21,8 @@ public: Id addNode(int type, const NameHierarchy& nameHierarchy, int definitionType); Id addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime); Id addFile(const std::string& filePath); - void addSourceLocation(Id elementId, const ParseLocation& location, bool isScope); + Id addLocalSymbol(const std::string& name); + void addSourceLocation(Id elementId, const ParseLocation& location, int type); void addComponentAccess(Id nodeId , int type); void addCommentLocation(const ParseLocation& location); void addError(const std::string& message, bool fatal, const ParseLocation& location); @@ -40,6 +41,7 @@ private: std::string serialize(const StorageEdge& edge); std::string serialize(const StorageNode& node); std::string serialize(const StorageFile& file); + std::string serialize(const StorageLocalSymbol& localSymbol); std::unordered_map m_fileNamesToIds; // this is used to prevent duplicates (unique) std::unordered_map> m_fileIdsToData; @@ -50,6 +52,10 @@ private: std::unordered_map m_edgeNamesToIds; // this is used to prevent duplicates (unique) std::map> m_edgeIdsToData; + + std::unordered_map m_localSymbolNamesToIds; // this is used to prevent duplicates (unique) + std::map> m_localSymbolIdsToData; + std::vector m_sourceLocations; std::vector m_componentAccesses; std::vector m_commentLocations; diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index ea4e6a63..bfe2c763 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -136,14 +136,29 @@ Id SqliteStorage::addFile(const std::string& serializedName, const std::string& return id; } +Id SqliteStorage::addLocalSymbol(const std::string& name) +{ + m_database.execDML( + "INSERT INTO element(id) VALUES(NULL);" + ); + Id id = m_database.lastRowId(); + + m_database.execDML(( + "INSERT INTO local_symbol(id, name) VALUES(" + + std::to_string(id) + ", '" + name + "');" + ).c_str()); + + return id; +} + Id SqliteStorage::addSourceLocation( - Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope) + Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type) { m_database.execDML(( - "INSERT INTO source_location(id, element_id, file_node_id, start_line, start_column, end_line, end_column, is_scope) " + "INSERT INTO source_location(id, element_id, file_node_id, start_line, start_column, end_line, end_column, type) " "VALUES(NULL, " + std::to_string(elementId) + ", " + std::to_string(fileNodeId) + ", " + std::to_string(startLine) + ", " + std::to_string(startCol) + ", " - + std::to_string(endLine) + ", " + std::to_string(endCol) + ", " + std::to_string(isScope) + ");" + + std::to_string(endLine) + ", " + std::to_string(endCol) + ", " + std::to_string(type) + ");" ).c_str()); return m_database.lastRowId(); @@ -420,6 +435,18 @@ std::vector SqliteStorage::getNodesByIds(const std::vector& nod return getAllNodes("WHERE id IN (" + utility::join(utility::toStrings(nodeIds), ',') + ")"); } +StorageLocalSymbol SqliteStorage::getLocalSymbolByName(const std::string& name) const +{ + StorageLocalSymbol localSymbol( + getFirstResult( + "SELECT id FROM local_symbol WHERE " + "name == '" + name + "';" + ), + name + ); + return localSymbol; +} + StorageFile SqliteStorage::getFileById(const Id id) const { return getFirstFile( @@ -474,7 +501,7 @@ void SqliteStorage::setNodeDefinitionType(int definitionType, Id nodeId) StorageSourceLocation SqliteStorage::getSourceLocationById(const Id id) const { return getFirstSourceLocation( - "SELECT id, element_id, file_node_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE id == " + std::to_string(id) + ";" + "SELECT id, element_id, file_node_id, start_line, start_column, end_line, end_column, type FROM source_location WHERE id == " + std::to_string(id) + ";" ); } @@ -489,7 +516,7 @@ std::shared_ptr SqliteStorage::getTokenLocationsForFile(const } CppSQLite3Query q = m_database.execQuery(( - "SELECT id, element_id, start_line, start_column, end_line, end_column, is_scope FROM source_location WHERE file_node_id == " + std::to_string(fileNodeId) + ";" + "SELECT id, element_id, start_line, start_column, end_line, end_column, type FROM source_location WHERE file_node_id == " + std::to_string(fileNodeId) + ";" ).c_str()); while (!q.eof()) @@ -500,12 +527,12 @@ std::shared_ptr SqliteStorage::getTokenLocationsForFile(const 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 int type = q.getIntField(6, -1); - if (locationId != 0 && elementId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && isScope != -1) + if (locationId != 0 && elementId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && type != -1) { TokenLocation* loc = ret->addTokenLocation(locationId, elementId, startLineNumber, startColNumber, endLineNumber, endColNumber); - loc->setType(isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN); + loc->setType(intToLocationType(type)); } q.nextRow(); } @@ -524,7 +551,7 @@ std::vector SqliteStorage::getTokenLocationsForElementIds std::vector locations; CppSQLite3Query q = m_database.execQuery(( - "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), ',') + ");" + "SELECT id, element_id, file_node_id, start_line, start_column, end_line, end_column, type FROM source_location WHERE element_id IN (" + utility::join(utility::toStrings(elementIds), ',') + ");" ).c_str()); while (!q.eof()) @@ -536,12 +563,12 @@ std::vector SqliteStorage::getTokenLocationsForElementIds 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); + const int type = q.getIntField(7, -1); - if (id != 0 && elementId != 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 && type != -1) { locations.push_back(StorageSourceLocation( - id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope + id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, type )); } q.nextRow(); @@ -700,6 +727,7 @@ void SqliteStorage::clearTables() m_database.execDML("DROP TABLE IF EXISTS main.comment_location;"); m_database.execDML("DROP TABLE IF EXISTS main.component_access;"); m_database.execDML("DROP TABLE IF EXISTS main.source_location;"); + m_database.execDML("DROP TABLE IF EXISTS main.local_symbol;"); m_database.execDML("DROP TABLE IF EXISTS main.file;"); m_database.execDML("DROP TABLE IF EXISTS main.node;"); m_database.execDML("DROP TABLE IF EXISTS main.edge;"); @@ -764,6 +792,14 @@ void SqliteStorage::setupTables() "FOREIGN KEY(id) REFERENCES node(id) ON DELETE CASCADE);" ); + m_database.execDML( + "CREATE TABLE IF NOT EXISTS local_symbol(" + "id INTEGER NOT NULL, " + "name TEXT, " + "PRIMARY KEY(id), " + "FOREIGN KEY(id) REFERENCES element(id) ON DELETE CASCADE);" + ); + m_database.execDML( "CREATE TABLE IF NOT EXISTS source_location(" "id INTEGER NOT NULL, " @@ -773,7 +809,7 @@ void SqliteStorage::setupTables() "start_column INTEGER, " "end_line INTEGER, " "end_column INTEGER, " - "is_scope INTEGER, " + "type INTEGER, " "PRIMARY KEY(id), " "FOREIGN KEY(element_id) REFERENCES element(id) ON DELETE CASCADE, " "FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE);" @@ -907,12 +943,12 @@ StorageSourceLocation SqliteStorage::getFirstSourceLocation(const std::string& q 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); + const int type = q.getIntField(7, -1); - if (id != 0 && elementId != 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 && type != -1) { return StorageSourceLocation( - id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, isScope + id, elementId, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, type ); } } diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index 91dc58c7..cad4d96f 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -37,7 +37,8 @@ public: Id addEdge(int type, Id sourceNodeId, Id targetNodeId); Id addNode(int type, const std::string& serializedName, int definitionType); Id addFile(const std::string& serializedName, const std::string& filePath, const std::string& modificationTime); - Id addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope); + Id addLocalSymbol(const std::string& name); + Id addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type); Id addComponentAccess(Id memberEdgeId, int type); @@ -75,6 +76,8 @@ public: StorageNode getNodeBySerializedName(const std::string& serializedName) const; std::vector getNodesByIds(const std::vector& nodeIds) const; + StorageLocalSymbol getLocalSymbolByName(const std::string& name) const; + StorageFile getFileById(const Id id) const; StorageFile getFileByPath(const std::string& filePath) const; std::vector getAllFiles() const; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 25c6821b..905b5865 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -456,7 +456,7 @@ std::vector Storage::getNodeIdsForLocationIds(const std::vector& locatio { edgeIds.insert(edge.targetNodeId); } - else + else if(m_sqliteStorage.isNode(elementId)) { StorageNode node = m_sqliteStorage.getNodeById(elementId); if (node.id != 0 && intToDefinitionType(node.definitionType) == DEFINITION_EXPLICIT) @@ -474,6 +474,23 @@ std::vector Storage::getNodeIdsForLocationIds(const std::vector& locatio return utility::toVector(edgeIds); } +std::vector Storage::getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const +{ + std::set localSymbolIds; + + for (Id locationId : locationIds) + { + Id elementId = m_sqliteStorage.getElementIdByLocationId(locationId); + + if (m_sqliteStorage.getNodeById(elementId).id == 0 && m_sqliteStorage.getEdgeById(elementId).id == 0) + { + localSymbolIds.insert(elementId); + } + } + + return utility::toVector(localSymbolIds); +} + std::vector Storage::getTokenIdsForMatches(const std::vector& matches) const { std::set idSet; @@ -584,7 +601,7 @@ std::shared_ptr Storage::getTokenLocationsForTokenIds(c if (loc) { - loc->setType(location.isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN); + loc->setType(intToLocationType(location.type)); } } @@ -605,8 +622,8 @@ std::shared_ptr Storage::getTokenLocationsForLocationId location.startLine, location.startCol, location.endLine, - location.endCol)->setType(location.isScope ? TokenLocation::LOCATION_SCOPE : TokenLocation::LOCATION_TOKEN - ); + location.endCol + )->setType(intToLocationType(location.type)); } return collection; diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index b7d1501c..29642de2 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -62,6 +62,7 @@ public: virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const; virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const; + virtual std::vector getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const; virtual std::vector getTokenIdsForMatches(const std::vector& matches) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; diff --git a/src/lib/data/StorageTypes.h b/src/lib/data/StorageTypes.h index 8aea572c..73a8e2e5 100644 --- a/src/lib/data/StorageTypes.h +++ b/src/lib/data/StorageTypes.h @@ -50,9 +50,20 @@ struct StorageFile std::string modificationTime; }; +struct StorageLocalSymbol +{ + StorageLocalSymbol(Id id, const std::string& name) + : id(id) + , name(name) + {} + + Id id; + std::string name; +}; + struct StorageSourceLocation { - StorageSourceLocation(Id id, Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope) + StorageSourceLocation(Id id, Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, int type) : id(id) , elementId(elementId) , fileNodeId(fileNodeId) @@ -60,7 +71,7 @@ struct StorageSourceLocation , startCol(startCol) , endLine(endLine) , endCol(endCol) - , isScope(isScope) + , type(type) {} Id id; @@ -70,7 +81,7 @@ struct StorageSourceLocation uint startCol; uint endLine; uint endCol; - bool isScope; + int type; }; struct StorageComponentAccess diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 490b06dd..32a6879e 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -44,6 +44,7 @@ public: virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const = 0; virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const = 0; + virtual std::vector getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const = 0; virtual std::vector getTokenIdsForMatches(const std::vector& matches) const = 0; virtual Id getTokenIdForFileNode(const FilePath& filePath) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 4a190542..91d3bf31 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -143,6 +143,16 @@ std::vector StorageAccessProxy::getNodeIdsForLocationIds(const std::vector(); } +std::vector StorageAccessProxy::getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const +{ + if (hasSubject()) + { + return m_subject->getLocalSymbolIdsForLocationIds(locationIds); + } + + return std::vector(); +} + std::vector StorageAccessProxy::getTokenIdsForMatches(const std::vector& matches) const { if (hasSubject()) diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index df10e24c..d5083b60 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -31,6 +31,7 @@ public: virtual std::vector getActiveTokenIdsForId(Id tokenId, Id* declarationId) const; virtual std::vector getNodeIdsForLocationIds(const std::vector& locationIds) const; + virtual std::vector getLocalSymbolIdsForLocationIds(const std::vector& locationIds) const; virtual std::vector getTokenIdsForMatches(const std::vector& matches) const; virtual Id getTokenIdForFileNode(const FilePath& filePath) const; diff --git a/src/lib/data/location/LocationType.cpp b/src/lib/data/location/LocationType.cpp new file mode 100644 index 00000000..4d246ebc --- /dev/null +++ b/src/lib/data/location/LocationType.cpp @@ -0,0 +1,27 @@ +#include "data/location/LocationType.h" + +int locationTypeToInt(LocationType type) +{ + switch (type) + { + case LOCATION_TOKEN: + return 0; + case LOCATION_SCOPE: + return 1; + case LOCATION_LOCAL_SYMBOL: + return 2; + } +} + +LocationType intToLocationType(int value) +{ + switch (value) + { + case 0: + return LOCATION_TOKEN; + case 1: + return LOCATION_SCOPE; + case 2: + return LOCATION_LOCAL_SYMBOL; + } +} diff --git a/src/lib/data/location/LocationType.h b/src/lib/data/location/LocationType.h new file mode 100644 index 00000000..e450f1b7 --- /dev/null +++ b/src/lib/data/location/LocationType.h @@ -0,0 +1,14 @@ +#ifndef LOCATION_TYPE_H +#define LOCATION_TYPE_H + +enum LocationType +{ + LOCATION_TOKEN, + LOCATION_SCOPE, + LOCATION_LOCAL_SYMBOL +}; + +int locationTypeToInt(LocationType type); +LocationType intToLocationType(int value); + +#endif // LOCATION_TYPE_H diff --git a/src/lib/data/location/TokenLocation.cpp b/src/lib/data/location/TokenLocation.cpp index 2310dc77..5574b25a 100644 --- a/src/lib/data/location/TokenLocation.cpp +++ b/src/lib/data/location/TokenLocation.cpp @@ -69,7 +69,7 @@ Id TokenLocation::getTokenId() const return m_tokenId; } -TokenLocation::LocationType TokenLocation::getType() const +LocationType TokenLocation::getType() const { return m_type; } diff --git a/src/lib/data/location/TokenLocation.h b/src/lib/data/location/TokenLocation.h index 5dfd4503..f198567b 100644 --- a/src/lib/data/location/TokenLocation.h +++ b/src/lib/data/location/TokenLocation.h @@ -5,6 +5,7 @@ #include #include +#include "data/location/LocationType.h" #include "utility/file/FilePath.h" #include "utility/types.h" @@ -15,13 +16,6 @@ class TokenLocationLine; class TokenLocation { public: - enum LocationType - { - LOCATION_TOKEN, - LOCATION_SCOPE - }; - - TokenLocation(Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart); TokenLocation(Id locationId, Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart); TokenLocation(TokenLocation* other, TokenLocationLine* line, unsigned int columnNumber, bool isStart); TokenLocation(const TokenLocation& other, TokenLocationLine* line); diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index fcc70bcf..13a3fbd1 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -105,6 +105,8 @@ public: virtual Id onTemplateMemberFunctionSpecializationParsed( const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction) = 0; + virtual Id onLocalSymbolParsed(const std::string& name, const ParseLocation& location) = 0; + virtual Id onFileParsed(const FileInfo& fileInfo) = 0; virtual Id onFileIncludeParsed( const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo) = 0; diff --git a/src/lib/data/parser/ParserClientImpl.cpp b/src/lib/data/parser/ParserClientImpl.cpp index af596fb2..50f03fbd 100644 --- a/src/lib/data/parser/ParserClientImpl.cpp +++ b/src/lib/data/parser/ParserClientImpl.cpp @@ -5,6 +5,7 @@ #include "data/graph/Edge.h" #include "utility/logging/logging.h" #include "utility/utility.h" +#include "data/location/TokenLocation.h" ParserClientImpl::ParserClientImpl() { @@ -58,7 +59,7 @@ Id ParserClientImpl::onTypedefParsed( log("typedef", typedefName.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_TYPEDEF, typedefName, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); addAccess(nodeId, access); return 0; @@ -75,8 +76,8 @@ Id ParserClientImpl::onClassParsed( nameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : (scopeLocation.isValid() ? DEFINITION_EXPLICIT : DEFINITION_NONE)) ); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); addAccess(nodeId, access); return 0; @@ -93,8 +94,8 @@ Id ParserClientImpl::onStructParsed( nameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : (scopeLocation.isValid() ? DEFINITION_EXPLICIT : DEFINITION_NONE)) ); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); addAccess(nodeId, access); return 0; @@ -105,7 +106,7 @@ Id ParserClientImpl::onGlobalVariableParsed(const ParseLocation& location, const log("global", variable.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, variable, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); return 0; } @@ -115,7 +116,7 @@ Id ParserClientImpl::onFieldParsed(const ParseLocation& location, const NameHier log("field", field.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_FIELD, field, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); addAccess(nodeId, access); return 0; @@ -127,8 +128,8 @@ Id ParserClientImpl::onFunctionParsed( log("function", function.getQualifiedNameWithSignature(), location); Id nodeId = addNodeHierarchy(Node::NODE_FUNCTION, function, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); return 0; } @@ -144,8 +145,8 @@ Id ParserClientImpl::onMethodParsed( method, (isImplicit ? DEFINITION_IMPLICIT : ((location.isValid() && scopeLocation.isValid()) ? (DEFINITION_EXPLICIT) : DEFINITION_NONE)) ); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); addAccess(nodeId, access); return 0; @@ -157,8 +158,8 @@ Id ParserClientImpl::onNamespaceParsed( log("namespace", nameHierarchy.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_NAMESPACE, nameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); return 0; } @@ -170,8 +171,8 @@ Id ParserClientImpl::onEnumParsed( log("enum", nameHierarchy.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_ENUM, nameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); - addSourceLocation(nodeId, scopeLocation, true); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); addAccess(nodeId, access); return 0; @@ -182,7 +183,7 @@ Id ParserClientImpl::onEnumConstantParsed(const ParseLocation& location, const N log("enum constant", nameHierarchy.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, nameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); return 0; } @@ -193,7 +194,7 @@ Id ParserClientImpl::onTemplateParameterTypeParsed( log("template parameter type", templateParameterTypeNameHierarchy.getQualifiedName(), location); Id nodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT)); - addSourceLocation(nodeId, location, false); + addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN)); addAccess(nodeId, TokenComponentAccess::ACCESS_TEMPLATE); return 0; @@ -208,7 +209,7 @@ Id ParserClientImpl::onInheritanceParsed( Id childNodeId = addNodeHierarchy(Node::NODE_TYPE, childNameHierarchy, DEFINITION_NONE); Id parentNodeId = addNodeHierarchy(Node::NODE_TYPE, parentNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_INHERITANCE, childNodeId, parentNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -221,7 +222,7 @@ Id ParserClientImpl::onMethodOverrideParsed( Id overriddenNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overridden, DEFINITION_NONE); Id overriderNodeId = addNodeHierarchy(Node::NODE_FUNCTION, overrider, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_OVERRIDE, overriderNodeId, overriddenNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -233,7 +234,7 @@ Id ParserClientImpl::onCallParsed(const ParseLocation& location, const NameHiera Id callerNodeId = addNodeHierarchy(Node::NODE_FUNCTION, caller, DEFINITION_NONE); Id calleeNodeId = addNodeHierarchy(Node::NODE_FUNCTION, callee, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_CALL, callerNodeId, calleeNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -246,7 +247,7 @@ Id ParserClientImpl::onFieldUsageParsed( Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, DEFINITION_NONE); Id usedNodeId = addNodeHierarchy(Node::NODE_FIELD, usedNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -259,7 +260,7 @@ Id ParserClientImpl::onGlobalVariableUsageParsed( // or static variable used Id userNodeId = addNodeHierarchy(Node::NODE_FUNCTION, userNameHierarchy, DEFINITION_NONE); Id usedNodeId = addNodeHierarchy(Node::NODE_GLOBAL_VARIABLE, usedNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -272,7 +273,7 @@ Id ParserClientImpl::onEnumConstantUsageParsed( Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userNameHierarchy, DEFINITION_NONE); Id usedNodeId = addNodeHierarchy(Node::NODE_ENUM_CONSTANT, usedNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -289,7 +290,7 @@ Id ParserClientImpl::onTypeUsageParsed(const ParseLocation& location, const Name Id functionNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, user, DEFINITION_NONE); Id typeNodeId = addNodeHierarchy(Node::NODE_TYPE, used, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_TYPE_USAGE, functionNodeId, typeNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -307,7 +308,7 @@ Id ParserClientImpl::onTemplateArgumentTypeParsed( Id argumentNodeId = addNodeHierarchy(Node::NODE_TYPE, argumentTypeNameHierarchy, DEFINITION_NONE); Id templateNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, templateNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_TEMPLATE_ARGUMENT, templateNodeId, argumentNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return argumentNodeId; } @@ -325,7 +326,7 @@ Id ParserClientImpl::onTemplateDefaultArgumentTypeParsed( Id defaultArgumentNodeId = addNodeHierarchy(Node::NODE_TYPE, defaultArgumentTypeNameHierarchy, DEFINITION_NONE); Id parameterNodeId = addNodeHierarchy(Node::NODE_TYPE, templateParameterNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT, parameterNodeId, defaultArgumentNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return defaultArgumentNodeId; } @@ -343,7 +344,7 @@ Id ParserClientImpl::onTemplateSpecializationParsed( Id specializedId = addNodeHierarchy(Node::NODE_TYPE, specializedNameHierarchy, DEFINITION_NONE); Id recordNodeId = addNodeHierarchy(Node::NODE_TYPE, specializedFromNameHierarchy, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedId, recordNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -355,16 +356,30 @@ Id ParserClientImpl::onTemplateMemberFunctionSpecializationParsed( "template member function specialization", instantiatedFunction.getQualifiedNameWithSignature() + " -> " + specializedFunction.getQualifiedNameWithSignature(), location - ); + ); Id instantiatedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, instantiatedFunction, DEFINITION_NONE); Id specializedFunctionNodeId = addNodeHierarchy(Node::NODE_FUNCTION, specializedFunction, DEFINITION_NONE); Id edgeId = addEdge(Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION_OF, instantiatedFunctionNodeId, specializedFunctionNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } +Id ParserClientImpl::onLocalSymbolParsed(const std::string& name, const ParseLocation& location) +{ + log( + "local symbol", + name, + location + ); + + Id localSymbolId = addLocalSymbol(name); + addSourceLocation(localSymbolId, location, locationTypeToInt(LOCATION_LOCAL_SYMBOL)); + + return localSymbolId; +} + Id ParserClientImpl::onFileParsed(const FileInfo& fileInfo) // TODO: move up to nodes { log("file", fileInfo.path.str(), ParseLocation()); @@ -381,7 +396,7 @@ Id ParserClientImpl::onFileIncludeParsed(const ParseLocation& location, const Fi Id fileNodeId = addFile(fileInfo.path.fileName(), fileInfo.path.str(), utility::timeToString(fileInfo.lastWriteTime)); Id includedFileNodeId = addFile(includedFileInfo.path.fileName(), includedFileInfo.path.str(), utility::timeToString(includedFileInfo.lastWriteTime)); Id edgeId = addEdge(Edge::EDGE_INCLUDE, fileNodeId, includedFileNodeId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return fileNodeId; } @@ -392,8 +407,8 @@ Id ParserClientImpl::onMacroDefineParsed( log("macro", macroNameHierarchy.getQualifiedName(), location); Id macroId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, DEFINITION_EXPLICIT); - addSourceLocation(macroId, location, false); - addSourceLocation(macroId, scopeLocation, true); + addSourceLocation(macroId, location, locationTypeToInt(LOCATION_TOKEN)); + addSourceLocation(macroId, scopeLocation, locationTypeToInt(LOCATION_SCOPE)); //Id fileNodeId = getFileNodeId(location.filePath); // do we need this??? //addEdge(Edge::EDGE_MACRO_USAGE, fileNodeId, macroId, , location); @@ -407,7 +422,7 @@ Id ParserClientImpl::onMacroExpandParsed(const ParseLocation &location, const Na Id macroExpandId = addNodeHierarchy(Node::NODE_MACRO, macroNameHierarchy, DEFINITION_NONE); Id fileNodeId = addFile(location.filePath.str()); Id edgeId = addEdge(Edge::EDGE_MACRO_USAGE, fileNodeId, macroExpandId); - addSourceLocation(edgeId, location, false); + addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); return edgeId; } @@ -531,8 +546,17 @@ Id ParserClientImpl::addEdge(int type, Id sourceId, Id targetId) return m_storage->addEdge(type, sourceId, targetId); } +Id ParserClientImpl::addLocalSymbol(const std::string& name) +{ + if (!m_storage) + { + return 0; + } -void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& location, bool isScope) + return m_storage->addLocalSymbol(name); +} + +void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& location, int type) { if (!m_storage) { @@ -550,7 +574,7 @@ void ParserClientImpl::addSourceLocation(Id elementId, const ParseLocation& loca return; } - m_storage->addSourceLocation(elementId, location, isScope); + m_storage->addSourceLocation(elementId, location, type); } void ParserClientImpl::addComponentAccess(Id nodeId , int type) diff --git a/src/lib/data/parser/ParserClientImpl.h b/src/lib/data/parser/ParserClientImpl.h index 493666f3..c8b986f8 100644 --- a/src/lib/data/parser/ParserClientImpl.h +++ b/src/lib/data/parser/ParserClientImpl.h @@ -78,6 +78,8 @@ public: virtual Id onTemplateMemberFunctionSpecializationParsed( const ParseLocation& location, const NameHierarchy& instantiatedFunction, const NameHierarchy& specializedFunction); + virtual Id onLocalSymbolParsed(const std::string& name, const ParseLocation& location); + virtual Id onFileParsed(const FileInfo& fileInfo); virtual Id onFileIncludeParsed( const ParseLocation& location, const FileInfo& fileInfo, const FileInfo& includedFileInfo); @@ -99,7 +101,8 @@ private: Id addFile(const std::string& filePath); Id addNode(Node::NodeType nodeType, NameHierarchy nameHierarchy, DefinitionType definitionType); Id addEdge(int type, Id sourceId, Id targetId); - void addSourceLocation(Id elementId, const ParseLocation& location, bool isScope); + Id addLocalSymbol(const std::string& name); + void addSourceLocation(Id elementId, const ParseLocation& location, int type); void addComponentAccess(Id nodeId , int type); void addCommentLocation(const ParseLocation& location); void addError(const std::string& message, bool fatal, const ParseLocation& location); diff --git a/src/lib/utility/messaging/type/MessageActivateLocalSymbols.h b/src/lib/utility/messaging/type/MessageActivateLocalSymbols.h new file mode 100644 index 00000000..c9e75ddc --- /dev/null +++ b/src/lib/utility/messaging/type/MessageActivateLocalSymbols.h @@ -0,0 +1,41 @@ +#ifndef MESSAGE_ACTIVATE_LOCAL_SYMBOLS_H +#define MESSAGE_ACTIVATE_LOCAL_SYMBOLS_H + +#include "utility/messaging/Message.h" +#include "utility/types.h" + +class MessageActivateLocalSymbols + : public Message +{ +public: + MessageActivateLocalSymbols() + { + } + + MessageActivateLocalSymbols(const std::vector& symbolIds) + : symbolIds(symbolIds) + { + } + + void addSymbol(Id symbolId) + { + symbolIds.push_back(symbolId); + } + + static const std::string getStaticType() + { + return "MessageActivateLocalSymbols"; + } + + virtual void print(std::ostream& os) const + { + for (const Id& symbolId : symbolIds) + { + os << symbolId << " "; + } + } + + std::vector symbolIds; +}; + +#endif // MESSAGE_ACTIVATE_LOCAL_SYMBOLS_H diff --git a/src/lib_gui/qt/element/QtCodeArea.cpp b/src/lib_gui/qt/element/QtCodeArea.cpp index 03da4352..5d10d09c 100644 --- a/src/lib_gui/qt/element/QtCodeArea.cpp +++ b/src/lib_gui/qt/element/QtCodeArea.cpp @@ -9,6 +9,7 @@ #include #include +#include "utility/messaging/type/MessageActivateLocalSymbols.h" #include "utility/messaging/type/MessageActivateTokenLocations.h" #include "utility/messaging/type/MessageActivateTokenIds.h" #include "utility/messaging/type/MessageFocusIn.h" @@ -355,7 +356,7 @@ void QtCodeArea::paintEvent(QPaintEvent* event) painter.setPen(QPen(color.border.c_str())); painter.setBrush(QBrush(color.fill.c_str())); - if (annotation.isScope) + if (annotation.locationType == LOCATION_SCOPE) { painter.drawRoundedRect( 0, top + (annotation.startLine - m_startLineNumber) * blockHeight, @@ -425,42 +426,10 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event) else if (!m_fileWidget->getErrorMessages().size()) { QTextCursor cursor = this->cursorForPosition(event->pos()); - std::vector annotations = getAnnotationsForPosition(cursor.position()); + std::vector annotations = getNonScopeAnnotationsForPosition(cursor.position()); - std::vector locationIds; - std::set tokenIds; - - bool allActive = true; - for (const Annotation* annotation : annotations) - { - if (!annotation->isActive) - { - allActive = false; - } - - if (annotation->locationId > 0) - { - locationIds.push_back(annotation->locationId); - } - if (annotation->tokenId > 0) - { - tokenIds.insert(annotation->tokenId); - } - } - - if (allActive) - { - return; - } - - if (locationIds.size()) - { - MessageActivateTokenLocations(locationIds).dispatch(); - } - else if (tokenIds.size()) // fallback for links in project description - { - MessageActivateTokenIds(utility::toVector(tokenIds)).dispatch(); - } + activateTokenLocations(annotations); + activateLocalSymbols(annotations); } } } @@ -481,7 +450,7 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event) QTextCursor cursor = this->cursorForPosition(event->pos()); - std::vector annotations = getAnnotationsForPosition(cursor.position()); + std::vector annotations = getNonScopeAnnotationsForPosition(cursor.position()); bool same = annotations.size() == m_hoveredAnnotations.size(); if (same) @@ -558,13 +527,13 @@ void QtCodeArea::setIDECursorPosition() MessageMoveIDECursor(m_locationFile->getFilePath().str(), lineColumn.first, lineColumn.second).dispatch(); } -std::vector QtCodeArea::getAnnotationsForPosition(int pos) const +std::vector QtCodeArea::getNonScopeAnnotationsForPosition(int pos) const { std::vector annotations; for (const Annotation& annotation : m_annotations) { - if (!annotation.isScope && pos >= annotation.start && pos <= annotation.end) + if (annotation.locationType != LOCATION_SCOPE && pos >= annotation.start && pos <= annotation.end) { annotations.push_back(&annotation); } @@ -573,6 +542,75 @@ std::vector QtCodeArea::getAnnotationsForPosition return annotations; } +void QtCodeArea::activateTokenLocations(const std::vector& annotations) +{ + std::vector tokenLocationIds; + std::set tokenIds; + + bool allActive = true; + for (const Annotation* annotation : annotations) + { + if (annotation->locationType == LOCATION_TOKEN) + { + if (!annotation->isActive) + { + allActive = false; + } + + if (annotation->locationId > 0) + { + tokenLocationIds.push_back(annotation->locationId); + } + if (annotation->tokenId > 0) + { + tokenIds.insert(annotation->tokenId); + } + } + } + + if (!allActive) + { + if (tokenLocationIds.size()) + { + MessageActivateTokenLocations(tokenLocationIds).dispatch(); + } + else if (tokenIds.size()) // fallback for links in project description + { + MessageActivateTokenIds(utility::toVector(tokenIds)).dispatch(); + } + } +} + +void QtCodeArea::activateLocalSymbols(const std::vector& annotations) +{ + std::vector localSymbolIds; + + bool allActive = true; + for (const Annotation* annotation : annotations) + { + if (annotation->locationType == LOCATION_LOCAL_SYMBOL) + { + if (!annotation->isActive) + { + allActive = false; + } + + if (annotation->tokenId > 0) + { + localSymbolIds.push_back(annotation->tokenId); + } + } + } + + if (!allActive) + { + if (localSymbolIds.size()) + { + MessageActivateLocalSymbols(localSymbolIds).dispatch(); + } + } +} + void QtCodeArea::createAnnotations(std::shared_ptr locationFile) { locationFile->forEachStartTokenLocation( @@ -624,7 +662,7 @@ void QtCodeArea::createAnnotations(std::shared_ptr locationFi annotation.tokenId = startLocation->getTokenId(); annotation.locationId = startLocation->getId(); - annotation.isScope = (startLocation->getType() == TokenLocation::LOCATION_SCOPE); + annotation.locationType = startLocation->getType(); annotation.isError = false; annotation.isActive = false; @@ -637,7 +675,8 @@ void QtCodeArea::createAnnotations(std::shared_ptr locationFi void QtCodeArea::annotateText() { - const std::vector& activeIds = m_fileWidget->getActiveTokenIds(); + const std::vector& activeTokenIds = m_fileWidget->getActiveTokenIds(); + const std::vector& activeLocalSymbolIds = m_fileWidget->getActiveLocalSymbolIds(); const std::vector& focusIds = m_fileWidget->getFocusedTokenIds(); bool isError = m_fileWidget->hasErrors(); @@ -648,7 +687,10 @@ void QtCodeArea::annotateText() bool wasActive = annotation.isActive; bool wasFocused = annotation.isFocused; - annotation.isActive = std::find(activeIds.begin(), activeIds.end(), annotation.tokenId) != activeIds.end(); + annotation.isActive = ( + std::find(activeTokenIds.begin(), activeTokenIds.end(), annotation.tokenId) != activeTokenIds.end() || + std::find(activeLocalSymbolIds.begin(), activeLocalSymbolIds.end(), annotation.tokenId) != activeLocalSymbolIds.end() + ); annotation.isFocused = std::find(focusIds.begin(), focusIds.end(), annotation.tokenId) != focusIds.end(); annotation.isError = isError; @@ -827,7 +869,8 @@ const QtCodeArea::AnnotationColor& QtCodeArea::getAnnotationColorForAnnotation(c { ColorScheme* scheme = ColorScheme::getInstance().get(); std::vector types; - types.push_back("location"); + types.push_back("token"); + types.push_back("local_symbol"); types.push_back("scope"); types.push_back("error"); @@ -850,14 +893,18 @@ const QtCodeArea::AnnotationColor& QtCodeArea::getAnnotationColorForAnnotation(c size_t i = 0; - if (annotation.isScope) + if (annotation.locationType == LOCATION_LOCAL_SYMBOL) { i = 3; } - else if (annotation.isError) + else if (annotation.locationType == LOCATION_SCOPE) { i = 6; } + else if (annotation.isError) + { + i = 9; + } if (annotation.isActive) { diff --git a/src/lib_gui/qt/element/QtCodeArea.h b/src/lib_gui/qt/element/QtCodeArea.h index cfb299ec..9edf9441 100644 --- a/src/lib_gui/qt/element/QtCodeArea.h +++ b/src/lib_gui/qt/element/QtCodeArea.h @@ -7,6 +7,7 @@ #include +#include "data/location/LocationType.h" #include "utility/types.h" class QDragMoveEvent; @@ -124,7 +125,7 @@ private: Id tokenId; Id locationId; - bool isScope; + LocationType locationType; bool isError; bool isActive; @@ -137,7 +138,9 @@ private: std::string fill; }; - std::vector getAnnotationsForPosition(int pos) const; + std::vector getNonScopeAnnotationsForPosition(int pos) const; + void activateTokenLocations(const std::vector& annotations); + void activateLocalSymbols(const std::vector& annotations); void createAnnotations(std::shared_ptr locationFile); void annotateText(); diff --git a/src/lib_gui/qt/element/QtCodeFile.cpp b/src/lib_gui/qt/element/QtCodeFile.cpp index c053db61..75f348e8 100644 --- a/src/lib_gui/qt/element/QtCodeFile.cpp +++ b/src/lib_gui/qt/element/QtCodeFile.cpp @@ -129,6 +129,11 @@ const std::vector& QtCodeFile::getActiveTokenIds() const return m_parent->getActiveTokenIds(); } +const std::vector& QtCodeFile::getActiveLocalSymbolIds() const +{ + return m_parent->getActiveLocalSymbolIds(); +} + const std::vector& QtCodeFile::getFocusedTokenIds() const { return m_parent->getFocusedTokenIds(); diff --git a/src/lib_gui/qt/element/QtCodeFile.h b/src/lib_gui/qt/element/QtCodeFile.h index 0c26cb6a..c96a2501 100644 --- a/src/lib_gui/qt/element/QtCodeFile.h +++ b/src/lib_gui/qt/element/QtCodeFile.h @@ -39,6 +39,7 @@ public: std::string getFileName() const; const std::vector& getActiveTokenIds() const; + const std::vector& getActiveLocalSymbolIds() const; const std::vector& getFocusedTokenIds() const; const std::vector& getErrorMessages() const; diff --git a/src/lib_gui/qt/element/QtCodeFileList.cpp b/src/lib_gui/qt/element/QtCodeFileList.cpp index 187405f0..a169f2f4 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.cpp +++ b/src/lib_gui/qt/element/QtCodeFileList.cpp @@ -85,6 +85,17 @@ const std::vector& QtCodeFileList::getActiveTokenIds() const void QtCodeFileList::setActiveTokenIds(const std::vector& activeTokenIds) { m_activeTokenIds = activeTokenIds; + m_activeLocalSymbolIds.clear(); +} + +const std::vector& QtCodeFileList::getActiveLocalSymbolIds() const +{ + return m_activeLocalSymbolIds; +} + +void QtCodeFileList::setActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds) +{ + m_activeLocalSymbolIds = activeLocalSymbolIds; } const std::vector& QtCodeFileList::getFocusedTokenIds() const diff --git a/src/lib_gui/qt/element/QtCodeFileList.h b/src/lib_gui/qt/element/QtCodeFileList.h index 52e00164..950b6155 100644 --- a/src/lib_gui/qt/element/QtCodeFileList.h +++ b/src/lib_gui/qt/element/QtCodeFileList.h @@ -39,6 +39,9 @@ public: const std::vector& getActiveTokenIds() const; void setActiveTokenIds(const std::vector& activeTokenIds); + const std::vector& getActiveLocalSymbolIds() const; + void setActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds); + const std::vector& getFocusedTokenIds() const; void setFocusedTokenIds(const std::vector& focusedTokenIds); @@ -77,6 +80,7 @@ private: std::vector> m_files; std::vector m_activeTokenIds; + std::vector m_activeLocalSymbolIds; std::vector m_focusedTokenIds; std::vector m_errorMessages; diff --git a/src/lib_gui/qt/view/QtCodeView.cpp b/src/lib_gui/qt/view/QtCodeView.cpp index 5ff34577..94e7b265 100644 --- a/src/lib_gui/qt/view/QtCodeView.cpp +++ b/src/lib_gui/qt/view/QtCodeView.cpp @@ -19,6 +19,7 @@ QtCodeView::QtCodeView(ViewLayout* viewLayout) , m_setFileStateFunctor(std::bind(&QtCodeView::doSetFileState, this, std::placeholders::_1, std::placeholders::_2)) , m_doShowFirstActiveSnippetFunctor(std::bind(&QtCodeView::doShowFirstActiveSnippet, this, std::placeholders::_1, std::placeholders::_2)) , m_doShowActiveTokenIdsFunctor(std::bind(&QtCodeView::doShowActiveTokenIds, this, std::placeholders::_1)) + , m_doShowActiveLocalSymbolIdsFunctor(std::bind(&QtCodeView::doShowActiveLocalSymbolIds, this, std::placeholders::_1)) , m_focusTokenIdsFunctor(std::bind(&QtCodeView::doFocusTokenIds, this, std::placeholders::_1)) , m_defocusTokenIdsFunctor(std::bind(&QtCodeView::doDefocusTokenIds, this)) , m_showContentsFunctor(std::bind(&QtCodeView::doShowContents, this)) @@ -91,6 +92,11 @@ void QtCodeView::showActiveTokenIds(const std::vector& activeTokenIds) m_doShowActiveTokenIdsFunctor(activeTokenIds); } +void QtCodeView::showActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds) +{ + m_doShowActiveLocalSymbolIdsFunctor(activeLocalSymbolIds); +} + void QtCodeView::focusTokenIds(const std::vector& focusedTokenIds) { m_focusTokenIdsFunctor(focusedTokenIds); @@ -194,6 +200,12 @@ void QtCodeView::doShowActiveTokenIds(const std::vector& activeTokenIds) m_widget->showActiveTokenIds(); } +void QtCodeView::doShowActiveLocalSymbolIds(const std::vector& localSymbolIds) +{ + m_widget->setActiveLocalSymbolIds(localSymbolIds); + m_widget->showActiveTokenIds(); +} + void QtCodeView::doFocusTokenIds(const std::vector& focusedTokenIds) { m_widget->focusTokenIds(focusedTokenIds); diff --git a/src/lib_gui/qt/view/QtCodeView.h b/src/lib_gui/qt/view/QtCodeView.h index 33b582d2..9ffaef0b 100644 --- a/src/lib_gui/qt/view/QtCodeView.h +++ b/src/lib_gui/qt/view/QtCodeView.h @@ -39,6 +39,7 @@ public: virtual void showFirstActiveSnippet(const std::vector& activeTokenIds, bool scrollTo); virtual void showActiveTokenIds(const std::vector& activeTokenIds); + virtual void showActiveLocalSymbolIds(const std::vector& activeLocalSymbolIds); virtual void focusTokenIds(const std::vector& focusedTokenIds); virtual void defocusTokenIds(); @@ -59,6 +60,7 @@ private: void doShowFirstActiveSnippet(const std::vector& activeTokenIds, bool scrollTo); void doShowActiveTokenIds(const std::vector& activeTokenIds); + void doShowActiveLocalSymbolIds(const std::vector& localSymbolIds); void doFocusTokenIds(const std::vector& focusedTokenIds); void doDefocusTokenIds(); @@ -77,6 +79,7 @@ private: QtThreadedFunctor m_setFileStateFunctor; QtThreadedFunctor&, bool> m_doShowFirstActiveSnippetFunctor; QtThreadedFunctor&> m_doShowActiveTokenIdsFunctor; + QtThreadedFunctor&> m_doShowActiveLocalSymbolIdsFunctor; QtThreadedFunctor&> m_focusTokenIdsFunctor; QtThreadedFunctor<> m_defocusTokenIdsFunctor; QtThreadedFunctor<> m_showContentsFunctor; diff --git a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp index f4530519..7c167a47 100644 --- a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp @@ -1305,7 +1305,18 @@ void ASTVisitor::RecordDeclRef( break; case ST_LocalVariable: case ST_Parameter: - // Do nothing. + if (clang::VarDecl* varDecl = clang::dyn_cast(d)) + { + ParseLocation declLocation = getParseLocation(varDecl->getSourceRange()); // i think we dont need this since this is the decl/def + std::string name = + declLocation.filePath.str() + "::" + + varDecl->getNameAsString() + "<" + + std::to_string(declLocation.startLineNumber) + ":" + + std::to_string(declLocation.startColumnNumber) + ">"; + m_client->onLocalSymbolParsed( + name, + parseLocation); + } break; default: fallback = true; @@ -1374,6 +1385,21 @@ void ASTVisitor::RecordDeclRef( contextNameHierarchy, declNameHierarchy); break; + case ST_LocalVariable: + case ST_Parameter: + if (clang::VarDecl* varDecl = clang::dyn_cast(d)) + { + ParseLocation declLocation = getParseLocation(varDecl->getSourceRange()); // i think we dont need this since this is the decl/def + std::string name = + declLocation.filePath.str() + "::" + + varDecl->getNameAsString() + "<" + + std::to_string(declLocation.startLineNumber) + ":" + + std::to_string(declLocation.startColumnNumber) + ">"; + m_client->onLocalSymbolParsed( + name, + parseLocation); + } + break; case ST_Max: switch (refType) { @@ -1408,10 +1434,6 @@ void ASTVisitor::RecordDeclRef( break; } break; - case ST_LocalVariable: - case ST_Parameter: - // Do nothing. - break; default: fallback = true; break; diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index e90c954b..65a8b86e 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -45,7 +45,7 @@ public: "struct A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->structs.size(), 1); TS_ASSERT_EQUALS(client->structs[0], "A <1:1 <1:8 1:8> 3:1>"); @@ -55,7 +55,7 @@ public: { std::shared_ptr client = parseCode( "struct A;\n" - ); + ); TS_ASSERT_EQUALS(client->structs.size(), 1); TS_ASSERT_EQUALS(client->structs[0], "A <1:8 1:8>"); @@ -65,7 +65,7 @@ public: { std::shared_ptr client = parseCode( "int x;\n" - ); + ); TS_ASSERT_EQUALS(client->globalVariables.size(), 1); TS_ASSERT_EQUALS(client->globalVariables[0], "x <1:5 1:5>"); @@ -85,7 +85,7 @@ public: "private:\n" " const int d;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->fields.size(), 4); TS_ASSERT_EQUALS(client->fields[0], "private A::a <3:6 3:6>"); @@ -101,7 +101,7 @@ public: "{\n" " return 1;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->functions.size(), 1); TS_ASSERT_EQUALS(client->functions[0], "int ceil(float) <1:1 <1:5 1:8> 4:1>"); @@ -114,7 +114,7 @@ public: "{\n" " return static_cast(a) + 1;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->functions.size(), 1); TS_ASSERT_EQUALS(client->functions[0], "static int ceil(float) <1:1 <1:12 1:15> 4:1>"); @@ -128,7 +128,7 @@ public: "public:\n" " B();\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 1); TS_ASSERT_EQUALS(client->methods[0], "public void B::B() <4:2 4:2>"); @@ -145,7 +145,7 @@ public: "B::B()\n" "{\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "public void B::B() <4:2 4:2>"); @@ -162,7 +162,7 @@ public: "public:\n" " virtual void process();\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "public virtual void B::process() <4:15 4:21>"); @@ -176,7 +176,7 @@ public: "protected:\n" " virtual void process() = 0;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "protected pure virtual void B::process() <4:15 4:21>"); @@ -188,7 +188,7 @@ public: "namespace A\n" "{\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->namespaces.size(), 1); TS_ASSERT_EQUALS(client->namespaces[0], "A <1:1 <1:11 1:11> 3:1>"); @@ -200,7 +200,7 @@ public: "namespace\n" "{\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->namespaces.size(), 1); TS_ASSERT_EQUALS(client->namespaces[0], "anonymous namespace (input.cc) <1:1 3:1>"); @@ -212,7 +212,7 @@ public: "enum E\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->enums.size(), 1); TS_ASSERT_EQUALS(client->enums[0], "E <1:1 <1:6 1:6> 3:1>"); @@ -225,7 +225,7 @@ public: "{\n" " P\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->enumConstants.size(), 1); TS_ASSERT_EQUALS(client->enumConstants[0], "E::P <3:2 3:2>"); @@ -235,7 +235,7 @@ public: { std::shared_ptr client = parseCode( "typedef unsigned int uint;\n" - ); + ); TS_ASSERT_EQUALS(client->typedefs.size(), 1); TS_ASSERT_EQUALS(client->typedefs[0], "uint <1:22 1:25>"); @@ -248,7 +248,7 @@ public: "{\n" " typedef unsigned int uint;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typedefs.size(), 1); TS_ASSERT_EQUALS(client->typedefs[0], "test::uint <3:23 3:26>"); @@ -261,7 +261,7 @@ public: "{\n" " typedef unsigned int uint;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typedefs.size(), 1); TS_ASSERT_EQUALS(client->typedefs[0], "anonymous namespace (input.cc)::uint <3:23 3:26>"); @@ -274,7 +274,8 @@ public: "void test()\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->macros.size(), 1); TS_ASSERT_EQUALS(client->macros[0], "PI <1:9 <1:9 1:10> 1:8>"); } @@ -286,7 +287,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:20 1:20>"); @@ -299,7 +300,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:17 1:17>"); @@ -312,7 +313,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:15 1:15>"); @@ -325,7 +326,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:16 1:16>"); @@ -339,7 +340,7 @@ public: "template \n" "class A\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A

::p <3:14 3:14>"); @@ -353,7 +354,7 @@ public: "template \n" "class A\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A

::p <3:14 3:14>"); @@ -365,7 +366,7 @@ public: "template \n" "class A\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T1 <1:20 1:21>"); @@ -378,7 +379,7 @@ public: "template class T1, T1& T2>\n" "class A\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A typename T1, T1 & T2>::T1 <1:36 1:37>"); @@ -391,7 +392,7 @@ public: // "template class T1, T1& T2>\n" // test that t1 uses int // "class A\n" // "{};\n" - // ); + // ); //} void test_cxx_parser_finds_template_template_parameter_of_template_class() @@ -407,7 +408,7 @@ public: "{\n" " B ba;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:20 1:20>"); @@ -421,7 +422,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:23 1:23>"); @@ -436,7 +437,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:18 1:18>"); @@ -449,7 +450,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A typename... T>::T <1:42 1:42>"); @@ -462,7 +463,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:20 1:20>"); @@ -476,7 +477,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->classes.size(), 1); TS_ASSERT_EQUALS(client->classes[0], "A <1:1 <2:7 2:7> 4:1>"); @@ -495,7 +496,8 @@ public: "template \n" "U A::foo()\n" "{}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 3); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::foo::U <4:21 4:21>"); TS_ASSERT_EQUALS(client->templateParameterTypes[1], "A::T <1:20 1:20>"); @@ -513,7 +515,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->classes.size(), 2); TS_ASSERT_EQUALS(client->classes[0], "A <1:1 <2:7 2:7> 4:1>"); TS_ASSERT_EQUALS(client->classes[1], "A <5:1 <6:7 6:7> 8:1>"); @@ -530,7 +533,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->classes.size(), 2); TS_ASSERT_EQUALS(client->classes[0], "A <1:1 <2:7 2:7> 4:1>"); TS_ASSERT_EQUALS(client->classes[1], "A <5:1 <6:7 6:7> 8:1>"); @@ -547,7 +551,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->classes.size(), 2); TS_ASSERT_EQUALS(client->classes[0], "A <1:1 <2:7 2:7> 4:1>"); @@ -562,7 +566,7 @@ public: "{\n" " int foo;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->fields.size(), 1); TS_ASSERT_EQUALS(client->fields[0], "private A::foo <4:6 4:8>"); @@ -576,7 +580,7 @@ public: "{\n" " T foo;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->fields.size(), 1); TS_ASSERT_EQUALS(client->fields[0], "private A::foo <4:4 4:6>"); @@ -590,7 +594,7 @@ public: "{\n" " int foo();\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 1); TS_ASSERT_EQUALS(client->methods[0], "private int A::foo() <4:6 4:8>"); @@ -604,7 +608,7 @@ public: "{\n" " return a;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "test::T <1:20 1:20>"); @@ -618,7 +622,7 @@ public: "{\n" " return a + T;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "test::T <1:15 1:15>"); @@ -632,7 +636,7 @@ public: "{\n" " return T ? a : 0;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "test::T <1:16 1:16>"); @@ -648,7 +652,7 @@ public: "{\n" " return a;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "test

::p <3:14 3:14>"); @@ -664,7 +668,7 @@ public: "{\n" " return a;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "test

::p <3:14 3:14>"); @@ -681,7 +685,7 @@ public: "{\n" " return a;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 2); TS_ASSERT_EQUALS(client->templateParameterTypes[0], "A::T <1:20 1:20>"); @@ -701,7 +705,7 @@ public: "{\n" " return test(1);\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->functions.size(), 3); TS_ASSERT_EQUALS(client->functions[0], "T test(T) <1:1 <2:3 2:6> 5:1>"); @@ -716,7 +720,7 @@ public: "{\n" " [](){}();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->functions.size(), 2); TS_ASSERT_EQUALS(client->functions[0], "void lambdaCaller() <1:1 <1:6 1:17> 4:1>"); @@ -725,6 +729,30 @@ public: TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 3:2() <3:8 3:8>"); } + void test_cxx_parser_finds_definition_of_local_symbol_in_function_parameter_list() + { + std::shared_ptr client = parseCode( + "void test(int a)\n" + "{\n" + "}\n" + ); + + TS_ASSERT_EQUALS(client->localSymbols.size(), 1); + TS_ASSERT_EQUALS(client->localSymbols[0], "input.cc::a<1:11>"); + } + + void test_cxx_parser_finds_definition_of_local_symbol_in_function_scope() + { + std::shared_ptr client = parseCode( + "void test()\n" + "{\n" + " int a;\n" + "}\n" + ); + + TS_ASSERT_EQUALS(client->localSymbols.size(), 1); + TS_ASSERT_EQUALS(client->localSymbols[0], "input.cc::a<3:2>"); + } /////////////////////////////////////////////////////////////////////////////// // test finding nested symbol definitions and declarations @@ -816,7 +844,7 @@ public: "{\n" " int x;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->globalVariables.size(), 1); TS_ASSERT_EQUALS(client->globalVariables[0], "n::x <2:6 2:6>"); @@ -834,7 +862,7 @@ public: " static const int amount;\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->fields.size(), 1); TS_ASSERT_EQUALS(client->fields[0], "private B::C::amount <7:20 7:25>"); @@ -847,7 +875,7 @@ public: "{\n" " int sum(int a, int b);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->functions.size(), 1); TS_ASSERT_EQUALS(client->functions[0], "int anonymous namespace (input.cc)::sum(int, int) <3:6 3:8>"); @@ -863,7 +891,7 @@ public: " bool isGreat() const;\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->methods.size(), 1); TS_ASSERT_EQUALS(client->methods[0], "private bool B::C::isGreat() const <5:8 5:14>"); @@ -878,7 +906,7 @@ public: " {\n" " }\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->namespaces.size(), 2); TS_ASSERT_EQUALS(client->namespaces[0], "A <1:1 <1:11 1:11> 6:1>"); @@ -895,7 +923,7 @@ public: " {\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->enums.size(), 1); TS_ASSERT_EQUALS(client->enums[0], "public B::Z <4:2 <4:7 4:7> 6:2>"); @@ -910,7 +938,7 @@ public: " {\n" " };\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->enums.size(), 1); TS_ASSERT_EQUALS(client->enums[0], "n::Z <3:2 <3:7 3:7> 5:2>"); @@ -928,7 +956,7 @@ public: " TEST_TWO\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->enums.size(), 1); TS_ASSERT_EQUALS(client->enums[0], "private A::TestType <4:2 <4:7 4:14> 8:2>"); @@ -947,7 +975,7 @@ public: " };\n" " TestType foo;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "A::foo -> A::TestType <9:2 9:9>"); @@ -965,7 +993,7 @@ public: " TEST_TWO\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->enumConstants.size(), 2); TS_ASSERT_EQUALS(client->enumConstants[0], "A::TestType::TEST_ONE <6:3 6:10>"); @@ -983,7 +1011,7 @@ public: " T foo;\n" " };\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "A::B::foo -> A::T <6:3 6:3>"); @@ -999,7 +1027,7 @@ public: { std::shared_ptr client = parseCode( "int x;\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "x -> int <1:1 1:3>"); @@ -1009,7 +1037,7 @@ public: { std::shared_ptr client = parseCode( "typedef unsigned int uint;\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "uint -> unsigned int <1:9 1:16>"); @@ -1023,7 +1051,7 @@ public: " struct TestStruct{};\n" "}\n" "typedef test::TestStruct globalTestStruct;\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "globalTestStruct -> test::TestStruct <5:15 5:24>"); @@ -1034,7 +1062,7 @@ public: std::shared_ptr client = parseCode( "typedef unsigned int uint;\n" "uint number;\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[1], "number -> uint <2:1 2:4>"); @@ -1045,7 +1073,7 @@ public: std::shared_ptr client = parseCode( "class A {};\n" "class B : A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : private A <2:11 2:11>"); @@ -1056,7 +1084,7 @@ public: std::shared_ptr client = parseCode( "class A {};\n" "class B : public A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : public A <2:18 2:18>"); @@ -1067,7 +1095,7 @@ public: std::shared_ptr client = parseCode( "class A {};\n" "class B : protected A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : protected A <2:21 2:21>"); @@ -1078,7 +1106,7 @@ public: std::shared_ptr client = parseCode( "class A {};\n" "class B : private A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : private A <2:19 2:19>"); @@ -1093,7 +1121,7 @@ public: " : public A\n" " , private B\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 2); TS_ASSERT_EQUALS(client->inheritances[0], "C : public A <4:11 4:11>"); @@ -1105,7 +1133,7 @@ public: std::shared_ptr client = parseCode( "struct A {};\n" "struct B : A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : public A <2:12 2:12>"); @@ -1116,7 +1144,7 @@ public: std::shared_ptr client = parseCode( "struct A {};\n" "struct B : public A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : public A <2:19 2:19>"); @@ -1127,7 +1155,7 @@ public: std::shared_ptr client = parseCode( "struct A {};\n" "struct B : protected A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : protected A <2:22 2:22>"); @@ -1138,7 +1166,7 @@ public: std::shared_ptr client = parseCode( "struct A {};\n" "struct B : private A {};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : private A <2:20 2:20>"); @@ -1153,7 +1181,7 @@ public: " : public A\n" " , private B\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 2); TS_ASSERT_EQUALS(client->inheritances[0], "C : public A <4:11 4:11>"); @@ -1169,7 +1197,7 @@ public: "class B : public A {\n" " void foo();\n" "};" - ); + ); TS_ASSERT_EQUALS(client->overrides.size(), 1); TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo() <5:7 5:9>"); @@ -1187,7 +1215,7 @@ public: "class C : public B {\n" " void foo();\n" "};" - ); + ); TS_ASSERT_EQUALS(client->overrides.size(), 2); TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo() <5:7 5:9>"); @@ -1204,7 +1232,7 @@ public: " int foo();\n" "};\n", false - ); + ); TS_ASSERT_EQUALS(client->overrides.size(), 1); TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> int B::foo() <5:6 5:8>"); @@ -1220,7 +1248,7 @@ public: "class B : public A {\n" " void foo();\n" "};" - ); + ); TS_ASSERT_EQUALS(client->overrides.size(), 0); } @@ -1234,7 +1262,7 @@ public: "class B : public A {\n" " int foo(int a, int b);\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->overrides.size(), 0); } @@ -1250,7 +1278,7 @@ public: "{\n" " sum(1, 2);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:2 7:4>"); @@ -1270,7 +1298,7 @@ public: "{\n" " sum(1, 2);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "void func(bool) -> int sum(int, int) <10:2 10:4>"); @@ -1292,7 +1320,7 @@ public: " sum(1, 2);\n" " sum(1.0f, 0.5f);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <11:2 11:4>"); @@ -1310,7 +1338,7 @@ public: "{\n" " return sum(1, sum(2, 3));\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "int main() -> int sum(int, int) <7:9 7:11>"); @@ -1331,7 +1359,7 @@ public: " return sum(1, 2);\n" " }\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "int App::main() -> int sum(int, int) <9:10 9:12>"); @@ -1347,7 +1375,7 @@ public: "{\n" " App app;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <6:6 6:8>"); @@ -1365,7 +1393,7 @@ public: "{\n" " App();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <8:2 8:4>"); @@ -1383,7 +1411,7 @@ public: " App() : item() {}\n" " Item item;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item() <7:10 7:13>"); @@ -1405,7 +1433,7 @@ public: " {}\n" " Item item;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "void App::App() -> void Item::Item(int) <10:5 10:8>"); @@ -1426,7 +1454,7 @@ public: " App app;\n" " App app2(app);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <9:6 9:8>"); @@ -1442,7 +1470,7 @@ public: " App() {}\n" "};\n" "App app;\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "app -> void App::App() <6:5 6:7>"); @@ -1453,7 +1481,7 @@ public: std::shared_ptr client = parseCode( "int one() { return 1; }\n" "int a = one();\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 1); TS_ASSERT_EQUALS(client->calls[0], "a -> int one() <2:9 2:11>"); @@ -1474,7 +1502,7 @@ public: " App app;\n" " app + 2;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "int main() -> void App::App() <10:6 10:8>"); @@ -1490,7 +1518,7 @@ public: "{\n" " bar = 1;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "int main() -> bar <5:2 5:4>"); @@ -1501,7 +1529,7 @@ public: std::shared_ptr client = parseCode( "int a = 0;\n" "int b[] = {a};\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 2); // FIXME: this usage is recorded twice (by InitList and ImplicitCast) TS_ASSERT_EQUALS(client->usages[0], "b -> a <2:12 2:12>"); @@ -1519,7 +1547,7 @@ public: " bar = 1;\n" " }\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "void App::foo() -> bar <7:3 7:5>"); @@ -1537,7 +1565,7 @@ public: " }\n" " int bar;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 2); TS_ASSERT_EQUALS(client->usages[0], "void App::foo() -> App::bar <5:3 5:5>"); @@ -1554,7 +1582,7 @@ public: " {}\n" " int bar;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "void App::App() -> App::bar <4:5 4:7>"); @@ -1567,7 +1595,7 @@ public: "{\n" " return 3.14159265359;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "double PI() -> double <1:1 1:6>"); @@ -1579,7 +1607,7 @@ public: "void ceil(float a)\n" "{\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "void ceil(float) -> void <1:1 1:4>"); @@ -1593,7 +1621,7 @@ public: "{\n" " A(int a);\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "void A::A(int) -> int <3:4 3:6>"); @@ -1606,7 +1634,7 @@ public: "{\n" " int a = 42;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "int main() -> int <1:1 1:3>"); @@ -1624,7 +1652,7 @@ public: " return a;\n" " }\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "int A::main() -> int <3:2 3:4>"); @@ -1645,7 +1673,7 @@ public: " int b = i * 2;\n" " }\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 4); TS_ASSERT_EQUALS(client->typeUses[0], "int main() -> int <1:1 1:3>"); @@ -1667,7 +1695,7 @@ public: "public:\n" " B() : A(42) {}\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "void A::A(int) -> int <4:4 4:6>"); @@ -1684,7 +1712,7 @@ public: "};\n" "A a = B;\n" "A* aPtr = new A;\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "a -> A::B <6:7 6:7>"); @@ -1710,7 +1738,7 @@ public: " A a = B;\n" " A* aPtr = new A;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "int main() -> A::B <8:8 8:8>"); @@ -1729,7 +1757,8 @@ public: "{\n" "double i = PI;" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->macroUses.size(), 1); TS_ASSERT_EQUALS(client->macroUses[0], "PI <4:12 4:13>"); } @@ -1746,7 +1775,7 @@ public: " void foo(T parameter)\n" " {}\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "void B typename T>::foo(B typename T>::T) -> void <7:2 7:5>"); @@ -1766,7 +1795,7 @@ public: " void foo(T parameter)\n" " {}\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 2); TS_ASSERT_EQUALS(client->typeUses[0], "void B typename T>::foo(B typename T>::T) -> void <8:2 8:5>"); @@ -1788,10 +1817,8 @@ public: "public:\n" " typedef typename A::type type;\n" "};\n" - "B::type f = 0;\n" - - ); + ); TS_ASSERT_EQUALS(client->typedefs.size(), 4); TS_ASSERT_EQUALS(client->typedefs[0], "public A::type <5:12 5:15>"); @@ -1819,7 +1846,8 @@ public: " A a;\n" " return 0;\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->int <7:4 7:6>"); } @@ -1834,7 +1862,7 @@ public: "{\n" " A();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<>->int <7:6 7:8>"); @@ -1854,7 +1882,8 @@ public: "{\n" " A(5);\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->int <9:4 9:6>"); } @@ -1872,7 +1901,8 @@ public: "{\n" " A();\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->int <9:4 9:6>"); } @@ -1890,7 +1920,8 @@ public: "{\n" " new A();\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->int <9:8 9:10>"); } @@ -1907,7 +1938,8 @@ public: " A<1> a;\n" " return 0;\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -1923,7 +1955,8 @@ public: " A a;\n" " return 0;\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -1940,7 +1973,8 @@ public: "{\n" " A<&g_p> a;\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p>->g_p <9:5 9:7>"); } @@ -1958,7 +1992,8 @@ public: "{\n" " A a;\n" "}\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p>->g_p <9:4 9:6>"); } @@ -1974,7 +2009,7 @@ public: "{\n" " A<1, 2, 33>();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -1992,7 +2027,7 @@ public: "{\n" " B ba;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "B->A <9:4 9:4>"); @@ -2013,7 +2048,7 @@ public: "{\n" " B();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "B<>->A <11:4 11:4>"); @@ -2033,7 +2068,7 @@ public: "{\n" " A a;\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->templateMemberSpecializations.size(), 1); TS_ASSERT_EQUALS(client->templateMemberSpecializations[0], "int A::foo() -> A::T A::foo() <5:4 5:6>"); @@ -2050,7 +2085,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->int <6:9 6:11>"); } @@ -2066,7 +2102,8 @@ public: "class A<1>\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -2081,7 +2118,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -2098,7 +2136,8 @@ public: "class A<&g_p>\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p>->g_p <8:10 8:12>"); } @@ -2116,7 +2155,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p>->g_p <8:9 8:11>"); } @@ -2134,7 +2174,7 @@ public: "class B\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "B->A <8:9 8:9>"); @@ -2151,7 +2191,8 @@ public: "class A\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->A::T <6:9 6:9>"); TS_ASSERT_EQUALS(client->templateArgumentTypes[1], "A->int <6:12 6:14>"); @@ -2168,7 +2209,7 @@ public: "class A<3, U>\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<3, int U>->A<3, int U>::U <6:12 6:12>"); @@ -2185,7 +2226,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A->A::U <6:15 6:15>"); @@ -2204,7 +2245,7 @@ public: "class A<&g_p, q>\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p, P * q>->g_p <8:10 8:12>"); @@ -2224,7 +2265,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<&g_p, P & q>->g_p <8:9 8:11>"); // why reference here? @@ -2244,7 +2285,7 @@ public: "class B\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "B typename U>->A <8:9 8:9>"); @@ -2262,7 +2303,7 @@ public: "class A<3, T2, T3>\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<3, typename T2, T2 T3>->A<3, typename T2, T2 T3>::T2 <6:12 6:13>"); @@ -2280,7 +2321,7 @@ public: // "class A<3, T2, T3>\n" // "{\n" // "};\n" - // ); + // ); // TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 2); // TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<3, template typename T2, T2 T3>->A<3, template typename T2, T2 T3>::T2 <6:12 6:13>"); @@ -2297,7 +2338,7 @@ public: "};\n" "\n" "A a;\n" - ); + ); TS_ASSERT_EQUALS(client->templateSpecializations.size(), 1); TS_ASSERT_EQUALS(client->templateSpecializations[0], "A -> A <2:7 2:7>"); @@ -2315,7 +2356,7 @@ public: "class B: public A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->inheritances.size(), 1); TS_ASSERT_EQUALS(client->inheritances[0], "B : public A <7:17 7:17>"); @@ -2334,7 +2375,7 @@ public: "class B: public A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A::U>->B::U <8:19 8:19>"); @@ -2349,7 +2390,7 @@ public: " A(): foo() {}\n" " T foo;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->usages.size(), 1); TS_ASSERT_EQUALS(client->usages[0], "void A::A() -> A::foo <4:7 4:9>"); @@ -2363,7 +2404,7 @@ public: "{\n" " T foo();\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->typeUses.size(), 1); TS_ASSERT_EQUALS(client->typeUses[0], "A::T A::foo() -> A::T <4:2 4:2>"); @@ -2376,7 +2417,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "int -> A::T <1:24 1:26>"); @@ -2389,7 +2430,7 @@ public: "class A\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 0); } @@ -2403,7 +2444,7 @@ public: "template class T = A>\n" "class B\n" "{};\n" - ); + ); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "A -> B typename T>::T <4:40 4:40>"); @@ -2422,7 +2463,7 @@ public: "{\n" " return test(1);\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateSpecializations.size(), 1); TS_ASSERT_EQUALS(client->templateSpecializations[0], "int test(int) -> T test(T) <2:3 2:6>"); @@ -2442,7 +2483,7 @@ public: "{\n" " return a + a;\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateSpecializations.size(), 1); TS_ASSERT_EQUALS(client->templateSpecializations[0], "int test(int) -> T test(T) <8:5 8:8>"); @@ -2460,7 +2501,8 @@ public: "void test()\n" "{\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "void test()->int <7:11 7:13>"); } @@ -2476,7 +2518,8 @@ public: " test();\n" " return 1;\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "void test()->int <6:7 6:9>"); } @@ -2492,7 +2535,8 @@ public: " test<33>();\n" " return 1;\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -2508,7 +2552,8 @@ public: " test();\n" " return 1;\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "void test()->A <7:7 7:7>"); } @@ -2524,7 +2569,8 @@ public: " test(1);\n" " return 1;\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -2538,7 +2584,8 @@ public: "{\n" " int foo = test();\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "int test()->int <6:17 6:19>"); } @@ -2553,7 +2600,8 @@ public: "{\n" " int foo = test(1);\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 0); } @@ -2570,7 +2618,8 @@ public: " test();\n" " return 1;\n" "};\n" - ); + ); + TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes[0], "int -> test::T <1:24 1:26>"); } @@ -2582,7 +2631,7 @@ public: "void test()\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 0); } @@ -2597,7 +2646,7 @@ public: "void test()\n" "{\n" "};\n" - ); + ); TS_ASSERT_EQUALS(client->templateDefaultArgumentTypes.size(), 1); TS_ASSERT_EQUALS( @@ -2616,7 +2665,7 @@ public: " func();\n" " }();\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[0], "void lambdaCaller() -> void lambdaCaller::lambda at 4:2() <7:3 7:3>"); @@ -2662,7 +2711,7 @@ public: "{\n" " n::App a = n::App(2);\n" "}\n" - ); + ); TS_ASSERT_EQUALS(client->calls.size(), 2); TS_ASSERT_EQUALS(client->calls[1], "int main() -> void n::App::App(int) <11:16 11:18>"); @@ -2673,7 +2722,8 @@ public: std::shared_ptr client = parseCode( "#define MAX(a,b) \\\n" " ((a)>(b)?(a):(b))" - ); + ); + TS_ASSERT_EQUALS(client->macros.size(), 1); TS_ASSERT_EQUALS(client->macros[0], "MAX <1:9 <1:9 1:11> 2:17>"); } @@ -2685,7 +2735,8 @@ public: // "{\n" // " return static_cast(4.0f);" // "}\n" - // ); + // ); + // TS_ASSERT_EQUALS(client->templateArgumentTypes.size(), 1); // TS_ASSERT_EQUALS(client->templateArgumentTypes[0], "A<1>->int <0:0 0:0>"); //} @@ -2760,7 +2811,7 @@ public: { std::shared_ptr client = parseCode( "// this is a line comment\n" - ); + ); TS_ASSERT_EQUALS(client->comments.size(), 1); TS_ASSERT_EQUALS(client->comments[0], "comment <1:1 1:26>"); @@ -2771,7 +2822,7 @@ public: std::shared_ptr client = parseCode( "/* this is a\n" "block comment */\n" - ); + ); TS_ASSERT_EQUALS(client->comments.size(), 1); TS_ASSERT_EQUALS(client->comments[0], "comment <1:1 2:17>"); @@ -2994,6 +3045,13 @@ private: return 0; } + virtual Id onLocalSymbolParsed(const std::string& name, const ParseLocation& location) + { + localSymbols.push_back(name); + return 0; + } + + virtual Id onFileParsed(const FileInfo& fileInfo) { files.push_back(fileInfo.path.str()); @@ -3052,6 +3110,7 @@ private: std::vector templateDefaultArgumentTypes; std::vector templateSpecializations; std::vector templateMemberSpecializations; + std::vector localSymbols; std::vector files; std::vector includes;