15
15
BindableExpression = Union [IndexExpr , MemberExpr , NameExpr ]
16
16
17
17
18
- class Frame (Dict [Key , Type ]):
18
+ class Frame (Dict [Optional [ Key ] , Type ]):
19
19
"""A Frame represents a specific point in the execution of a program.
20
20
It carries information about the current types of expressions at
21
21
that point, arising either from assignments to those expressions
@@ -31,7 +31,7 @@ def __init__(self) -> None:
31
31
self .unreachable = False
32
32
33
33
34
- class DeclarationsFrame (Dict [Key , Optional [Type ]]):
34
+ class DeclarationsFrame (Dict [Optional [ Key ] , Optional [Type ]]):
35
35
"""Same as above, but allowed to have None values."""
36
36
37
37
def __init__ (self ) -> None :
@@ -80,7 +80,7 @@ def __init__(self) -> None:
80
80
self .declarations = DeclarationsFrame ()
81
81
# Set of other keys to invalidate if a key is changed, e.g. x -> {x.a, x[0]}
82
82
# Whenever a new key (e.g. x.a.b) is added, we update this
83
- self .dependencies = {} # type: Dict[Key, Set[Key]]
83
+ self .dependencies = {} # type: Dict[Optional[ Key] , Set[Key]]
84
84
85
85
# Whether the last pop changed the newly top frame on exit
86
86
self .last_pop_changed = False
@@ -89,7 +89,7 @@ def __init__(self) -> None:
89
89
self .break_frames = [] # type: List[int]
90
90
self .continue_frames = [] # type: List[int]
91
91
92
- def _add_dependencies (self , key : Key , value : Key = None ) -> None :
92
+ def _add_dependencies (self , key : Key , value : Optional [ Key ] = None ) -> None :
93
93
if value is None :
94
94
value = key
95
95
else :
@@ -105,10 +105,10 @@ def push_frame(self) -> Frame:
105
105
self .options_on_return .append ([])
106
106
return f
107
107
108
- def _put (self , key : Key , type : Type , index : int = - 1 ) -> None :
108
+ def _put (self , key : Optional [ Key ] , type : Type , index : int = - 1 ) -> None :
109
109
self .frames [index ][key ] = type
110
110
111
- def _get (self , key : Key , index : int = - 1 ) -> Optional [Type ]:
111
+ def _get (self , key : Optional [ Key ] , index : int = - 1 ) -> Optional [Type ]:
112
112
if index < 0 :
113
113
index += len (self .frames )
114
114
for i in range (index , - 1 , - 1 ):
@@ -125,7 +125,8 @@ def put(self, expr: Expression, typ: Type) -> None:
125
125
if key not in self .declarations :
126
126
assert isinstance (expr , BindableTypes )
127
127
self .declarations [key ] = get_declaration (expr )
128
- self ._add_dependencies (key )
128
+ if key is not None :
129
+ self ._add_dependencies (key )
129
130
self ._put (key , typ )
130
131
131
132
def unreachable (self ) -> None :
@@ -143,7 +144,7 @@ def cleanse(self, expr: Expression) -> None:
143
144
"""Remove all references to a Node from the binder."""
144
145
self ._cleanse_key (expr .literal_hash )
145
146
146
- def _cleanse_key (self , key : Key ) -> None :
147
+ def _cleanse_key (self , key : Optional [ Key ] ) -> None :
147
148
"""Remove all references to a key from the binder."""
148
149
for frame in self .frames :
149
150
if key in frame :
0 commit comments