mirror of
https://github.com/Instagram/LibCST.git
synced 2025-12-23 10:35:53 +00:00
* Add flatten_sentinal * Add FlattenSentinal to __all__ * Fix lint errors * Fix type errors * Update test to use leave_Return * Update and run codegen * Add empty test * Update docs * autofix
144 lines
5.2 KiB
ReStructuredText
144 lines
5.2 KiB
ReStructuredText
.. _libcst-visitors:
|
|
|
|
Visitors
|
|
========
|
|
|
|
.. autoclass:: libcst.CSTVisitor
|
|
.. autoclass:: libcst.CSTTransformer
|
|
.. autofunction:: libcst.RemoveFromParent
|
|
.. autoclass:: libcst.RemovalSentinel
|
|
.. autoclass:: libcst.FlattenSentinel
|
|
|
|
Visit and Leave Helper Functions
|
|
--------------------------------
|
|
|
|
While it is possible to subclass from :class:`~libcst.CSTVisitor` or :class:`~libcst.CSTTransformer`
|
|
and override the ``on_visit``/``on_leave``/``on_visit_attribute``/``on_leave_attribute`` functions
|
|
directly, it is not recommended. The default implementation for both visitors will look up any
|
|
``visit_<Type[CSTNode]>``, ``leave_<Type[CSTNode]>``, ``visit_<Type[CSTNode]>_<attribute>`` and
|
|
``leave_<Type[CSTNode]>_<attribute>`` method on the visitor subclass and call them directly.
|
|
If such a function exists for the node in question, the visitor base class will call the relevant
|
|
function, respecting the above outlined semantics. If the function does not exist, the visitor base
|
|
class will assume that you do not care about that node and visit its children for you without
|
|
requiring a default implementation.
|
|
|
|
Much like ``on_visit``, ``visit_<Type[CSTNode]>`` return a boolean specifying whether or not LibCST
|
|
should visit a node's children. As a convenience, you can return ``None`` instead of a boolean value
|
|
from your ``visit_<Type[CSTNode]>`` functions. Returning a ``None`` value is treated as a request for
|
|
default behavior, which causes the visitor to traverse children. It is equivalent to returning
|
|
``True``, but requires no explicit return.
|
|
|
|
For example, the below visitor will visit every function definition, traversing to its children only
|
|
if the function name doesn't include the word "foo". Notice that we don't need to provide our own
|
|
``on_visit`` or ``on_leave`` function, nor do we need to provide visit and leave functions for the
|
|
rest of the nodes which we do not care about. This will have the effect of visiting all strings not
|
|
inside of functions that have "foo" in the name. Note that we take advantage of default behavior when
|
|
we decline to return a value in ``visit_SimpleString``.
|
|
|
|
.. code-block:: python
|
|
|
|
class FooingAround(libcst.CSTVisitor):
|
|
def visit_FunctionDef(self, node: libcst.FunctionDef) -> bool:
|
|
return "foo" not in node.name.value
|
|
|
|
def visit_SimpleString(self, node: libcst.SimpleString) -> None:
|
|
print(node.value)
|
|
|
|
An example Python REPL using the above visitor is as follows::
|
|
|
|
>>> import libcst
|
|
>>> demo = libcst.parse_module("'abc'\n'123'\ndef foo():\n 'not printed'")
|
|
>>> _ = demo.visit(FooingAround())
|
|
'abc'
|
|
'123'
|
|
|
|
.. _libcst-visitor-traversal:
|
|
|
|
Traversal Order
|
|
---------------
|
|
|
|
Traversal of any parsed tree directly matches the order that tokens appear in the source which
|
|
was parsed. LibCST will first call ``on_visit`` for the node. Then, for each of the node's
|
|
child attributes, LibCST will call ``on_visit_attribute`` for the node's attribute, followed
|
|
by running the same visit algorithm on each child node in the node's attribute. Then,
|
|
``on_leave_attribute`` is called. After each attribute has been fully traversed, LibCST will
|
|
call ``on_leave`` for the node. Note that LibCST will only call ``on_visit_attribute`` and
|
|
``on_leave_attribute`` for attributes in which there might be a LibCST node as a child. It
|
|
will not call attribute visitors for attributes which are built-in python types.
|
|
|
|
For example, take the following simple tree generated by calling ``parse_expression("1+2")``.
|
|
|
|
.. code-block:: python
|
|
|
|
BinaryOperation(
|
|
left=Integer(
|
|
value='1',
|
|
lpar=[],
|
|
rpar=[],
|
|
),
|
|
operator=Add(
|
|
whitespace_before=SimpleWhitespace(
|
|
value='',
|
|
),
|
|
whitespace_after=SimpleWhitespace(
|
|
value='',
|
|
),
|
|
),
|
|
right=Integer(
|
|
value='2',
|
|
lpar=[],
|
|
rpar=[],
|
|
),
|
|
lpar=[],
|
|
rpar=[],
|
|
)
|
|
|
|
Assuming you have a visitor that overrides every convenience helper method available,
|
|
methods will be called in this order:
|
|
|
|
.. code-block:: python
|
|
|
|
visit_BinaryOperation
|
|
visit_BinaryOperation_lpar
|
|
leave_BinaryOperation_lpar
|
|
visit_BinaryOperation_left
|
|
visit_Integer
|
|
visit_Integer_lpar
|
|
leave_Integer_lpar
|
|
visit_Integer_rpar
|
|
leave_Integer_rpar
|
|
leave_Integer
|
|
leave_BinaryOperation_left
|
|
visit_BinaryOperation_operator
|
|
visit_Add
|
|
visit_Add_whitespace_before
|
|
visit_SimpleWhitespace
|
|
leave_SimpleWhitespace
|
|
leave_Add_whitespace_before
|
|
visit_Add_whitespace_after
|
|
visit_SimpleWhitespace
|
|
leave_SimpleWhitespace
|
|
leave_Add_whitespace_after
|
|
leave_Add
|
|
leave_BinaryOperation_operator
|
|
visit_BinaryOperation_right
|
|
visit_Integer
|
|
visit_Integer_lpar
|
|
leave_Integer_lpar
|
|
visit_Integer_rpar
|
|
leave_Integer_rpar
|
|
leave_Integer
|
|
leave_BinaryOperation_right
|
|
visit_BinaryOperation_rpar
|
|
leave_BinaryOperation_rpar
|
|
leave_BinaryOperation
|
|
|
|
Batched Visitors
|
|
----------------
|
|
|
|
A batchable visitor class is provided to facilitate performing operations that
|
|
can be performed in parallel in a single traversal over a CST. An example of this
|
|
is :ref:`metadata computation<libcst-metadata>`.
|
|
|
|
.. autoclass:: libcst.BatchableCSTVisitor
|
|
.. autofunction:: libcst.visit_batched
|