Class VariationTreeNode<L extends Label>
- All Implemented Interfaces:
HasNodeType
A variation tree is a representation of source code in a software product line. Each node in
such a tree is either an artifact
or a mapping node
.
Artifacts represent source code which may be reused in multiple variants. In contrast, mappings
do not contain source code of a specific variant. They store information about which variants
contain the artifacts it has as children
in the form of a
feature mapping
.
See definition 2.2 of
our ESEC/FSE'22 paper for a mathematical formalization or variation trees. In contrast to
this formalization, this implementation optimizes for variation trees obtained from source code
annotated with the C preprocessor syntax. This mostly means that there is the additional
NodeType.ELIF
node type.
This class contains references to all of its children and its parent so all connected nodes of
a variation tree can be reached through each node of the variation tree. Nevertheless, most of
the time only node itself or its subtree (the reflexive hull of getChildren()
) is meant
when when referencing a VariationTreeNode
. Use VariationTree
to unambiguously
refer to a whole variation tree.
If possible, algorithms should be using VariationNode
instead of this concrete
implementation. This allows the usage of a projection of a DiffNode
instead of a concrete
variation node.
To compare two variation trees use VariationDiff
which uses the aforementioned
DiffNode
s.
- Author:
- Benjamin Moosherr
- See Also:
-
Field Summary
Modifier and TypeFieldDescriptionprivate final List<VariationTreeNode<L>>
The list for maintaining the order of all children of this node.private org.prop4j.Node
The direct feature mapping of this node.private VariationLabel<L>
The label together with the node type of this node, which determines the type of the represented element in the diff (e.g., mapping or artifact).private LineRange
The range of line numbers of this node's corresponding source code.private VariationTreeNode<L>
The parent of this node. -
Constructor Summary
ConstructorDescriptionVariationTreeNode
(NodeType nodeType, org.prop4j.Node featureMapping, LineRange lineRange, L label) Creates a new node of a variation tree. -
Method Summary
Modifier and TypeMethodDescriptionvoid
addChild
(VariationTreeNode<L> child) The same asVariationNode.insertChild(T,int)
but puts the node at the end of the children list instead of inserting it at a specific index.static <L extends Label>
VariationTreeNode<L>createArtifact
(LineRange lineRange, L label) Convenience constructor for creating an artifact node of aVariationTree
.static <L extends Label>
VariationTreeNode<L>createRoot
(L label) Convenience constructor for creating the root of aVariationTree
.deepCopy()
Creates a deep copy of this node.deepCopy
(Map<VariationTreeNode<L>, VariationTreeNode<L>> oldToNew) Creates a deep copy of this node.static <L extends Label>
VariationTreeNode<L>fromID
(int id, L label) Reconstructs a node from the givenid
and label.Returns an unmodifiable list representing the children of this node.org.prop4j.Node
Returns the formula that is stored in this node.int
getID()
Returns an integer that uniquely identifiers this node within its variation tree.getLabel()
Returns the label of this node.Returns the range of line numbers of this node's corresponding source code.Returns the node type of this node which determines the type of the represented element in the variation tree (e.g., mapping or artifact).Returns the parent of this node, ornull
if this node doesn't have a parent.void
insertChild
(VariationTreeNode<L> child, int index) Adds a child before the given index to the children list of this node and sets its parent to this node.void
Removes all children of this node and sets their parent tonull
.void
removeChild
(VariationTreeNode<L> child) Removes the given node from this node's children list and sets the parent ofchild
tonull
.void
Replaces the current label bynewLabelLines
.void
setLineRange
(LineRange lineRange) Sets the range of line numbers of this node's corresponding source code.private void
setParent
(VariationTreeNode<L> newParent) SetsnewParent
as the new parent of this node.toString()
upCast()
Returns this instance as the derived class typeT
.Methods inherited from class org.variantsync.diffdetective.variation.tree.VariationNode
addBelow, addChildren, anyMatch, assertConsistency, downCast, drop, forAllPreorder, forMeAndMyAncestors, getChildCount, getDepth, getFeatureMapping, getIfNode, getPresenceCondition, indexOfChild, isChild, isLeaf, isRoot, isSameAs, printSourceCode, removeChildren, shallowIsSameAs, stealChildrenOf, toVariationTree, toVariationTree
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.variantsync.diffdetective.variation.tree.HasNodeType
isAnnotation, isArtifact, isConditionalAnnotation, isElif, isElse, isIf
-
Field Details
-
label
The label together with the node type of this node, which determines the type of the represented element in the diff (e.g., mapping or artifact). -
lineRange
The range of line numbers of this node's corresponding source code. -
featureMapping
private org.prop4j.Node featureMappingThe direct feature mapping of this node.This is
null
iffHasNodeType.isConditionalAnnotation()
isfalse
. -
parent
The parent of this node. It'snull
iff this node doesn't have a parent.Invariant: Iff
parent != null
thenparent.childOrder.contains(this)
. -
childOrder
The list for maintaining the order of all children of this node.- See Also:
-
-
Constructor Details
-
VariationTreeNode
public VariationTreeNode(NodeType nodeType, org.prop4j.Node featureMapping, LineRange lineRange, L label) Creates a new node of a variation tree. The newly created node is not connected to any other nodes. The new node takes ownership of the given label without copying it. Beware of any further modifications to this list.- Parameters:
nodeType
- the type of this nodefeatureMapping
- the direct feature mapping of this node, has be non null iffnodeType.isConditionalAnnotation
istrue
lineRange
- the line range of the code oflabel
label
- a list of lines used as label- See Also:
-
-
Method Details
-
createRoot
Convenience constructor for creating the root of aVariationTree
.The newly created root has no children yet.
The root is a neutral annotation (i.e., its type if
NodeType.IF
and its feature mapping is"true"
). The label of this node is empty and therefore the line numbers areinvalid
. -
createArtifact
Convenience constructor for creating an artifact node of aVariationTree
.- Parameters:
lineRange
- the line range of the code oflabel
label
- a list of lines used as label- See Also:
-
upCast
Description copied from class:VariationNode
Returns this instance as the derived class typeT
. The deriving class will only have to returnthis
here but this can't be implemented in the base class. If some derived class can't implement this method by returningthis
, it probably violates the requirements for the type parameterT
(namely that it' the derived class itself).- Specified by:
upCast
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label>
-
getNodeType
Description copied from class:VariationNode
Returns the node type of this node which determines the type of the represented element in the variation tree (e.g., mapping or artifact).- Specified by:
getNodeType
in interfaceHasNodeType
- Specified by:
getNodeType
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
getLabel
Description copied from class:VariationNode
Returns the label of this node.If
HasNodeType.isArtifact()
istrue
this may represent the source code of this artifact. Otherwise it may represent the preprocessor expression which was parsed to obtainVariationNode.getFormula()
. In either case, this label may be an arbitrary value, selected according to the needs of the user of this class.- Specified by:
getLabel
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label>
-
setLabel
Replaces the current label bynewLabelLines
.- See Also:
-
getLineRange
Description copied from class:VariationNode
Returns the range of line numbers of this node's corresponding source code.- Specified by:
getLineRange
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
setLineRange
Description copied from class:VariationNode
Sets the range of line numbers of this node's corresponding source code.- Specified by:
setLineRange
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
getParent
Description copied from class:VariationNode
Returns the parent of this node, ornull
if this node doesn't have a parent.- Specified by:
getParent
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
setParent
SetsnewParent
as the new parent of this node.This node must not have a parent yet.
-
getChildren
Description copied from class:VariationNode
Returns an unmodifiable list representing the children of this node.The following invariant has to hold for all
node
s:for (var child : node.getChildren()) { Assert.assertTrue(node == child.getParent(node)) }
- Specified by:
getChildren
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
addChild
Description copied from class:VariationNode
The same asVariationNode.insertChild(T,int)
but puts the node at the end of the children list instead of inserting it at a specific index.- Specified by:
addChild
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
insertChild
Description copied from class:VariationNode
Adds a child before the given index to the children list of this node and sets its parent to this node.When calling
VariationNode.indexOfChild(T)
withchild
the returned index will beindex
as long as the children list isn't modified.- Specified by:
insertChild
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
removeChild
Description copied from class:VariationNode
Removes the given node from this node's children list and sets the parent ofchild
tonull
.- Specified by:
removeChild
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label> - See Also:
-
removeAllChildren
public void removeAllChildren()Description copied from class:VariationNode
Removes all children of this node and sets their parent tonull
. Afterwards, this node will have no children.- Specified by:
removeAllChildren
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label>
-
getFormula
public org.prop4j.Node getFormula()Description copied from class:VariationNode
Returns the formula that is stored in this node. The formula is notnull
formapping nodes with annotations
andnull
otherwise (NodeType.ARTIFACT
,NodeType.ELSE
).If the type parameter
T
of this class is not a concrete variation tree, then the returnedformula
should be treated as unmodifiable to prevent undesired side effects (e.g., toDiffNode
s).- Specified by:
getFormula
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label>
-
getID
public int getID()Returns an integer that uniquely identifiers this node within its variation tree.From the returned id a new node with all essential attributes (
node type
andstart line number
) can be reconstructed by using<L>fromID(int,L)
.Note that this encoding assumes that line numbers fit into
26
bits.- Specified by:
getID
in classVariationNode<VariationTreeNode<L extends Label>,
L extends Label>
-
fromID
Reconstructs a node from the givenid
and label. The almost-inverse function isgetID()
but the conversion is not lossless.- Parameters:
id
- the id from which to reconstruct the nodelabel
- the label the node should have- Returns:
- the reconstructed node
-
deepCopy
Creates a deep copy of this node. -
deepCopy
Creates a deep copy of this node.The map
oldToNew
should be empty as it will be filled by this method. After the method call, the map keys will contain all nodes in this node's subtree (including this node). The corresponding values will be the nodes in the returned node's subtree (including the returned node), where each pair (k, v) denotes that v was cloned from k.- Parameters:
oldToNew
- A map that memorizes the translation of individual nodes.- Returns:
- A deep copy of this tree.
-
toString
-