50
50
from mypy .nodes import (
51
51
Node , MypyFile , SymbolTable , Block , AssignmentStmt , NameExpr , MemberExpr , RefExpr , TypeInfo ,
52
52
FuncDef , ClassDef , NamedTupleExpr , SymbolNode , Var , Statement , SuperExpr , NewTypeExpr ,
53
- OverloadedFuncDef , LambdaExpr , TypedDictExpr , EnumCallExpr , MDEF
53
+ OverloadedFuncDef , LambdaExpr , TypedDictExpr , EnumCallExpr , FuncBase , TypeAliasExpr , CallExpr ,
54
+ MDEF
54
55
)
55
56
from mypy .traverser import TraverserVisitor
56
57
from mypy .types import (
57
58
Type , TypeVisitor , Instance , AnyType , NoneTyp , CallableType , DeletedType , PartialType ,
58
59
TupleType , TypeType , TypeVarType , TypedDictType , UnboundType , UninhabitedType , UnionType ,
59
- Overloaded , TypeVarDef
60
+ Overloaded , TypeVarDef , TypeList
60
61
)
61
62
from mypy .util import get_prefix
62
63
@@ -156,34 +157,41 @@ def visit_block(self, node: Block) -> None:
156
157
157
158
def visit_func_def (self , node : FuncDef ) -> None :
158
159
node = self .fixup (node )
159
- if node .type :
160
- self .fixup_type (node .type )
161
- if node .info :
162
- node .info = self .fixup (node .info )
160
+ self .process_base_func (node )
163
161
super ().visit_func_def (node )
164
162
165
163
def visit_overloaded_func_def (self , node : OverloadedFuncDef ) -> None :
166
- if node .info :
167
- node .info = self .fixup (node .info )
164
+ self .process_base_func (node )
168
165
super ().visit_overloaded_func_def (node )
169
166
170
167
def visit_class_def (self , node : ClassDef ) -> None :
171
168
# TODO additional things?
172
169
node .defs .body = self .replace_statements (node .defs .body )
173
170
node .info = self .fixup (node .info )
171
+ info = node .info
174
172
for tv in node .type_vars :
175
173
self .process_type_var_def (tv )
176
- self .process_type_info (node .info )
174
+ if info :
175
+ if info .is_named_tuple :
176
+ self .process_synthetic_type_info (info )
177
+ else :
178
+ self .process_type_info (info )
177
179
super ().visit_class_def (node )
178
180
181
+ def process_base_func (self , node : FuncBase ) -> None :
182
+ self .fixup_type (node .type )
183
+ node .info = self .fixup (node .info )
184
+ if node .unanalyzed_type :
185
+ # Unanalyzed types can have AST node references
186
+ self .fixup_type (node .unanalyzed_type )
187
+
179
188
def process_type_var_def (self , tv : TypeVarDef ) -> None :
180
189
for value in tv .values :
181
190
self .fixup_type (value )
182
191
self .fixup_type (tv .upper_bound )
183
192
184
193
def visit_assignment_stmt (self , node : AssignmentStmt ) -> None :
185
- if node .type :
186
- self .fixup_type (node .type )
194
+ self .fixup_type (node .type )
187
195
super ().visit_assignment_stmt (node )
188
196
189
197
# Expressions
@@ -200,46 +208,56 @@ def visit_member_expr(self, node: MemberExpr) -> None:
200
208
def visit_ref_expr (self , node : RefExpr ) -> None :
201
209
if node .node is not None :
202
210
node .node = self .fixup (node .node )
211
+ if isinstance (node .node , Var ):
212
+ # The Var node may be an orphan and won't otherwise be processed.
213
+ fixup_var (node .node , self .replacements )
203
214
204
215
def visit_namedtuple_expr (self , node : NamedTupleExpr ) -> None :
205
216
super ().visit_namedtuple_expr (node )
206
217
node .info = self .fixup (node .info )
207
- self .process_type_info (node .info )
218
+ self .process_synthetic_type_info (node .info )
208
219
209
220
def visit_super_expr (self , node : SuperExpr ) -> None :
210
221
super ().visit_super_expr (node )
211
222
if node .info is not None :
212
223
node .info = self .fixup (node .info )
213
224
225
+ def visit_call_expr (self , node : CallExpr ) -> None :
226
+ super ().visit_call_expr (node )
227
+ if isinstance (node .analyzed , SymbolNode ):
228
+ node .analyzed = self .fixup (node .analyzed )
229
+
214
230
def visit_newtype_expr (self , node : NewTypeExpr ) -> None :
215
231
if node .info :
216
232
node .info = self .fixup (node .info )
217
- self .process_type_info (node .info )
218
- if node .old_type :
219
- self .fixup_type (node .old_type )
233
+ self .process_synthetic_type_info (node .info )
234
+ self .fixup_type (node .old_type )
220
235
super ().visit_newtype_expr (node )
221
236
222
237
def visit_lambda_expr (self , node : LambdaExpr ) -> None :
223
- if node .info :
224
- node .info = self .fixup (node .info )
238
+ node .info = self .fixup (node .info )
225
239
super ().visit_lambda_expr (node )
226
240
227
241
def visit_typeddict_expr (self , node : TypedDictExpr ) -> None :
228
- node .info = self .fixup (node .info )
229
242
super ().visit_typeddict_expr (node )
243
+ node .info = self .fixup (node .info )
244
+ self .process_synthetic_type_info (node .info )
230
245
231
246
def visit_enum_call_expr (self , node : EnumCallExpr ) -> None :
232
247
node .info = self .fixup (node .info )
233
- self .process_type_info (node .info )
248
+ self .process_synthetic_type_info (node .info )
234
249
super ().visit_enum_call_expr (node )
235
250
251
+ def visit_type_alias_expr (self , node : TypeAliasExpr ) -> None :
252
+ self .fixup_type (node .type )
253
+ self .fixup_type (node .fallback )
254
+ super ().visit_type_alias_expr (node )
255
+
236
256
# Others
237
257
238
258
def visit_var (self , node : Var ) -> None :
239
- if node .info :
240
- node .info = self .fixup (node .info )
241
- if node .type :
242
- self .fixup_type (node .type )
259
+ node .info = self .fixup (node .info )
260
+ self .fixup_type (node .type )
243
261
super ().visit_var (node )
244
262
245
263
# Helpers
@@ -251,25 +269,34 @@ def fixup(self, node: SN) -> SN:
251
269
return cast (SN , new )
252
270
return node
253
271
254
- def fixup_type (self , typ : Type ) -> None :
255
- typ .accept (TypeReplaceVisitor (self .replacements ))
272
+ def fixup_type (self , typ : Optional [Type ]) -> None :
273
+ if typ is not None :
274
+ typ .accept (TypeReplaceVisitor (self .replacements ))
256
275
257
276
def process_type_info (self , info : Optional [TypeInfo ]) -> None :
258
277
if info is None :
259
278
return
260
- # TODO: Additional things:
261
- # - declared_metaclass
262
- # - metaclass_type
263
- # - _promote
264
- # - typeddict_type
265
- # - replaced
279
+ self .fixup_type (info .declared_metaclass )
280
+ self .fixup_type (info .metaclass_type )
281
+ self .fixup_type (info ._promote )
282
+ self .fixup_type (info .tuple_type )
283
+ self .fixup_type (info .typeddict_type )
284
+ info .defn .info = self .fixup (info )
285
+ info .replaced = self .fixup (info .replaced )
266
286
replace_nodes_in_symbol_table (info .names , self .replacements )
267
287
for i , item in enumerate (info .mro ):
268
288
info .mro [i ] = self .fixup (info .mro [i ])
269
289
for i , base in enumerate (info .bases ):
270
290
self .fixup_type (info .bases [i ])
271
- if info .tuple_type :
272
- self .fixup_type (info .tuple_type )
291
+
292
+ def process_synthetic_type_info (self , info : TypeInfo ) -> None :
293
+ # Synthetic types (types not created using a class statement) don't
294
+ # have bodies in the AST so we need to iterate over their symbol
295
+ # tables separately, unlike normal classes.
296
+ self .process_type_info (info )
297
+ for name , node in info .names .items ():
298
+ if node .node :
299
+ node .node .accept (self )
273
300
274
301
def replace_statements (self , nodes : List [Statement ]) -> List [Statement ]:
275
302
result = []
@@ -345,6 +372,10 @@ def visit_unbound_type(self, typ: UnboundType) -> None:
345
372
for arg in typ .args :
346
373
arg .accept (self )
347
374
375
+ def visit_type_list (self , typ : TypeList ) -> None :
376
+ for item in typ .items :
377
+ item .accept (self )
378
+
348
379
def visit_uninhabited_type (self , typ : UninhabitedType ) -> None :
349
380
pass
350
381
@@ -371,15 +402,16 @@ def replace_nodes_in_symbol_table(symbols: SymbolTable,
371
402
new = replacements [node .node ]
372
403
new .__dict__ = node .node .__dict__
373
404
node .node = new
374
- # TODO: Other node types
375
- if isinstance (node .node , Var ) and node .node .type :
376
- node .node .type .accept (TypeReplaceVisitor (replacements ))
377
- node .node .info = cast (TypeInfo , replacements .get (node .node .info ,
378
- node .node .info ))
379
- else :
380
- # TODO: Other node types
381
- if isinstance (node .node , Var ) and node .node .type :
382
- node .node .type .accept (TypeReplaceVisitor (replacements ))
405
+ if isinstance (node .node , Var ):
406
+ # Handle them here just in case these aren't exposed through the AST.
407
+ # TODO: Is this necessary?
408
+ fixup_var (node .node , replacements )
383
409
override = node .type_override
384
410
if override :
385
411
override .accept (TypeReplaceVisitor (replacements ))
412
+
413
+
414
+ def fixup_var (node : Var , replacements : Dict [SymbolNode , SymbolNode ]) -> None :
415
+ if node .type :
416
+ node .type .accept (TypeReplaceVisitor (replacements ))
417
+ node .info = cast (TypeInfo , replacements .get (node .info , node .info ))
0 commit comments