Mypy file AST visitor run before building the IR. This collects various things, including: * Determine relationships between nested functions and functions that contain nested functions * Find non-local variables (free variables) * Find property setters * Find decorators
| 52 | |
| 53 | |
| 54 | class PreBuildVisitor(ExtendedTraverserVisitor): |
| 55 | """Mypy file AST visitor run before building the IR. |
| 56 | |
| 57 | This collects various things, including: |
| 58 | |
| 59 | * Determine relationships between nested functions and functions that |
| 60 | contain nested functions |
| 61 | * Find non-local variables (free variables) |
| 62 | * Find property setters |
| 63 | * Find decorators of functions |
| 64 | * Find module import groups |
| 65 | |
| 66 | The main IR build pass uses this information. |
| 67 | """ |
| 68 | |
| 69 | def __init__( |
| 70 | self, |
| 71 | errors: Errors, |
| 72 | current_file: MypyFile, |
| 73 | decorators_to_remove: dict[FuncDef, list[int]], |
| 74 | types: dict[Expression, Type], |
| 75 | ) -> None: |
| 76 | super().__init__() |
| 77 | # Dict from a function to symbols defined directly in the |
| 78 | # function that are used as non-local (free) variables within a |
| 79 | # nested function. |
| 80 | self.free_variables: dict[FuncItem, set[SymbolNode]] = {} |
| 81 | |
| 82 | # Intermediate data structure used to find the function where |
| 83 | # a SymbolNode is declared. Initially this may point to a |
| 84 | # function nested inside the function with the declaration, |
| 85 | # but we'll eventually update this to refer to the function |
| 86 | # with the declaration. |
| 87 | self.symbols_to_funcs: dict[SymbolNode, FuncItem] = {} |
| 88 | |
| 89 | # Stack representing current function nesting. |
| 90 | self.funcs: list[FuncItem] = [] |
| 91 | |
| 92 | # All property setters encountered so far. |
| 93 | self.prop_setters: set[FuncDef] = set() |
| 94 | |
| 95 | # A map from any function that contains nested functions to |
| 96 | # a set of all the functions that are nested within it. |
| 97 | self.encapsulating_funcs: dict[FuncItem, list[FuncItem]] = {} |
| 98 | |
| 99 | # Map nested function to its parent/encapsulating function. |
| 100 | self.nested_funcs: dict[FuncItem, FuncItem] = {} |
| 101 | |
| 102 | # Map function to its non-special decorators. |
| 103 | self.funcs_to_decorators: dict[FuncDef, list[Expression]] = {} |
| 104 | |
| 105 | # Map function to indices of decorators to remove |
| 106 | self.decorators_to_remove: dict[FuncDef, list[int]] = decorators_to_remove |
| 107 | |
| 108 | # A mapping of import groups (a series of Import nodes with |
| 109 | # nothing in between) where each group is keyed by its first |
| 110 | # import node. |
| 111 | self.module_import_groups: dict[Import, list[Import]] = {} |
no outgoing calls
searching dependent graphs…