loki.ir.transformer
Visitor classes for transforming the IR
Classes
| 
 | An enriched  | 
| 
 | A  | 
| 
 | A  | 
| 
 | Visitor class to rebuild the tree and replace nodes according to a mapper. | 
- class Transformer(mapper=None, invalidate_source=True, inplace=False, rebuild_scopes=False)
- Bases: - Visitor- Visitor class to rebuild the tree and replace nodes according to a mapper. - Given a control flow tree \(T\) and a mapper from nodes in \(T\) to a set of new nodes \(L, M : N \rightarrow L\), build a new control flow tree \(T'\) where a node \(n \in N\) is replaced with \(M(n)\). - Important - The mapping is applied before visiting any children of a node. - Removing nodes: In the special case in which \(M(n)\) is None, \(n\) is dropped from \(T'\). - One to many mapping: In the special case in which \(M(n)\) is an iterable of nodes, all nodes in \(M(n)\) are inserted into the tuple containing \(n\). - Warning - Applying a - Transformerto an IR tree rebuilds all nodes by default, which means individual nodes from the original IR are no longer found in the new tree. To update references to IR nodes, the attribute- Transformer.rebuiltprovides a mapping from original to rebuilt nodes. Alternatively, with- inplacethe mapping can be applied without rebuilding the tree, leaving existing references to individual IR nodes intact (as long as the mapping does not replace or remove them in the tree).- Parameters:
- mapper (dict) – The mapping \(M : N \rightarrow L\). 
- invalidate_source (bool, optional) – If set to True, this triggers invalidating the - sourceproperty of all parent nodes of a node \(n\) if \(M(n)\) has- source=None.
- inplace (bool, optional) – If set to True, all updates are performed on existing - Nodeobjects, instead of rebuilding them, keeping the original tree intact.
- rebuild_scopes (bool, optional) – If set to True, this will also rebuild - ScopedNodein the IR. This requires updating- TypedSymbol.scopeproperties, which is expensive and thus carried out only when explicitly requested.
 
 - rebuilt
