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
DiffNodes.
- Author:
- Benjamin Moosherr
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final List<VariationTreeNode<L>> The list for maintaining the order of all children of this node.private org.prop4j.NodeThe 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 LineRangeThe range of line numbers of this node's corresponding source code.private VariationTreeNode<L> The parent of this node. -
Constructor Summary
ConstructorsConstructorDescriptionVariationTreeNode(NodeType nodeType, org.prop4j.Node featureMapping, LineRange lineRange, L label) Creates a new node of a variation tree. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddChild(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 givenidand label.Returns an unmodifiable list representing the children of this node.org.prop4j.NodeReturns the formula that is stored in this node.intgetID()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, ornullif this node doesn't have a parent.voidinsertChild(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.voidRemoves all children of this node and sets their parent tonull.voidremoveChild(VariationTreeNode<L> child) Removes the given node from this node's children list and sets the parent ofchildtonull.voidReplaces the current label bynewLabelLines.voidsetLineRange(LineRange lineRange) Sets the range of line numbers of this node's corresponding source code.private voidsetParent(VariationTreeNode<L> newParent) SetsnewParentas 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, toVariationTreeMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods 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
nulliffHasNodeType.isConditionalAnnotation()isfalse. -
parent
The parent of this node. It'snulliff this node doesn't have a parent.Invariant: Iff
parent != nullthenparent.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.isConditionalAnnotationistruelineRange- the line range of the code oflabellabel- 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.IFand its feature mapping is"true"). The label of this node is empty and therefore the line numbers areinvalid.- See Also:
-
createArtifact
Convenience constructor for creating an artifact node of aVariationTree.- Parameters:
lineRange- the line range of the code oflabellabel- a list of lines used as label- See Also:
-
upCast
Description copied from class:VariationNodeReturns this instance as the derived class typeT. The deriving class will only have to returnthishere 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:
upCastin classVariationNode<VariationTreeNode<L extends Label>,L extends Label>
-
getNodeType
Description copied from class:VariationNodeReturns 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:
getNodeTypein interfaceHasNodeType- Specified by:
getNodeTypein classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
getLabel
Description copied from class:VariationNodeReturns the label of this node.If
HasNodeType.isArtifact()istruethis 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:
getLabelin classVariationNode<VariationTreeNode<L extends Label>,L extends Label>
-
setLabel
Replaces the current label bynewLabelLines.- See Also:
-
getLineRange
Description copied from class:VariationNodeReturns the range of line numbers of this node's corresponding source code.- Specified by:
getLineRangein classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
setLineRange
Description copied from class:VariationNodeSets the range of line numbers of this node's corresponding source code.- Specified by:
setLineRangein classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
getParent
Description copied from class:VariationNodeReturns the parent of this node, ornullif this node doesn't have a parent.- Specified by:
getParentin classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
setParent
SetsnewParentas the new parent of this node.This node must not have a parent yet.
-
getChildren
Description copied from class:VariationNodeReturns an unmodifiable list representing the children of this node.The following invariant has to hold for all
nodes:for (var child : node.getChildren()) { Assert.assertTrue(node == child.getParent(node)) }- Specified by:
getChildrenin classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
addChild
Description copied from class:VariationNodeThe 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:
addChildin classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
insertChild
Description copied from class:VariationNodeAdds 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)withchildthe returned index will beindexas long as the children list isn't modified.- Specified by:
insertChildin classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
removeChild
Description copied from class:VariationNodeRemoves the given node from this node's children list and sets the parent ofchildtonull.- Specified by:
removeChildin classVariationNode<VariationTreeNode<L extends Label>,L extends Label> - See Also:
-
removeAllChildren
public void removeAllChildren()Description copied from class:VariationNodeRemoves all children of this node and sets their parent tonull. Afterwards, this node will have no children.- Specified by:
removeAllChildrenin classVariationNode<VariationTreeNode<L extends Label>,L extends Label>
-
getFormula
public org.prop4j.Node getFormula()Description copied from class:VariationNodeReturns the formula that is stored in this node. The formula is notnullformapping nodes with annotationsandnullotherwise (NodeType.ARTIFACT,NodeType.ELSE).If the type parameter
Tof this class is not a concrete variation tree, then the returnedformulashould be treated as unmodifiable to prevent undesired side effects (e.g., toDiffNodes).- Specified by:
getFormulain 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 typeandstart line number) can be reconstructed by using<L>fromID(int,L).Note that this encoding assumes that line numbers fit into
26bits.- Specified by:
getIDin classVariationNode<VariationTreeNode<L extends Label>,L extends Label>
-
fromID
Reconstructs a node from the givenidand 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
oldToNewshould 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
-