diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 5a545f3f..6ccea078 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -150,6 +150,11 @@ void Storage::logLocations() const LOG_INFO_STREAM(<< '\n' << m_locationCollection); } +void Storage::logIndex() const +{ + LOG_INFO_STREAM(<< '\n' << m_tokenIndex); +} + void Storage::onError(const ParseLocation& location, const std::string& message) { log("ERROR", message, location); @@ -352,10 +357,7 @@ Id Storage::onNamespaceParsed( log("namespace", nameHierarchy.getFullName(), location); Node* node = addNodeHierarchy(Node::NODE_NAMESPACE, nameHierarchy); - if (location.isValid()) - { - addTokenLocation(node, location); - } + addTokenLocation(node, location); addTokenLocation(node, scopeLocation, true); return node->getId(); @@ -402,15 +404,18 @@ Id Storage::onInheritanceParsed( return edge->getId(); } -Id Storage::onMethodOverrideParsed(const ParseFunction& base, const ParseFunction& overrider) +Id Storage::onMethodOverrideParsed( + const ParseLocation& location, const ParseFunction& base, const ParseFunction& overrider) { - log("override", base.getFullName() + " -> " + overrider.getFullName(), ParseLocation()); + log("override", base.getFullName() + " -> " + overrider.getFullName(), location); Node* baseNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, base); Node* overriderNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, overrider); Edge* edge = m_graph.createEdge(Edge::EDGE_OVERRIDE, baseNode, overriderNode); + addTokenLocation(edge, location); + return edge->getId(); } @@ -566,11 +571,12 @@ Id Storage::onTemplateDefaultArgumentTypeParsed( Node* templateDefaultArgumentNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, defaultArgumentType.dataType->getTypeNameHierarchy()); - addTokenLocation(templateDefaultArgumentNode, defaultArgumentType.location); - Node* templateArgumentNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateArgumentTypeNameHierarchy); + Edge* templateArgumentEdge = + m_graph.createEdge(Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT_OF, templateDefaultArgumentNode, templateArgumentNode); - m_graph.createEdge(Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT_OF, templateDefaultArgumentNode, templateArgumentNode); + addTokenLocation(templateDefaultArgumentNode, defaultArgumentType.location); + addTokenLocation(templateArgumentEdge, defaultArgumentType.location); return templateDefaultArgumentNode->getId(); } @@ -582,10 +588,12 @@ Id Storage::onTemplateRecordParameterTypeParsed( log("template record type parameter", templateParameterTypeNameHierarchy.getFullName(), location); Node* templateParameterNode = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy); - addTokenLocation(templateParameterNode, location); - Node* templateRecordNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, templateRecordNameHierarchy); - m_graph.createEdge(Edge::EDGE_TEMPLATE_PARAMETER_OF, templateParameterNode, templateRecordNode); + Edge* templateParameterEdge = + m_graph.createEdge(Edge::EDGE_TEMPLATE_PARAMETER_OF, templateParameterNode, templateRecordNode); + + addTokenLocation(templateParameterNode, location); + addTokenLocation(templateParameterEdge, location); return templateParameterNode->getId(); } @@ -608,9 +616,11 @@ Id Storage::onTemplateRecordSpecializationParsed( Node* specializedRecordNode = addNodeHierarchy(specializedRecordNodeType, specializedRecordNameHierarchy); Node* templateRecordNode = addNodeHierarchy(Node::NODE_UNDEFINED_TYPE, specializedFromNameHierarchy); + Edge* templateSpecializationEdge = + m_graph.createEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedRecordNode, templateRecordNode); - m_graph.createEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedRecordNode, templateRecordNode); - //addTokenLocation(edge, location); + addTokenLocation(specializedRecordNode, location); + addTokenLocation(templateSpecializationEdge, location); return specializedRecordNode->getId(); } @@ -621,25 +631,29 @@ Id Storage::onTemplateFunctionParameterTypeParsed( log("template function type parameter", templateParameterTypeNameHierarchy.getFullName(), location); Node* templateParameterNode = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy); - addTokenLocation(templateParameterNode, location); - Node* templateFunctionNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, function); + Edge* templateParameterEdge = + m_graph.createEdge(Edge::EDGE_TEMPLATE_PARAMETER_OF, templateParameterNode, templateFunctionNode); - m_graph.createEdge(Edge::EDGE_TEMPLATE_PARAMETER_OF, templateParameterNode, templateFunctionNode); + addTokenLocation(templateParameterNode, location); + addTokenLocation(templateParameterEdge, location); return templateParameterNode->getId(); } Id Storage::onTemplateFunctionSpecializationParsed( const ParseLocation& location, const ParseFunction specializedFunction, const ParseFunction templateFunction -) -{ +){ log("function template specialization", specializedFunction.getFullName(), location); Node* specializedFunctionNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, specializedFunction); Node* templateFunctionNode = addNodeHierarchyWithDistinctSignature(Node::NODE_UNDEFINED_FUNCTION, templateFunction); - m_graph.createEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedFunctionNode, templateFunctionNode); + Edge* templateSpecializationEdge = + m_graph.createEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION_OF, specializedFunctionNode, templateFunctionNode); + + addTokenLocation(specializedFunctionNode, location); + addTokenLocation(templateSpecializationEdge, location); return specializedFunctionNode->getId(); } @@ -1375,13 +1389,25 @@ void Storage::removeNodeIfUnreferenced(Node* node) Id tokenId = node->getId(); SearchNode* searchNode = m_tokenIndex.getNode(node->getTokenComponentName()->getSearchNode()); + Node* parentNode = node->getParentNode(); + bool removed = m_graph.removeNodeIfUnreferencedRecursive(node); - if (removed && searchNode) + if (!removed) + { + return; + } + + if (searchNode) { searchNode->removeTokenId(tokenId); m_tokenIndex.removeNodeIfUnreferencedRecursive(searchNode); } + + if (parentNode) + { + removeNodeIfUnreferenced(parentNode); + } } void Storage::log(std::string type, std::string str, const ParseLocation& location) const diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 2f79fb13..c59ddecf 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -28,6 +28,7 @@ public: void logGraph() const; void logLocations() const; + void logIndex() const; // ParserClient implementation virtual void onError(const ParseLocation& location, const std::string& message); @@ -63,7 +64,8 @@ public: virtual Id onInheritanceParsed( const ParseLocation& location, const NameHierarchy& nameHierarchy, const NameHierarchy& baseNameHierarchy, AccessType access); - virtual Id onMethodOverrideParsed(const ParseFunction& base, const ParseFunction& overrider); + virtual Id onMethodOverrideParsed( + const ParseLocation& location, const ParseFunction& base, const ParseFunction& overrider); virtual Id onCallParsed( const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee); virtual Id onCallParsed( diff --git a/src/lib/data/graph/StorageGraph.cpp b/src/lib/data/graph/StorageGraph.cpp index 48dfe975..6d01fe71 100644 --- a/src/lib/data/graph/StorageGraph.cpp +++ b/src/lib/data/graph/StorageGraph.cpp @@ -93,13 +93,28 @@ Edge* StorageGraph::createEdge(Edge::EdgeType type, Node* from, Node* to) if (from->getLastParentNode() != to->getLastParentNode()) { Id edgeId = edge->getId(); - updateAggregationEdges(from->getParentNode(), to, edgeId); - updateAggregationEdges(from, to->getParentNode(), edgeId); + updateAggregationEdges(from->getParentNode(), to, edgeId, 0); + updateAggregationEdges(from, to->getParentNode(), edgeId, 0); } return edge; } +void StorageGraph::removeEdge(Edge* edge) +{ + Node* from = edge->getFrom(); + Node* to = edge->getTo(); + + if (from->getLastParentNode() != to->getLastParentNode()) + { + Id edgeId = edge->getId(); + updateAggregationEdges(from->getParentNode(), to, 0, edgeId); + updateAggregationEdges(from, to->getParentNode(), 0, edgeId); + } + + Graph::removeEdge(edge); +} + Node* StorageGraph::insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode) { std::deque searchNodes = searchNode->getParentsWithoutTokenId(); @@ -151,7 +166,7 @@ Edge* StorageGraph::insertEdge(Edge::EdgeType type, Node* from, Node* to) return edgePtr.get(); } -void StorageGraph::updateAggregationEdges(Node* from, Node* to, Id edgeId) +void StorageGraph::updateAggregationEdges(Node* from, Node* to, Id addEdgeId, Id removeEdgeId) { if (!from || !to || from == to) { @@ -174,15 +189,28 @@ void StorageGraph::updateAggregationEdges(Node* from, Node* to, Id edgeId) } ); - if (!edge) + if (!edge && addEdgeId) { edge = insertEdge(Edge::EDGE_AGGREGATION, from, to); edge->addComponentAggregation(std::make_shared()); } - edge->getComponent()->addAggregationId(edgeId); + if (addEdgeId) + { + edge->getComponent()->addAggregationId(addEdgeId); + } + + if (edge && removeEdgeId) + { + edge->getComponent()->removeAggregationId(removeEdgeId); + } + + if (edge && edge->getComponent()->getAggregationCount() == 0) + { + Graph::removeEdge(edge); + } } - updateAggregationEdges(from->getParentNode(), to, edgeId); - updateAggregationEdges(from, to->getParentNode(), edgeId); + updateAggregationEdges(from->getParentNode(), to, addEdgeId, removeEdgeId); + updateAggregationEdges(from, to->getParentNode(), addEdgeId, removeEdgeId); } diff --git a/src/lib/data/graph/StorageGraph.h b/src/lib/data/graph/StorageGraph.h index 66dc1744..1ffb1270 100644 --- a/src/lib/data/graph/StorageGraph.h +++ b/src/lib/data/graph/StorageGraph.h @@ -16,13 +16,14 @@ public: Node* createNodeHierarchyWithDistinctSignature( Node::NodeType type, SearchNode* searchNode, std::shared_ptr signature); Edge* createEdge(Edge::EdgeType type, Node* from, Node* to); + void removeEdge(Edge* edge); private: Node* insertNodeHierarchy(Node::NodeType type, SearchNode* searchNode); Node* insertNode(Node::NodeType type, Node* parentNode, SearchNode* searchNode); Edge* insertEdge(Edge::EdgeType type, Node* from, Node* to); - void updateAggregationEdges(Node* from, Node* to, Id edgeId); + void updateAggregationEdges(Node* from, Node* to, Id addEdgeId, Id removeEdgeId); }; #endif // STORAGE_GRAPH_H diff --git a/src/lib/data/parser/ParseLocation.cpp b/src/lib/data/parser/ParseLocation.cpp index cd1034d3..453a6652 100644 --- a/src/lib/data/parser/ParseLocation.cpp +++ b/src/lib/data/parser/ParseLocation.cpp @@ -37,12 +37,5 @@ ParseLocation::ParseLocation( bool ParseLocation::isValid() const { - if (startLineNumber == endLineNumber) - { - return startLineNumber > 0 && startColumnNumber <= endColumnNumber; - } - else - { - return startLineNumber > 0 && startLineNumber < endLineNumber; - } + return filePath.size() > 0; } diff --git a/src/lib/data/parser/ParserClient.h b/src/lib/data/parser/ParserClient.h index dbbfc550..8674ccb8 100644 --- a/src/lib/data/parser/ParserClient.h +++ b/src/lib/data/parser/ParserClient.h @@ -84,7 +84,8 @@ public: virtual Id onInheritanceParsed( const ParseLocation& location, const NameHierarchy& nameHierarchy, const NameHierarchy& baseNameHierarchy, AccessType access) = 0; - virtual Id onMethodOverrideParsed(const ParseFunction& base, const ParseFunction& overrider) = 0; + virtual Id onMethodOverrideParsed( + const ParseLocation& location, const ParseFunction& base, const ParseFunction& overrider) = 0; virtual Id onCallParsed( const ParseLocation& location, const ParseFunction& caller, const ParseFunction& callee) = 0; virtual Id onCallParsed( diff --git a/src/lib/data/parser/cxx/ASTVisitor.cpp b/src/lib/data/parser/cxx/ASTVisitor.cpp index 5be556b5..59cf03b1 100644 --- a/src/lib/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib/data/parser/cxx/ASTVisitor.cpp @@ -186,9 +186,10 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration) } ParseFunction parseFunction = getParseFunction(declaration); + ParseLocation location = getParseLocationForNamedDecl(declaration); m_client->onMethodParsed( - getParseLocationForNamedDecl(declaration), + location, parseFunction, convertAccessType(declaration->getAccess()), abstraction, @@ -198,7 +199,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration) for (clang::CXXMethodDecl::method_iterator it = declaration->begin_overridden_methods(); it != declaration->end_overridden_methods(); it++) { - m_client->onMethodOverrideParsed(getParseFunction(*it), parseFunction); + m_client->onMethodOverrideParsed(location, getParseFunction(*it), parseFunction); } if (declaration->hasBody() && declaration->getBody() != NULL && declaration->isThisDeclarationADefinition()) diff --git a/src/lib/data/search/SearchIndex.cpp b/src/lib/data/search/SearchIndex.cpp index 3ba0f418..84cf0fb4 100644 --- a/src/lib/data/search/SearchIndex.cpp +++ b/src/lib/data/search/SearchIndex.cpp @@ -134,3 +134,10 @@ std::vector SearchIndex::runFuzzySearchAndGetMatches(const std::str } const std::string SearchIndex::DELIMITER = "::"; + +std::ostream& operator<<(std::ostream& ostream, const SearchIndex& index) +{ + ostream << "SearchIndex:\n"; + ostream << &index.m_root; + return ostream; +} diff --git a/src/lib/data/search/SearchIndex.h b/src/lib/data/search/SearchIndex.h index c099e68f..5f83ee5b 100644 --- a/src/lib/data/search/SearchIndex.h +++ b/src/lib/data/search/SearchIndex.h @@ -41,6 +41,10 @@ public: private: SearchNode m_root; Dictionary m_dictionary; + + friend std::ostream& operator<<(std::ostream& ostream, const SearchIndex& index); }; +std::ostream& operator<<(std::ostream& ostream, const SearchIndex& index); + #endif // SEARCH_INDEX_H diff --git a/src/lib/data/search/SearchNode.cpp b/src/lib/data/search/SearchNode.cpp index 71fd7ca9..9ed301cc 100644 --- a/src/lib/data/search/SearchNode.cpp +++ b/src/lib/data/search/SearchNode.cpp @@ -407,3 +407,22 @@ std::deque SearchNode::getNodesToParent(const SearchNode* par return nodes; } + +std::ostream& operator<<(std::ostream& ostream, const SearchNode* node) +{ + ostream << node->m_name; + + for (Id tokenId : node->m_tokenIds) + { + ostream << ' ' << tokenId; + } + + ostream << '\n'; + + for (const std::shared_ptr n : node->m_nodes) + { + ostream << n.get(); + } + + return ostream; +} diff --git a/src/lib/data/search/SearchNode.h b/src/lib/data/search/SearchNode.h index 05734cc8..fe0af701 100644 --- a/src/lib/data/search/SearchNode.h +++ b/src/lib/data/search/SearchNode.h @@ -77,6 +77,10 @@ private: const std::string& m_name; const Id m_nameId; + + friend std::ostream& operator<<(std::ostream& ostream, const SearchNode* node); }; +std::ostream& operator<<(std::ostream& ostream, const SearchNode* node); + #endif // SEARCH_NODE_H diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 584c052c..10b24096 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -614,7 +614,7 @@ public: ); TS_ASSERT_EQUALS(client->overrides.size(), 1); - TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo()"); + TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo() <5:7 5:9>"); } void test_cxx_parser_finds_no_method_override_when_not_virtual() @@ -646,8 +646,8 @@ public: ); TS_ASSERT_EQUALS(client->overrides.size(), 2); - TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo()"); - TS_ASSERT_EQUALS(client->overrides[1], "void B::foo() -> void C::foo()"); + TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> void B::foo() <5:7 5:9>"); + TS_ASSERT_EQUALS(client->overrides[1], "void B::foo() -> void C::foo() <8:7 8:9>"); } void test_cxx_parser_finds_no_method_overrides_on_different_signatures() @@ -677,7 +677,7 @@ public: ); TS_ASSERT_EQUALS(client->overrides.size(), 1); - TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> int B::foo()"); + TS_ASSERT_EQUALS(client->overrides[0], "void A::foo() -> int B::foo() <5:6 5:8>"); TS_ASSERT_EQUALS(client->errors.size(), 1); } @@ -2565,9 +2565,9 @@ private: return 0; } - virtual Id onMethodOverrideParsed(const ParseFunction& base, const ParseFunction& overrider) + virtual Id onMethodOverrideParsed(const ParseLocation& location, const ParseFunction& base, const ParseFunction& overrider) { - overrides.push_back(functionStr(base) + " -> " + functionStr(overrider)); + overrides.push_back(addLocationSuffix(functionStr(base) + " -> " + functionStr(overrider), location)); return 0; } diff --git a/src/test/StorageTestSuite.h b/src/test/StorageTestSuite.h index 1535b648..467f90fc 100644 --- a/src/test/StorageTestSuite.h +++ b/src/test/StorageTestSuite.h @@ -420,7 +420,7 @@ public: storage.onMethodParsed(validLocation(9), a, ParserClient::ACCESS_PRIVATE, ParserClient::ABSTRACTION_VIRTUAL, validLocation(4)); storage.onMethodParsed(validLocation(7), b, ParserClient::ACCESS_PRIVATE, ParserClient::ABSTRACTION_NONE, validLocation(3)); - Id id = storage.onMethodOverrideParsed(a, b); + Id id = storage.onMethodOverrideParsed(validLocation(4), a, b); Edge* edge = storage.getEdgeWithId(id); TS_ASSERT(edge);