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

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. 

5 

6from typing import Callable, TypeVar 

7 

8from libcst.matchers._matcher_base import BaseMatcherNode 

9 

10_CSTVisitFuncT = TypeVar("_CSTVisitFuncT") 

11 

12 

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" 

17 

18 

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 """ 

31 

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 

39 

40 return inner 

41 

42 

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 """ 

56 

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 

64 

65 return inner 

66 

67 

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``. 

78 

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 """ 

85 

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 

93 

94 return inner 

95 

96 

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. 

104 

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 """ 

111 

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 

119 

120 return inner