diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index 5b1849c9..92d24ed2 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -119,6 +119,16 @@ Id SqliteStorage::addNameHierarchyElement(const std::string& name, Id parentId) return m_database.lastRowId(); } +Id SqliteStorage::addComponentAccess(Id memberEdgeId, int type) +{ + m_database.execDML(( + "INSERT INTO component_access(id, edge_id, type) " + "VALUES (NULL, '" + std::to_string(memberEdgeId) + "', " + std::to_string(type) + ");" + ).c_str()); + + return m_database.lastRowId(); +} + void SqliteStorage::removeElement(Id id) { m_database.execDML(( @@ -585,6 +595,24 @@ Id SqliteStorage::getElementIdByLocationId(Id locationId) const ); } +StorageComponentAccess SqliteStorage::getComponentAccessByMemberEdgeId(Id memberEdgeId) const +{ + CppSQLite3Query q = m_database.execQuery(( + "SELECT id, edge_id, type FROM component_access WHERE edge_id == " + std::to_string(memberEdgeId) + ";" + ).c_str()); + + while (!q.eof()) + { + return StorageComponentAccess( + q.getIntField(0, 0), + q.getIntField(1, 0), + q.getIntField(2, 0) + ); + } + + return StorageComponentAccess(0, 0, 0); +} + int SqliteStorage::getNodeCount() const { return m_database.execScalar("SELECT COUNT(*) from node;"); @@ -654,7 +682,7 @@ void SqliteStorage::setupTables() "id INTEGER NOT NULL, " "name TEXT, " "parent_id INTEGER, " - "PRIMARY KEY(id)" + "PRIMARY KEY(id), " "FOREIGN KEY(parent_id) REFERENCES name_hierarchy_element(id) ON DELETE CASCADE);" // maybe use restrict here ); @@ -668,10 +696,19 @@ void SqliteStorage::setupTables() "end_line INTEGER, " "end_column INTEGER, " "is_scope INTEGER, " - "PRIMARY KEY(id)" + "PRIMARY KEY(id), " "FOREIGN KEY(element_id) REFERENCES element(id) ON DELETE CASCADE, " "FOREIGN KEY(file_node_id) REFERENCES node(id) ON DELETE CASCADE);" ); + + m_database.execDML( + "CREATE TABLE IF NOT EXISTS component_access(" + "id INTEGER NOT NULL, " + "edge_id INTEGER, " + "type INTEGER NOT NULL, " + "PRIMARY KEY(id), " + "FOREIGN KEY(edge_id) REFERENCES element(id) ON DELETE CASCADE);" + ); } StorageFile SqliteStorage::getFirstFile(const std::string& query) const diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index ae370202..e06de557 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -33,6 +33,7 @@ public: int addSourceLocation(Id elementId, Id fileNodeId, uint startLine, uint startCol, uint endLine, uint endCol, bool isScope); Id addNameHierarchyElement(const std::string& name); Id addNameHierarchyElement(const std::string& name, Id parentId); + Id addComponentAccess(Id memberEdgeId, int type); void removeElement(Id id); void removeNameHierarchyElement(Id id); @@ -79,6 +80,8 @@ public: Id getElementIdByLocationId(Id locationId) const; + StorageComponentAccess getComponentAccessByMemberEdgeId(Id memberEdgeId) const; + int getNodeCount() const; int getEdgeCount() const; int getNameHierarchyElementCount() const; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 598cfe38..f80d336e 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -177,9 +177,9 @@ Id Storage::onTypedefParsed( ){ Id typedefNodeId = addNodeHierarchy(Node::NODE_TYPEDEF, nameHierarchy); addSourceLocation(typedefNodeId, location); + addAccess(typedefNodeId, access); Id underlyingTypeNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, underlyingType.dataType->getTypeNameHierarchy()); - addEdge(typedefNodeId, underlyingTypeNodeId, Edge::EDGE_TYPEDEF_OF, location); return typedefNodeId; @@ -194,6 +194,8 @@ Id Storage::onClassParsed( addSourceLocation(nodeId, location); addSourceLocation(nodeId, scopeLocation, true); + addAccess(nodeId, access); + return nodeId; } @@ -206,6 +208,8 @@ Id Storage::onStructParsed( addSourceLocation(nodeId, location); addSourceLocation(nodeId, scopeLocation, true); + addAccess(nodeId, access); + return nodeId; } @@ -215,10 +219,8 @@ Id Storage::onGlobalVariableParsed(const ParseLocation& location, const ParseVar addSourceLocation(nodeId, location); Id typeNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, variable.type.dataType->getTypeNameHierarchy()); - addEdge(nodeId, typeNodeId, Edge::EDGE_TYPE_OF, location); - return nodeId; } @@ -226,6 +228,7 @@ Id Storage::onFieldParsed(const ParseLocation& location, const ParseVariable& va { Id nodeId = addNodeHierarchy(Node::NODE_FIELD, variable.nameHierarchy); addSourceLocation(nodeId, location); + addAccess(nodeId, access); Id typeNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, variable.type.dataType->getTypeNameHierarchy()); addEdge(nodeId, typeNodeId, Edge::EDGE_TYPE_OF, variable.type.location); @@ -258,6 +261,9 @@ Id Storage::onMethodParsed( const ParseLocation& scopeLocation ){ Id nodeId = addNodeHierarchyWithDistinctSignature(Node::NODE_METHOD, method); + addSourceLocation(nodeId, location); + addSourceLocation(nodeId, scopeLocation, true); + addAccess(nodeId, access); Id returnTypeNodeId = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, method.returnType.dataType->getTypeNameHierarchy()); addEdge(nodeId, returnTypeNodeId, Edge::EDGE_RETURN_TYPE_OF, method.returnType.location); @@ -268,9 +274,6 @@ Id Storage::onMethodParsed( addEdge(nodeId, parameternTypeNodeId, Edge::EDGE_PARAMETER_TYPE_OF, method.parameters[i].location); } - addSourceLocation(nodeId, location); - addSourceLocation(nodeId, scopeLocation, true); - return nodeId; } @@ -293,6 +296,7 @@ Id Storage::onEnumParsed( addSourceLocation(nodeId, location); addSourceLocation(nodeId, scopeLocation, true); + addAccess(nodeId, access); return nodeId; } @@ -722,6 +726,22 @@ std::shared_ptr Storage::getGraphForActiveTokenIds(const std::vector& } } + graph->forEachEdge( + [this](Edge* edge) + { + if (!edge->isType(Edge::EDGE_MEMBER)) + { + return; + } + + StorageComponentAccess access = m_sqliteStorage.getComponentAccessByMemberEdgeId(edge->getId()); + if (access.id && access.type) + { + edge->addComponentAccess(std::make_shared(TokenComponentAccess::intToType(access.type))); + } + } + ); + return g; } @@ -1357,3 +1377,35 @@ Node* Storage::addNodeToGraph(const Id nodeId, Graph* graph) const std::make_shared(m_sqliteStorage.getNameHierarchyById(storageNode.nameId)) ); } + +TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const +{ + switch (access) + { + case ACCESS_PUBLIC: + return TokenComponentAccess::ACCESS_PUBLIC; + case ACCESS_PROTECTED: + return TokenComponentAccess::ACCESS_PROTECTED; + case ACCESS_PRIVATE: + return TokenComponentAccess::ACCESS_PRIVATE; + case ACCESS_NONE: + return TokenComponentAccess::ACCESS_NONE; + } +} + +void Storage::addAccess(const Id nodeId, ParserClient::AccessType access) +{ + if (access == ACCESS_NONE) + { + return; + } + + std::vector memberEdges = m_sqliteStorage.getEdgesByTargetType(nodeId, Edge::EDGE_MEMBER); + if (memberEdges.size() != 1) + { + LOG_ERROR_STREAM(<< "Cannot assign access" << access << " to node id " << nodeId << " because it's no child."); + return; + } + + m_sqliteStorage.addComponentAccess(memberEdges[0].id, convertAccessType(access)); +} diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 1ada2f90..18f18f4e 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -8,7 +8,7 @@ #include "data/access/StorageAccess.h" //#include "data/graph/token_component/TokenComponentAbstraction.h" -//#include "data/graph/token_component/TokenComponentAccess.h" +#include "data/graph/token_component/TokenComponentAccess.h" #include "data/location/TokenLocationCollection.h" #include "data/parser/ParserClient.h" #include "data/search/SearchIndex.h" @@ -161,6 +161,9 @@ private: void addAggregationEdgesToGraph(const Id nodeId, Graph* graph) const; Node* addNodeToGraph(const Id nodeId, Graph* graph) const; + TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const; + void addAccess(const Id nodeId, ParserClient::AccessType access); + SearchIndex m_tokenIndex; SqliteStorage m_sqliteStorage; diff --git a/src/lib/data/StorageTypes.h b/src/lib/data/StorageTypes.h index 5cef9e57..af9fede0 100644 --- a/src/lib/data/StorageTypes.h +++ b/src/lib/data/StorageTypes.h @@ -68,4 +68,17 @@ struct StorageSourceLocation bool isScope; }; +struct StorageComponentAccess +{ + StorageComponentAccess(Id id, Id memberEdgeId, int type) + : id(id) + , memberEdgeId(memberEdgeId) + , type(type) + {} + + Id id; + Id memberEdgeId; + int type; +}; + #endif // STORAGE_TYPES_H diff --git a/src/lib/data/graph/token_component/TokenComponentAccess.cpp b/src/lib/data/graph/token_component/TokenComponentAccess.cpp index 2d9e4db4..cb1755ba 100644 --- a/src/lib/data/graph/token_component/TokenComponentAccess.cpp +++ b/src/lib/data/graph/token_component/TokenComponentAccess.cpp @@ -16,6 +16,27 @@ std::string TokenComponentAccess::getAccessString(AccessType access) return ""; } +int TokenComponentAccess::typeToInt(AccessType type) +{ + return type; +} + +TokenComponentAccess::AccessType TokenComponentAccess::intToType(int value) +{ + switch (value) + { + case 0x1: + return ACCESS_PUBLIC; + case 0x2: + return ACCESS_PROTECTED; + case 0x4: + return ACCESS_PRIVATE; + default: + break; + } + return ACCESS_NONE; +} + TokenComponentAccess::TokenComponentAccess(AccessType access) : m_access(access) { diff --git a/src/lib/data/graph/token_component/TokenComponentAccess.h b/src/lib/data/graph/token_component/TokenComponentAccess.h index f4a8c8ec..2e661513 100644 --- a/src/lib/data/graph/token_component/TokenComponentAccess.h +++ b/src/lib/data/graph/token_component/TokenComponentAccess.h @@ -9,16 +9,19 @@ class TokenComponentAccess : public TokenComponent { public: - enum AccessType + enum AccessType : int { - ACCESS_PUBLIC, - ACCESS_PROTECTED, - ACCESS_PRIVATE, - ACCESS_NONE + ACCESS_PUBLIC = 0x1, + ACCESS_PROTECTED = 0x2, + ACCESS_PRIVATE = 0x4, + ACCESS_NONE = 0x0 }; static std::string getAccessString(AccessType access); + static int typeToInt(AccessType type); + static AccessType intToType(int value); + TokenComponentAccess(AccessType access); virtual ~TokenComponentAccess();