- After applying the - Transformerto an IR, this contains a mapping \(n \rightarrow n'\) for every node of the original tree \(n \in T\) to the rebuilt nodes in the new tree \(n' \in T'\).- Type:
 
 - visit_object(o, **kwargs)
- Return the object unchanged. 
 - visit_tuple(o, **kwargs)
- Visit all elements in a tuple, injecting any one-to-many mappings. 
 - visit_list(o, **kwargs)
- Visit all elements in a tuple, injecting any one-to-many mappings. 
 - visit_Node(o, **kwargs)
- Handler for - Nodeobjects.- It replaces - oby- mapper[o], if it is in the mapper, otherwise visits all children before rebuilding the node.
 - visit_ScopedNode(o, **kwargs)
- Handler for - ScopedNodeobjects.- It replaces - oby- mapper[o], if it is in the mapper, otherwise its behaviour differs slightly from the default- visit_Node()as it rebuilds the node first, then visits all children and then updates in-place the rebuilt node. This is to make sure upwards-pointing references to this scope (such as- ScopedNode.parentproperties) can be updated correctly.- Additionally, it passes down the currently active scope in - kwargswhen recursing to children.
 - visit(o, *args, **kwargs)
- Apply this - Transformerto an IR tree.
 
- class NestedTransformer(mapper=None, invalidate_source=True, inplace=False, rebuild_scopes=False)
- Bases: - Transformer- A - Transformerthat applies replacements in a depth-first fashion.- visit_tuple(o, **kwargs)
- Visit all elements in a tuple, injecting any one-to-many mappings. 
 - visit_list(o, **kwargs)
- Visit all elements in a tuple, injecting any one-to-many mappings. 
 - visit_Node(o, **kwargs)
- Handler for - Nodeobjects.- It visits all children before applying the - mapper.
 - visit_ScopedNode(o, **kwargs)
- Handler for - ScopedNodeobjects.- Its behaviour differs slightly from the default - visit_Node()as it rebuilds the node first, then visits all children and then updates in-place the rebuilt node. This is to make sure upwards-pointing references to this scope (such as- ScopedNode.parentproperties) can be updated correctly.- Additionally, it passes down the currently active scope in - kwargswhen recursing to children.
 
- class MaskedTransformer(start=None, stop=None, active=False, require_all_start=False, greedy_stop=False, **kwargs)
- Bases: - Transformer- An enriched - Transformerthat can selectively include or exclude parts of the tree.- For that - MaskedTransformeris selectively switched on and off while traversing the tree. Nodes are only included in the new tree while it is “switched on”. The transformer is switched on or off when it encounters nodes from- startor- stop, respectively. This can be used, e.g., to extract everything between two nodes, or to create a copy of the entire tree but without all nodes between two nodes. Multiple such ranges can be defined by providing more than one- startand- stopnode, respectively.- The sets - startand- stopare to be understood in a Pythonic way, i.e.,- startnodes will be included in the result and- stopexcluded.- Important - When recursing down a tree, any - InternalNodeare only included in the tree if the- MaskedTransformerwas switched on before visiting that- InternalNode. Importantly, this means the node is also not included if the transformer is switched on while traversing the internal node’s body. In such a case, only the body nodes that are included are retained.- Optionally as a variant, switching on can also be delayed until all nodes from - starthave been encountered by setting- require_all_startto True.- Optionally, traversal can be terminated early with - greedy_stop. If enabled, the- MaskedTransformerwill stop completely to traverse the tree as soon as encountering a node from- stop.- Note - Enabling - require_all_startand- greedy_stopat the same time can be useful when you require the minimum number of nodes in-between multiple start and end nodes without knowing in which order they appear.- Note - MaskedTransformerrebuilds also- ScopedNodeby default (i.e., it calls the parent constructor with- rebuild_scopes=True).- Parameters:
- start ((iterable of) - Node, optional) – Encountering a node from- startduring traversal switches the- MaskedTransformeron and includes that node and all subsequently traversed nodes in the produced tree.
- stop ((iterable of) - Node, optional) – Encountering a node from- stopduring traversal switches the- MaskedTransformeroff and excludes that node and all subsequently traversed nodes from the produced tree.
- active (bool, optional) – Switch the - MaskedTransformeron at the beginning of the traversal. By default, it is switched on only after encountering a node from- start.
- require_all_start (bool, optional) – Switch the - MaskedTransformeron only after encountering all nodes from- start. By default, it is switched on after encountering any node from- start.
- greedy_stop (bool, optional) – Stop traversing the tree as soon as any node from - stopis encountered. By default, traversal continues but nodes are excluded from the new tree until a node from- startis encountered.
- **kwargs (optional) – Keyword arguments that are passed to the parent class constructor. 
 
 - visit(o, *args, **kwargs)
- Apply this - Transformerto an IR tree.
 - visit_object(o, **kwargs)
- Return the object unchanged. 
 - visit_Node(o, **kwargs)
- Handler for - Nodeobjects.- It replaces - oby- mapper[o], if it is in the mapper, otherwise visits all children before rebuilding the node.
 - visit_ScopedNode(o, **kwargs)
- Handler for - ScopedNodeobjects.- It replaces - oby- mapper[o], if it is in the mapper, otherwise its behaviour differs slightly from the default- visit_Node()as it rebuilds the node first, then visits all children and then updates in-place the rebuilt node. This is to make sure upwards-pointing references to this scope (such as- ScopedNode.parentproperties) can be updated correctly.- Additionally, it passes down the currently active scope in - kwargswhen recursing to children.
 
- class NestedMaskedTransformer(start=None, stop=None, active=False, require_all_start=False, greedy_stop=False, **kwargs)
- Bases: - MaskedTransformer- A - MaskedTransformerthat retains parents for children that are included in the produced tree.- In contrast to - MaskedTransformer, any encountered- InternalNodeare included in the new tree as long as any of its children are included.- visit_object(o, **kwargs)
- Return the object unchanged. - Note that we need to keep them here regardless of the transformer being active because this handler takes care of properties for inactive parents that may still be retained if other children switch on the transformer. 
 - visit_LeafNode(o, **kwargs)
- Handler for - LeafNodethat are included in the tree if the- NestedMaskedTransformeris active.
 - visit_InternalNode(o, **kwargs)
- Handler for - InternalNodethat are included in the tree as long as any- bodynode is included.
 - visit_Conditional(o, **kwargs)
- Handler for - Conditionalto account for the- else_body.- Note - This removes the - Conditionalif- bodyis empty. In that case,- else_bodyis returned (which can be empty, too).
 - visit_MultiConditional(o, **kwargs)
- Handler for - MultiConditionalto account for all bodies.- Note - This removes the - MultiConditionalif all of the- bodiesare empty. In that case,- else_bodyis returned (which can be empty, too).