8
8
from mypy .join import join_simple
9
9
from mypy .sametypes import is_same_type
10
10
11
+ from mypy .nodes import IndexExpr , MemberExpr , NameExpr
12
+
13
+
14
+ BindableTypes = (IndexExpr , MemberExpr , NameExpr )
15
+ BindableExpression = Union [IndexExpr , MemberExpr , NameExpr ]
16
+
11
17
12
18
class Frame (Dict [Key , Type ]):
13
19
"""A Frame represents a specific point in the execution of a program.
@@ -92,7 +98,7 @@ def push_frame(self) -> Frame:
92
98
self .options_on_return .append ([])
93
99
return f
94
100
95
- def _push (self , key : Key , type : Type , index : int = - 1 ) -> None :
101
+ def _put (self , key : Key , type : Type , index : int = - 1 ) -> None :
96
102
self .frames [index ][key ] = type
97
103
98
104
def _get (self , key : Key , index : int = - 1 ) -> Type :
@@ -103,19 +109,23 @@ def _get(self, key: Key, index: int=-1) -> Type:
103
109
return self .frames [i ][key ]
104
110
return None
105
111
106
- def push (self , node : Node , typ : Type ) -> None :
107
- if not node .literal :
112
+ def put (self , expr : Expression , typ : Type ) -> None :
113
+ # TODO: replace with isinstance(expr, BindableTypes)
114
+ if not isinstance (expr , (IndexExpr , MemberExpr , NameExpr )):
108
115
return
109
- key = node .literal_hash
116
+ if not expr .literal :
117
+ return
118
+ key = expr .literal_hash
110
119
if key not in self .declarations :
111
- self .declarations [key ] = self .get_declaration (node )
120
+ assert isinstance (expr , BindableTypes )
121
+ self .declarations [key ] = get_declaration (expr )
112
122
self ._add_dependencies (key )
113
- self ._push (key , typ )
123
+ self ._put (key , typ )
114
124
115
125
def unreachable (self ) -> None :
116
126
self .frames [- 1 ].unreachable = True
117
127
118
- def get (self , expr : Union [ Expression , Var ] ) -> Type :
128
+ def get (self , expr : Expression ) -> Type :
119
129
return self ._get (expr .literal_hash )
120
130
121
131
def is_unreachable (self ) -> bool :
@@ -163,7 +173,7 @@ def update_from_options(self, frames: List[Frame]) -> bool:
163
173
for other in resulting_values [1 :]:
164
174
type = join_simple (self .declarations [key ], type , other )
165
175
if not is_same_type (type , current_value ):
166
- self ._push (key , type )
176
+ self ._put (key , type )
167
177
changed = True
168
178
169
179
self .frames [- 1 ].unreachable = not frames
@@ -189,19 +199,13 @@ def pop_frame(self, can_skip: bool, fall_through: int) -> Frame:
189
199
190
200
return result
191
201
192
- def get_declaration (self , expr : Node ) -> Type :
193
- if isinstance (expr , RefExpr ) and isinstance (expr .node , Var ):
194
- type = expr .node .type
195
- if isinstance (type , PartialType ):
196
- return None
197
- return type
198
- else :
199
- return None
200
-
201
202
def assign_type (self , expr : Expression ,
202
203
type : Type ,
203
204
declared_type : Type ,
204
205
restrict_any : bool = False ) -> None :
206
+ # TODO: replace with isinstance(expr, BindableTypes)
207
+ if not isinstance (expr , (IndexExpr , MemberExpr , NameExpr )):
208
+ return None
205
209
if not expr .literal :
206
210
return
207
211
self .invalidate_dependencies (expr )
@@ -226,16 +230,16 @@ def assign_type(self, expr: Expression,
226
230
and not restrict_any ):
227
231
pass
228
232
elif isinstance (type , AnyType ):
229
- self .push (expr , declared_type )
233
+ self .put (expr , declared_type )
230
234
else :
231
- self .push (expr , type )
235
+ self .put (expr , type )
232
236
233
237
for i in self .try_frames :
234
238
# XXX This should probably not copy the entire frame, but
235
239
# just copy this variable into a single stored frame.
236
240
self .allow_jump (i )
237
241
238
- def invalidate_dependencies (self , expr : Expression ) -> None :
242
+ def invalidate_dependencies (self , expr : BindableExpression ) -> None :
239
243
"""Invalidate knowledge of types that include expr, but not expr itself.
240
244
241
245
For example, when expr is foo.bar, invalidate foo.bar.baz.
@@ -246,11 +250,11 @@ def invalidate_dependencies(self, expr: Expression) -> None:
246
250
for dep in self .dependencies .get (expr .literal_hash , set ()):
247
251
self ._cleanse_key (dep )
248
252
249
- def most_recent_enclosing_type (self , expr : Expression , type : Type ) -> Type :
253
+ def most_recent_enclosing_type (self , expr : BindableExpression , type : Type ) -> Type :
250
254
if isinstance (type , AnyType ):
251
- return self . get_declaration (expr )
255
+ return get_declaration (expr )
252
256
key = expr .literal_hash
253
- enclosers = ([self . get_declaration (expr )] +
257
+ enclosers = ([get_declaration (expr )] +
254
258
[f [key ] for f in self .frames
255
259
if key in f and is_subtype (type , f [key ])])
256
260
return enclosers [- 1 ]
@@ -334,3 +338,11 @@ def top_frame_context(self) -> Iterator[Frame]:
334
338
assert len (self .frames ) == 1
335
339
yield self .push_frame ()
336
340
self .pop_frame (True , 0 )
341
+
342
+
343
+ def get_declaration (expr : BindableExpression ) -> Type :
344
+ if isinstance (expr , RefExpr ) and isinstance (expr .node , Var ):
345
+ type = expr .node .type
346
+ if not isinstance (type , PartialType ):
347
+ return type
348
+ return None
0 commit comments