Class VariationNode<T extends VariationNode<T,L>,L extends Label>
- Type Parameters:
T
- the derived type (the type extending this class)L
- The type of label stored in this tree.
- All Implemented Interfaces:
HasNodeType
- Direct Known Subclasses:
Projection
,VariationTreeNode
Provides common methods for querying variation trees and changing their structure. This class
doesn't provide mutation methods for attributes which may be shared between different underlying
nodes (for example a projection
of a DiffNode
). Most prominently,
there are no methods to change the type
or the label
of this node.
There are many methods which are not abstract. These are convenience methods or algorithms
acting on variation nodes where a separate class may be undesirable (for example because they are
quite common or because the calling syntax node.algorithm()
makes more sense than the
alternative Algorithm.run(node)
).
- Author:
- Benjamin Moosherr
- See Also:
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Adds this subtree below the given parent.abstract void
The same asinsertChild(T,int)
but puts the node at the end of the children list instead of inserting it at a specific index.void
addChildren
(Collection<T> children) Adds the given nodes in traversal order as children usingaddChild(T)
.boolean
Checks whether any node in this subtree satisfies the given condition.void
Checks that this node satisfies some easy to check invariants.downCast()
Returns this instance as aVariationNode
.void
drop()
Removes this subtree from its parents by removing it as child from its parent and settings the parent of this node tonull
.void
forAllPreorder
(Consumer<T> action) Traverses all nodes in this subtree in preorder.void
forMeAndMyAncestors
(Consumer<T> action) int
Returns the number of child nodes.Returns an unmodifiable list representing the children of this node.int
getDepth()
Computes the length of the path from the root node to this node.org.prop4j.Node
Returns the full feature mapping formula of this node.private List<org.prop4j.Node>
Same asgetFeatureMapping()
but returns a list of formulas representing a conjunction.abstract org.prop4j.Node
Returns the formula that is stored in this node.abstract int
getID()
Returns an integer that uniquely identifies this node within its tree.Returns the firstif
node in the path from this node upwards to the root.abstract L
getLabel()
Returns the label of this node.abstract LineRange
Returns the range of line numbers of this node's corresponding source code.abstract NodeType
Returns the node type of this node which determines the type of the represented element in the variation tree (e.g., mapping or artifact).abstract T
Returns the parent of this node, ornull
if this node doesn't have a parent.org.prop4j.Node
Returns the presence condition of this node.private List<org.prop4j.Node>
Returns the presence condition clauses of this node.int
indexOfChild
(T child) Returns the index of the given child in the list of children of this node.abstract void
insertChild
(T child, int index) Adds a child before the given index to the children list of this node and sets its parent to this node.boolean
Returnstrue
iff this node is the parent of the given node.boolean
isLeaf()
Returnstrue
iff this node has no children.boolean
isRoot()
Returnstrue
iff this node has no parent.boolean
isSameAs
(VariationNode<T, L> other) Returns true if this subtree is exactly equal toother
.void
printSourceCode
(StringBuilder output) Unparses the labels of this subtree intooutput
.abstract void
Removes all children of this node and sets their parent tonull
.abstract void
removeChild
(T child) Removes the given node from this node's children list and sets the parent ofchild
tonull
.void
removeChildren
(Collection<T> childrenToRemove) Removes the given nodes from the children list usingremoveChild(T)
.abstract void
setLineRange
(LineRange lineRange) Sets the range of line numbers of this node's corresponding source code.protected boolean
shallowIsSameAs
(VariationNode<T, L> other) Returns true if this node is exactly equal toother
without checking any children.void
stealChildrenOf
(T other) Removes all children from the given node and adds them as children to this node.Returns a copy of this variation tree in aconcrete variation tree implementation
.toVariationTree
(Map<? super T, VariationTreeNode<L>> oldToNew) Returns a copy of this variation tree in aconcrete variation tree implementation
.abstract T
upCast()
Returns this instance as the derived class typeT
.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.variantsync.diffdetective.variation.tree.HasNodeType
isAnnotation, isArtifact, isConditionalAnnotation, isElif, isElse, isIf
-
Constructor Details
-
VariationNode
public VariationNode()
-
-
Method Details
-
upCast
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). -
downCast
Returns this instance as aVariationNode
. This is only useful for accessing private members inside ofVariationNode
. These can't be accessed if the type of the variable of this instance isT
so a down cast is required. This function only exists to document this necessity and make it more readable. -
getNodeType
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
- See Also:
-
getLabel
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 obtaingetFormula()
. In either case, this label may be an arbitrary value, selected according to the needs of the user of this class. -
getLineRange
Returns the range of line numbers of this node's corresponding source code.- See Also:
-
setLineRange
Sets the range of line numbers of this node's corresponding source code.- See Also:
-
getParent
Returns the parent of this node, ornull
if this node doesn't have a parent.- See Also:
-
getChildren
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)) }
- See Also:
-
isRoot
public boolean isRoot()Returnstrue
iff this node has no parent.- See Also:
-
isLeaf
public boolean isLeaf()Returnstrue
iff this node has no children.- See Also:
-
getChildCount
public int getChildCount()Returns the number of child nodes.Note: This is O(n) for
Projection
.- See Also:
-
getDepth
public int getDepth()Computes the length of the path from the root node to this node. -
getIfNode
Returns the firstif
node in the path from this node upwards to the root. -
isChild
Returnstrue
iff this node is the parent of the given node.- See Also:
-
indexOfChild
Returns the index of the given child in the list of children of this node. Returns -1 if the given node is not a child of this node.Warning: If this is a
Projection
, then the returned index may be different to the index returned byDiffNode.indexOfChild(org.variantsync.diffdetective.variation.diff.DiffNode<L>, org.variantsync.diffdetective.variation.diff.Time)
.- See Also:
-
addChild
The same asinsertChild(T,int)
but puts the node at the end of the children list instead of inserting it at a specific index.- Throws:
IllegalArgumentException
- ifchild
already has a parent- See Also:
-
insertChild
Adds a child before the given index to the children list of this node and sets its parent to this node.When calling
indexOfChild(T)
withchild
the returned index will beindex
as long as the children list isn't modified.- Throws:
IllegalArgumentException
- ifchild
already has a parent- See Also:
-
addChildren
Adds the given nodes in traversal order as children usingaddChild(T)
. *- Throws:
IllegalArgumentException
- if any child ofchildren
already has a parent
-
removeChild
Removes the given node from this node's children list and sets the parent ofchild
tonull
.- Throws:
IllegalArgumentException
- ifchilde
is not a child of this node- See Also:
-
removeChildren
Removes the given nodes from the children list usingremoveChild(T)
.- Throws:
IllegalArgumentException
- if any child inchildrenToRemove
is not a child of this node- See Also:
-
removeAllChildren
public abstract void removeAllChildren()Removes all children of this node and sets their parent tonull
. Afterwards, this node will have no children. -
addBelow
Adds this subtree below the given parent. Inverse ofdrop()
.- Throws:
IllegalArgumentException
- if this node already has a parent- See Also:
-
drop
public void drop()Removes this subtree from its parents by removing it as child from its parent and settings the parent of this node tonull
. Inverse ofaddBelow(T)
.- See Also:
-
stealChildrenOf
Removes all children from the given node and adds them as children to this node. The order of the children is preserved. The given node will have no children afterwards.- Parameters:
other
- The node whose children should be stolen.- See Also:
-
getFormula
public abstract org.prop4j.Node getFormula()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). -
getFeatureMappingClauses
Same asgetFeatureMapping()
but returns a list of formulas representing a conjunction. -
getFeatureMapping
public org.prop4j.Node getFeatureMapping()Returns the full feature mapping formula of this node.The feature mapping of an
NodeType.IF
node is itsdirect feature mapping
. The feature mapping ofNodeType.ELSE
andNodeType.ELIF
nodes is determined by all formulas in the respective if-elif-else chain. The feature mapping of anartifact
node is the feature mapping of its parent. See Equation (1) in our paper.- Returns:
- the feature mapping of this node
-
getPresenceConditionClauses
Returns the presence condition clauses of this node.- Returns:
- a list representing a conjunction (i.e., all clauses should be combined with boolean AND)
- See Also:
-
getPresenceCondition
public org.prop4j.Node getPresenceCondition()Returns the presence condition of this node. See Equation (2) in our paper. -
forAllPreorder
Traverses all nodes in this subtree in preorder. -
forMeAndMyAncestors
-
anyMatch
Checks whether any node in this subtree satisfies the given condition. The condition might not be invoked on every node in case a node is found.- Parameters:
condition
- A condition to check on each node.- Returns:
- True iff the given condition returns true for at least one node in this tree.
-
toVariationTree
Returns a copy of this variation tree in aconcrete variation tree implementation
. If the type parameterT
of this class isVariationTreeNode
then this is effectively a deep copy. -
toVariationTree
Returns a copy of this variation tree in aconcrete variation tree implementation
. If the type parameterT
of this class isVariationTreeNode
then this is effectively a deep copy.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.
-
assertConsistency
public void assertConsistency()Checks that this node satisfies some easy to check invariants. In particular, this method checks that- if-chains are nested correctly,
- the root is an
NodeType.IF
with the feature mapping"true"
, - the feature mapping is
null
iffisConditionalAnnotation
isfalse
and - all edges are well-formed (e.g., edges can be inconsistent because edges are double-linked).
Some invariants are not checked. These include
- There should be no cycles and
getID()
should be unique in the whole variation tree.
- Throws:
AssertionError
- when an inconsistency is detected.- See Also:
-
getID
public abstract int getID()Returns an integer that uniquely identifies this node within its tree.Some attributes may be recovered from this ID but this depends on the derived class. For example
VariationTreeNode.fromID(int, L)
can recovergetNodeType()
andthe start line number
. Beware thatProjection
returnsDiffNode.getID()
so this id is not fully compatible withVariationTreeNode.getID()
. -
printSourceCode
Unparses the labels of this subtree intooutput
.This method assumes that all labels of this subtree represent source code lines.
-
isSameAs
Returns true if this subtree is exactly equal toother
. This check uses equality checks instead of identity. -
shallowIsSameAs
Returns true if this node is exactly equal toother
without checking any children. This check uses equality checks instead of identity.
-