def find_slot_origin(info: TypeInfo, slot: int) -> Tuple[TypeInfo, int]: """Determine class and type variable index that directly maps to the slot. The result defines which class in inheritance hierarchy of info introduced the slot. All subclasses inherit this slot. The result TypeInfo always refers to one of the base classes of info (or info itself). Examples: - In 'class C(Generic[T]): ...', the slot 0 in C is mapped to type var 1 (T) in C. - In 'class D(C[U], Generic[S, U]): ...', the slot 0 in D is mapped to type var 1 (T) in C; the slot 1 of D is mapped to type variable 1 of D. """ base = info.bases[0].type super_slots = num_slots(base) if slot < super_slots: # A superclass introduced the slot. return find_slot_origin(base, slot) else: # This class introduced the slot. Figure out which type variable maps # to the slot. for tv in range(1, len(info.type_vars) + 1): if get_tvar_access_path(info, tv)[0] - 1 == slot: return (info, tv) raise RuntimeError('Could not map slot')
def make_tvar_representation(self, info, is_alt=False): """Return type variable slot member definitions. There are of form 'any __tv*'. Only include new slots defined in the type. """ defs = [] base_slots = num_slots(info.base) for n in range(len(info.type_vars)): # Only include a type variable if it introduces a new slot. slot = get_tvar_access_path(info, n + 1)[0] - 1 if slot >= base_slots: defs.append(VarDef([Var(tvar_slot_name(slot, is_alt), Any())], False, None)) return defs
def make_tvar_representation(self, info: TypeInfo, is_alt: Any = False) -> List[Node]: """Return type variable slot member definitions. There are of form '__tv*: Any'. Only include new slots defined in the type. """ defs = [] # type: List[Node] base_slots = num_slots(info.mro[1]) for n in range(len(info.type_vars)): # Only include a type variable if it introduces a new slot. slot = get_tvar_access_path(info, n + 1)[0] - 1 if slot >= base_slots: defs.append(VarDef([Var(tvar_slot_name(slot, is_alt), AnyType())], False, None)) return defs
self.make_wrapper_slot_initializer(fdef) return fdef Node[] make_tvar_representation(self, TypeInfo info, any is_alt=False): """Return type variable slot member definitions. There are of form 'any __tv*'. Only include new slots defined in the type. """ Node[] defs = [] base_slots = num_slots(info.base) for n in range(len(info.type_vars)): # Only include a type variable if it introduces a new slot. slot = get_tvar_access_path(info, n + 1)[0] - 1 if slot >= base_slots: defs.append(VarDef([Var(tvar_slot_name(slot, is_alt), Any())], False, None)) return defs void make_instance_tvar_initializer(self, FuncDef creat): """Add type variable member initialization code to a constructor. Modify the constructor body directly. """ for n in range(num_slots(creat.info)): rvalue = self.make_tvar_init_expression(creat.info, n) init = AssignmentStmt([MemberExpr(self_expr(), tvar_slot_name(n), direct=True)],
exprs.append(tvar) return exprs tuple<TypeInfo, int> find_slot_origin(TypeInfo info, int slot): """Determine class and type variable index that directly maps to the slot. The result defines which class in inheritance hierarchy of info introduced the slot. All subclasses inherit this slot. The result TypeInfo always refers to one of the base classes of info (or info itself). Examples: - In 'class C<T>: ...', the slot 0 in C is mapped to type var 1 (T) in C. - In 'class D<S, U>(C<U>): ...', the slot 0 in D is mapped to type var 1 (T) in C; the slot 1 of D is mapped to type variable 1 of D. """ base = info.base super_slots = num_slots(base) if slot < super_slots: # A superclass introduced the slot. return find_slot_origin(base, slot) else: # This class introduced the slot. Figure out which type variable maps # to the slot. for tv in range(1, len(info.type_vars) + 1): if get_tvar_access_path(info, tv)[0] - 1 == slot: return (info, tv) raise RuntimeError('Could not map slot')