@@ -48,6 +48,7 @@ def __init__(self) -> None:
48
48
# There may be multiple references to a Var node. Keep track of
49
49
# Var translations using a dictionary.
50
50
self .var_map = {} # type: Dict[Var, Var]
51
+ self .func_map = {} # type: Dict[FuncDef, FuncDef]
51
52
52
53
def visit_mypy_file (self , node : MypyFile ) -> Node :
53
54
# NOTE: The 'names' and 'imports' instance variables will be empty!
@@ -98,6 +99,12 @@ def copy_argument(self, argument: Argument) -> Argument:
98
99
99
100
def visit_func_def (self , node : FuncDef ) -> FuncDef :
100
101
# Note that a FuncDef must be transformed to a FuncDef.
102
+
103
+ # These contortions are needed to handle the case of recursive
104
+ # references inside the function being transformed.
105
+ result = FuncDef (node .name (), node .arguments , node .body , None )
106
+ self .func_map [node ] = result
107
+
101
108
new = FuncDef (node .name (),
102
109
[self .copy_argument (arg ) for arg in node .arguments ],
103
110
self .block (node .body ),
@@ -113,7 +120,8 @@ def visit_func_def(self, node: FuncDef) -> FuncDef:
113
120
new .is_class = node .is_class
114
121
new .is_property = node .is_property
115
122
new .original_def = node .original_def
116
- return new
123
+ result .__dict__ = new .__dict__
124
+ return result
117
125
118
126
def visit_func_expr (self , node : FuncExpr ) -> Node :
119
127
new = FuncExpr ([self .copy_argument (arg ) for arg in node .arguments ],
@@ -332,6 +340,9 @@ def copy_ref(self, new: RefExpr, original: RefExpr) -> None:
332
340
target = original .node
333
341
if isinstance (target , Var ):
334
342
target = self .visit_var (target )
343
+ elif isinstance (target , FuncDef ):
344
+ if target in self .func_map :
345
+ target = self .func_map [target ]
335
346
new .node = target
336
347
new .is_def = original .is_def
337
348
0 commit comments