Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/libcst/matchers/_decorators.py: 85%
27 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
1# Copyright (c) Meta Platforms, Inc. and affiliates.
2#
3# This source code is licensed under the MIT license found in the
4# LICENSE file in the root directory of this source tree.
6from typing import Callable, TypeVar
8from libcst.matchers._matcher_base import BaseMatcherNode
10_CSTVisitFuncT = TypeVar("_CSTVisitFuncT")
13VISIT_POSITIVE_MATCHER_ATTR: str = "_call_if_inside_matcher"
14VISIT_NEGATIVE_MATCHER_ATTR: str = "_call_if_not_inside_matcher"
15CONSTRUCTED_VISIT_MATCHER_ATTR: str = "_visit_matcher"
16CONSTRUCTED_LEAVE_MATCHER_ATTR: str = "_leave_matcher"
19def call_if_inside(
20 matcher: BaseMatcherNode,
21 # pyre-fixme[34]: `Variable[_CSTVisitFuncT]` isn't present in the function's parameters.
22) -> Callable[[_CSTVisitFuncT], _CSTVisitFuncT]:
23 """
24 A decorator for visit and leave methods inside a :class:`MatcherDecoratableTransformer`
25 or a :class:`MatcherDecoratableVisitor`. A method that is decorated with this decorator
26 will only be called if it or one of its parents matches the supplied matcher.
27 Use this to selectively gate visit and leave methods to be called only when
28 inside of another relevant node. Note that this works for both node and attribute
29 methods, so you can decorate a ``visit_<Node>`` or a ``visit_<Node>_<Attr>`` method.
30 """
32 def inner(original: _CSTVisitFuncT) -> _CSTVisitFuncT:
33 setattr(
34 original,
35 VISIT_POSITIVE_MATCHER_ATTR,
36 [*getattr(original, VISIT_POSITIVE_MATCHER_ATTR, []), matcher],
37 )
38 return original
40 return inner
43def call_if_not_inside(
44 matcher: BaseMatcherNode,
45 # pyre-fixme[34]: `Variable[_CSTVisitFuncT]` isn't present in the function's parameters.
46) -> Callable[[_CSTVisitFuncT], _CSTVisitFuncT]:
47 """
48 A decorator for visit and leave methods inside a :class:`MatcherDecoratableTransformer`
49 or a :class:`MatcherDecoratableVisitor`. A method that is decorated with this decorator
50 will only be called if it or one of its parents does not match the supplied
51 matcher. Use this to selectively gate visit and leave methods to be called only
52 when outside of another relevant node. Note that this works for both node and
53 attribute methods, so you can decorate a ``visit_<Node>`` or a ``visit_<Node>_<Attr>``
54 method.
55 """
57 def inner(original: _CSTVisitFuncT) -> _CSTVisitFuncT:
58 setattr(
59 original,
60 VISIT_NEGATIVE_MATCHER_ATTR,
61 [*getattr(original, VISIT_NEGATIVE_MATCHER_ATTR, []), matcher],
62 )
63 return original
65 return inner
68# pyre-fixme[34]: `Variable[_CSTVisitFuncT]` isn't present in the function's parameters.
69def visit(matcher: BaseMatcherNode) -> Callable[[_CSTVisitFuncT], _CSTVisitFuncT]:
70 """
71 A decorator that allows a method inside a :class:`MatcherDecoratableTransformer`
72 or a :class:`MatcherDecoratableVisitor` visitor to be called when visiting a node
73 that matches the provided matcher. Note that you can use this in combination with
74 :func:`call_if_inside` and :func:`call_if_not_inside` decorators. Unlike explicit
75 ``visit_<Node>`` and ``leave_<Node>`` methods, functions decorated with this
76 decorator cannot stop child traversal by returning ``False``. Decorated visit
77 functions should always have a return annotation of ``None``.
79 There is no restriction on the number of visit decorators allowed on a method.
80 There is also no restriction on the number of methods that may be decorated
81 with the same matcher. When multiple visit decorators are found on the same
82 method, they act as a simple or, and the method will be called when any one
83 of the contained matches is ``True``.
84 """
86 def inner(original: _CSTVisitFuncT) -> _CSTVisitFuncT:
87 setattr(
88 original,
89 CONSTRUCTED_VISIT_MATCHER_ATTR,
90 [*getattr(original, CONSTRUCTED_VISIT_MATCHER_ATTR, []), matcher],
91 )
92 return original
94 return inner
97# pyre-fixme[34]: `Variable[_CSTVisitFuncT]` isn't present in the function's parameters.
98def leave(matcher: BaseMatcherNode) -> Callable[[_CSTVisitFuncT], _CSTVisitFuncT]:
99 """
100 A decorator that allows a method inside a :class:`MatcherDecoratableTransformer`
101 or a :class:`MatcherDecoratableVisitor` visitor to be called when leaving a node
102 that matches the provided matcher. Note that you can use this in combination
103 with :func:`call_if_inside` and :func:`call_if_not_inside` decorators.
105 There is no restriction on the number of leave decorators allowed on a method.
106 There is also no restriction on the number of methods that may be decorated
107 with the same matcher. When multiple leave decorators are found on the same
108 method, they act as a simple or, and the method will be called when any one
109 of the contained matches is ``True``.
110 """
112 def inner(original: _CSTVisitFuncT) -> _CSTVisitFuncT:
113 setattr(
114 original,
115 CONSTRUCTED_LEAVE_MATCHER_ATTR,
116 [*getattr(original, CONSTRUCTED_LEAVE_MATCHER_ATTR, []), matcher],
117 )
118 return original
120 return inner