Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/libcst/codemod/visitors/_gather_global_names.py: 33%

36 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 Set 

7 

8import libcst 

9from libcst.codemod._context import CodemodContext 

10from libcst.codemod._visitor import ContextAwareVisitor 

11 

12 

13class GatherGlobalNamesVisitor(ContextAwareVisitor): 

14 """ 

15 Gathers all globally accessible names defined in a module and stores them as 

16 attributes on the instance. 

17 Intended to be instantiated and passed to a :class:`~libcst.Module` 

18 :meth:`~libcst.CSTNode.visit` method in order to gather up information about 

19 names defined on a module. Note that this is not a substitute for scope 

20 analysis or qualified name support. Please see :ref:`libcst-scope-tutorial` 

21 for a more robust way of determining the qualified name and definition for 

22 an arbitrary node. 

23 Names that are globally accessible through imports are currently not included 

24 but can be retrieved with GatherImportsVisitor. 

25 

26 After visiting a module the following attributes will be populated: 

27 

28 global_names 

29 A sequence of strings representing global variables defined in the module 

30 toplevel. 

31 class_names 

32 A sequence of strings representing classes defined in the module toplevel. 

33 function_names 

34 A sequence of strings representing functions defined in the module toplevel. 

35 

36 """ 

37 

38 def __init__(self, context: CodemodContext) -> None: 

39 super().__init__(context) 

40 self.global_names: Set[str] = set() 

41 self.class_names: Set[str] = set() 

42 self.function_names: Set[str] = set() 

43 # Track scope nesting 

44 self.scope_depth: int = 0 

45 

46 def visit_ClassDef(self, node: libcst.ClassDef) -> None: 

47 if self.scope_depth == 0: 

48 self.class_names.add(node.name.value) 

49 self.scope_depth += 1 

50 

51 def leave_ClassDef(self, original_node: libcst.ClassDef) -> None: 

52 self.scope_depth -= 1 

53 

54 def visit_FunctionDef(self, node: libcst.FunctionDef) -> None: 

55 if self.scope_depth == 0: 

56 self.function_names.add(node.name.value) 

57 self.scope_depth += 1 

58 

59 def leave_FunctionDef(self, original_node: libcst.FunctionDef) -> None: 

60 self.scope_depth -= 1 

61 

62 def visit_Assign(self, node: libcst.Assign) -> None: 

63 if self.scope_depth != 0: 

64 return 

65 for assign_target in node.targets: 

66 target = assign_target.target 

67 if isinstance(target, libcst.Name): 

68 self.global_names.add(target.value) 

69 

70 def visit_AnnAssign(self, node: libcst.AnnAssign) -> None: 

71 if self.scope_depth != 0: 

72 return 

73 target = node.target 

74 if isinstance(target, libcst.Name): 

75 self.global_names.add(target.value)