7.4.4. Class Node¶
A node represents an entity of the source code (e. g. a function, a variable, a file) or a concept in the imagination of the analyst or an analysis (e. g. a cluster, an architectural entity).
7.4.4.1. Obtaining a Node¶
The constructor of class Node returns either a new node of type node_type or the type in graph named node_type_name respectively. A node type can be acquired from the graph by using instance method node_type, see Section Node and Edge Types.
The new node is not contained in any view but it is already part of the graph. You have to insert it into a view. A node as part of the RFG graph is automatically garbage collected when it is removed from the last view that contains it.
Caution
If you remove a node from the last view it has been contained in, the node is automatically garbage collected immediately. So make sure you first add a node to a target view before removing it from a source view if you intend to transfer the node between two views.
Note
If you created a new node and want to get rid of it, you have to insert it into a view and remove it from that view. The node will be garbage collected after the removal.
Caution
Nodes contained in sets are not removed from the sets once they are garbage collected from an RFG.
All methods of the RFG interface that return nodes return values of class Node.
7.4.4.2. General Operations¶
graph()
Instance method graph returns the graph the node is part of.
__str__()
Instance method __str__ returns a textual representation of the node (only for debugging purposes). For user output, use the general attribute handling methods.
The two instance methods __eq__ and __ne__ check for equality respectively inequality of two nodes.
Ordinarily, both functions are called by way of the == and != operators.
7.4.4.3. Hashing of Nodes¶
__hash__()
The hash function is used for dictionaries. Hash values change between multiple runs of a script. They cannot be used for persistence.
The code fragment in Listing Mapping the linkage name onto the nodes hashes the value of the
attribute Linkage.Name for all nodes of a view.
#!/usr/bin/env rfgscript
# Copyright (C) 2025 Axivion GmbH
# Copyright (C) 2025 The Qt Company GmbH, a subsidiary of The Qt Group
# https://www.qt.io
import sys
from bauhaus import rfg
if len(sys.argv) < 2:
print("usage: %s <rfgfile>" % (sys.argv[0]))
sys.exit(1)
my_graph = rfg.Graph(sys.argv[1])
my_view = my_graph.view(rfg.code_facts_view_name())
# an empty dictionary
get_node_of_name = {}
# let us fill the table
for n in my_view.xnodes():
get_node_of_name[n["Linkage.Name"]] = n
# from here on, we have random access to the nodes
# of the code facts view by link name
# example:
# somenode = get_node_of_name["somename"]
7.4.4.4. Type of a Node¶
The node_type instance method returns the type of the node which is represented as NodeType. The instance method is_of_type takes a type descriptor or a string representing the name of the type as argument and checks whether the node is of the given type (and not of a subtype). Instance method is_of_subtype includes subtypes (children) of the given type in the check. Instance method mutate changes the type of a node.
The script shown in Listing Counting how many nodes are present in a view per node type counts how many nodes of
each node type show up in the Code Facts view of the RFG you give as command
line parameter.
#!/usr/bin/env rfgscript
# Copyright (C) 2025 Axivion GmbH
# Copyright (C) 2025 The Qt Company GmbH, a subsidiary of The Qt Group
# https://www.qt.io
import sys
import typing
from bauhaus import rfg
if len(sys.argv) < 3:
print("usage: %s <rfgfile> <viewname>" % (sys.argv[0]))
sys.exit(1)
myrfg = rfg.Graph(sys.argv[1])
# summary contains the count of each node type contained in myrfg
summary: typing.Dict[str, int] = {}
if myrfg.is_view_name(sys.argv[2]):
for node in myrfg.view(sys.argv[2]).xnodes():
type_of_node = node.node_type().name()
summary[type_of_node] = summary.get(type_of_node, 0) + 1
# printout the result table
print("\n".join("%s %s" % (atype, summary[atype]) for atype in summary))
else:
print("Argument %s is not a view in the loaded RFG." % sys.argv[2])
7.4.4.5. Value Handling for Attributes¶
For a full explanation of the attribute handling, see Section Attributes.
Caution
A node has to be inserted in at least one view of a graph before one can set values of attributes at that node.
7.4.4.6. Membership in the View¶
Instance methods insert and add make the node to be contained in the argument view. Instance method remove removes the node from a view.
Caution
If you remove a node from the last view it has been contained in, the node is automatically garbage collected immediately. So make sure you first add a node to a target view before removing it from a source view if you intend to transfer the node between two views.
The class View features a __contains__ method that can be used for checking whether a node is contained in a view.
7.4.4.7. Predicates for the Neighborhood of Nodes¶
7.4.4.8. Querying the Neighborhood of Nodes¶
These instance methods are performing the operations described in section Section Querying the Neighborhood of Nodes and Edges.
The instance methods incomings, outgoings, and attached return edge sets.
The instance methods successors, predecessors, and neighbors return node sets.
Note
Because edges can be contained in a view and not contained in another view, the argument view is crucial for the neighborhood relations.