def update_type_map(self, original_type_map: Dict[Expression, Type], extra_type_map: Dict[Expression, Type]) -> None: # Calculating this would not be needed if TypeMap directly used literal hashes instead of # expressions, as suggested in the TODO above it's definition already_captured = set( literal_hash(expr) for expr in original_type_map) for expr, typ in extra_type_map.items(): if literal_hash(expr) in already_captured: node = get_var(expr) self.msg.fail( message_registry.MULTIPLE_ASSIGNMENTS_IN_PATTERN.format( node.name), expr) else: original_type_map[expr] = typ
def most_recent_enclosing_type(self, expr: BindableExpression, type: Type) -> Optional[Type]: if isinstance(type, AnyType): return get_declaration(expr) key = literal_hash(expr) assert key is not None enclosers = ([get_declaration(expr)] + [f[key] for f in self.frames if key in f and is_subtype(type, f[key])]) return enclosers[-1]
def most_recent_enclosing_type(self, expr: BindableExpression, type: Type) -> Optional[Type]: if isinstance(type, AnyType): return get_declaration(expr) key = literal_hash(expr) assert key is not None enclosers = ([get_declaration(expr)] + [f.types[key] for f in self.frames if key in f.types and is_subtype(type, f.types[key])]) return enclosers[-1]
def put(self, expr: Expression, typ: Type) -> None: if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)): return if not literal(expr): return key = literal_hash(expr) assert key is not None, 'Internal error: binder tried to put non-literal' if key not in self.declarations: self.declarations[key] = get_declaration(expr) self._add_dependencies(key) self._put(key, typ)
def put(self, expr: Expression, typ: Type) -> None: if not isinstance(expr, BindableTypes): return if not literal(expr): return key = literal_hash(expr) assert key is not None, 'Internal error: binder tried to put non-literal' if key not in self.declarations: self.declarations[key] = get_declaration(expr) self._add_dependencies(key) self._put(key, typ)
def invalidate_dependencies(self, expr: BindableExpression) -> None: """Invalidate knowledge of types that include expr, but not expr itself. For example, when expr is foo.bar, invalidate foo.bar.baz. It is overly conservative: it invalidates globally, including in code paths unreachable from here. """ key = literal_hash(expr) assert key is not None for dep in self.dependencies.get(key, set()): self._cleanse_key(dep)
def cleanse(self, expr: Expression) -> None: """Remove all references to a Node from the binder.""" key = literal_hash(expr) assert key is not None, 'Internal error: binder tried cleanse non-literal' self._cleanse_key(key)
def get(self, expr: Expression) -> Optional[Type]: key = literal_hash(expr) assert key is not None, 'Internal error: binder tried to get non-literal' return self._get(key)