diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index e656f241..cf9ad5ea 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -376,6 +376,8 @@ void GraphController::setActiveAndVisibility(const std::vector& activeTokenI for (DummyNode& node : m_dummyNodes) { + removeImplicitAndUndefinedChildrenRecursive(node); + setNodeVisibilityRecursiveBottomUp(node, noActive); } } @@ -395,6 +397,35 @@ void GraphController::setNodeActiveRecursive(DummyNode& node, const std::vector< } } +void GraphController::removeImplicitAndUndefinedChildrenRecursive(DummyNode& node) +{ + for (size_t i = 0; i < node.subNodes.size(); i++) + { + bool removeNode = false; + + DummyNode& subNode = node.subNodes[i]; + if (subNode.isGraphNode() && !subNode.data->isExplicit() && !subNode.connected && !subNode.active && !subNode.subNodes.size()) + { + removeNode = true; + } + else + { + removeImplicitAndUndefinedChildrenRecursive(subNode); + + if (subNode.isAccessNode() && subNode.subNodes.size() == 0) + { + removeNode = true; + } + } + + if (removeNode) + { + node.subNodes.erase(node.subNodes.begin() + i); + i--; + } + } +} + bool GraphController::setNodeVisibilityRecursiveBottomUp(DummyNode& node, bool noActive) const { node.visible = false; diff --git a/src/lib/component/controller/GraphController.h b/src/lib/component/controller/GraphController.h index c779e2c7..7ab3d770 100644 --- a/src/lib/component/controller/GraphController.h +++ b/src/lib/component/controller/GraphController.h @@ -63,6 +63,7 @@ private: void setActiveAndVisibility(const std::vector& activeTokenIds); void setNodeActiveRecursive(DummyNode& node, const std::vector& activeTokenIds) const; + void removeImplicitAndUndefinedChildrenRecursive(DummyNode& node); bool setNodeVisibilityRecursiveBottomUp(DummyNode& node, bool noActive) const; void setNodeVisibilityRecursiveTopDown(DummyNode& node, bool parentExpanded) const; void deactivateNodesRecursive(std::vector* nodes) const; diff --git a/src/lib/component/view/GraphViewStyle.cpp b/src/lib/component/view/GraphViewStyle.cpp index c6f291e5..42140f35 100644 --- a/src/lib/component/view/GraphViewStyle.cpp +++ b/src/lib/component/view/GraphViewStyle.cpp @@ -261,7 +261,7 @@ GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfAccessNode(TokenComponen margins.minWidth = 58; break; case TokenComponentAccess::ACCESS_TEMPLATE: - margins.minWidth = 103; + margins.minWidth = 133; break; } diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index deb13a10..3ad91384 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -458,7 +458,11 @@ std::vector Storage::getNodeIdsForLocationIds(const std::vector& locatio } else { - nodeIds.insert(elementId); + StorageNode node = m_sqliteStorage.getNodeById(elementId); + if (node.id != 0 && intToDefinitionType(node.definitionType) == DEFINITION_EXPLICIT) + { + nodeIds.insert(elementId); + } } } @@ -757,13 +761,23 @@ void Storage::addNodesToGraph(const std::vector& nodeIds, Graph* graph) cons NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName); Node::NodeType type = Node::intToType(storageNode.type); + DefinitionType defType = intToDefinitionType(storageNode.definitionType); Node* node = graph->createNode( storageNode.id, type, nameHierarchy, - intToDefinitionType(storageNode.definitionType) != DEFINITION_NONE + defType != DEFINITION_NONE ); + if (defType == DEFINITION_IMPLICIT) + { + node->setImplicit(true); + } + else if (defType == DEFINITION_EXPLICIT) + { + node->setExplicit(true); + } + if (type == Node::NODE_FUNCTION || type == Node::NODE_METHOD) { std::string signatureString = nameHierarchy.getRawNameWithSignature(); diff --git a/src/lib/data/graph/Node.cpp b/src/lib/data/graph/Node.cpp index b280614d..cb8ccf23 100644 --- a/src/lib/data/graph/Node.cpp +++ b/src/lib/data/graph/Node.cpp @@ -98,6 +98,8 @@ Node::Node(Id id, NodeType type, NameHierarchy nameHierarchy, bool defined) , m_type(type) , m_nameHierarchy(nameHierarchy) , m_defined(defined) + , m_implicit(false) + , m_explicit(false) { } @@ -152,6 +154,26 @@ void Node::setDefined(bool defined) m_defined = defined; } +bool Node::isImplicit() const +{ + return m_implicit; +} + +void Node::setImplicit(bool implicit) +{ + m_implicit = implicit; +} + +bool Node::isExplicit() const +{ + return m_explicit; +} + +void Node::setExplicit(bool bExplicit) +{ + m_explicit = bExplicit; +} + const std::vector& Node::getEdges() const { return m_edges; diff --git a/src/lib/data/graph/Node.h b/src/lib/data/graph/Node.h index f953ed69..8ca75c48 100644 --- a/src/lib/data/graph/Node.h +++ b/src/lib/data/graph/Node.h @@ -63,6 +63,12 @@ public: bool isDefined() const; void setDefined(bool defined); + bool isImplicit() const; + void setImplicit(bool implicit); + + bool isExplicit() const; + void setExplicit(bool bExplicit); + const std::vector& getEdges() const; void addEdge(Edge* edge); @@ -107,6 +113,8 @@ private: NodeType m_type; NameHierarchy m_nameHierarchy; bool m_defined; + bool m_implicit; + bool m_explicit; }; std::ostream& operator<<(std::ostream& ostream, const Node& node); diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp index 02b326ce..468eaa01 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp @@ -176,7 +176,9 @@ void QtGraphEdge::onClick() { if (!getData()) { - MessageGraphNodeBundleSplit(m_target.lock()->getTokenId()).dispatch(); + std::weak_ptr node = + (m_direction == TokenComponentAggregation::DIRECTION_BACKWARD ? m_owner : m_target); + MessageGraphNodeBundleSplit(node.lock()->getTokenId()).dispatch(); } else { diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp index 4056f696..e327c817 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp @@ -21,6 +21,10 @@ QtGraphNodeData::QtGraphNodeData(const Node* data, const std::string& name, bool { toolTip = "undefined " + toolTip; } + else if (data->isImplicit()) + { + toolTip = "implicit " + toolTip; + } if (data->isType(Node::NODE_FUNCTION | Node::NODE_METHOD)) { @@ -75,8 +79,8 @@ void QtGraphNodeData::moved(const Vec2i& oldPosition) void QtGraphNodeData::updateStyle() { - GraphViewStyle::NodeStyle style = - GraphViewStyle::getStyleForNodeType(m_data->getType(), m_data->isDefined(), m_isActive, m_isHovering, m_childVisible); + GraphViewStyle::NodeStyle style = GraphViewStyle::getStyleForNodeType( + m_data->getType(), m_data->isExplicit(), m_isActive, m_isHovering, m_childVisible); setStyle(style); } diff --git a/src/lib_parser/data/parser/cxx/ASTVisitor.h b/src/lib_parser/data/parser/cxx/ASTVisitor.h index 306486de..e2a45ba6 100644 --- a/src/lib_parser/data/parser/cxx/ASTVisitor.h +++ b/src/lib_parser/data/parser/cxx/ASTVisitor.h @@ -151,7 +151,7 @@ private: // Misc routines bool shouldVisitTemplateInstantiations() const { return true; } bool shouldUseDataRecursionFor(clang::Stmt *s) const; - //bool shouldVisitImplicitCode() const { return true; } // TODO: uncomment this when implicit nodes are hidden in the ui + bool shouldVisitImplicitCode() const { return true; } // Dispatcher routines bool TraverseStmt(clang::Stmt *stmt); diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index ca650680..e90c954b 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -147,9 +147,11 @@ public: "}\n" ); - TS_ASSERT_EQUALS(client->methods.size(), 2); + TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "public void B::B() <4:2 4:2>"); - TS_ASSERT_EQUALS(client->methods[1], "public void B::B() <6:1 <6:4 6:4> 8:1>"); + TS_ASSERT_EQUALS(client->methods[1], "public void B::B(B const &) <1:7 1:7>"); + TS_ASSERT_EQUALS(client->methods[2], "public void B::B(B &) <1:7 1:7>"); + TS_ASSERT_EQUALS(client->methods[3], "public void B::B() <6:1 <6:4 6:4> 8:1>"); } void test_cxx_parser_finds_virtual_method_declaration() @@ -162,7 +164,7 @@ public: "};\n" ); - TS_ASSERT_EQUALS(client->methods.size(), 1); + TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "public virtual void B::process() <4:15 4:21>"); } @@ -176,7 +178,7 @@ public: "};\n" ); - TS_ASSERT_EQUALS(client->methods.size(), 1); + TS_ASSERT_EQUALS(client->methods.size(), 4); TS_ASSERT_EQUALS(client->methods[0], "protected pure virtual void B::process() <4:15 4:21>"); } @@ -2730,12 +2732,12 @@ public: TS_ASSERT_EQUALS(client.functions.size(), 2); TS_ASSERT_EQUALS(client.fields.size(), 4); TS_ASSERT_EQUALS(client.globalVariables.size(), 2); - TS_ASSERT_EQUALS(client.methods.size(), 5); + TS_ASSERT_EQUALS(client.methods.size(), 15); TS_ASSERT_EQUALS(client.namespaces.size(), 2); TS_ASSERT_EQUALS(client.structs.size(), 1); TS_ASSERT_EQUALS(client.inheritances.size(), 1); - TS_ASSERT_EQUALS(client.calls.size(), 1); + TS_ASSERT_EQUALS(client.calls.size(), 3); TS_ASSERT_EQUALS(client.usages.size(), 3); TS_ASSERT_EQUALS(client.typeUses.size(), 17);