def make_wrapper_slot_initializer(self, creat: FuncDef) -> None: """Add type variable member initializations to a wrapper constructor. The function must be a constructor of a generic wrapper class. Modify the constructor body directly. """ for alt in [BOUND_VAR, False]: for n in range(num_slots(creat.info)): rvalue = TypeExpr( RuntimeTypeVar(NameExpr(tvar_slot_name(n, alt)))) init = AssignmentStmt( [MemberExpr(self_expr(), tvar_slot_name(n, alt), direct=True)], rvalue) self.tf.set_type(init.lvalues[0], AnyType()) self.tf.set_type(init.rvalue, AnyType()) creat.body.body.insert(n, init)
def make_wrapper_slot_initializer(self, creat): """Add type variable member initializations to a wrapper constructor. The function must be a constructor of a generic wrapper class. Modify the constructor body directly. """ for alt in [BOUND_VAR, False]: for n in range(num_slots(creat.info)): rvalue = TypeExpr( RuntimeTypeVar(NameExpr(tvar_slot_name(n, alt)))) init = AssignmentStmt( [MemberExpr(self_expr(), tvar_slot_name(n, alt), direct=True)], rvalue) self.tf.set_type(init.lvalues[0], Any()) self.tf.set_type(init.rvalue, Any()) creat.body.body.insert(n, init)
def make_instance_tvar_initializer(self, 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)], rvalue) self.tf.set_type(init.lvalues[0], Any()) self.tf.set_type(init.rvalue, Any()) creat.body.body.insert(n, init)
def make_instance_tvar_initializer(self, creat: FuncDef) -> None: """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)], rvalue) self.tf.set_type(init.lvalues[0], AnyType()) self.tf.set_type(init.rvalue, AnyType()) creat.body.body.insert(n, init)
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
def get_tvar_access_expression(typ: TypeInfo, tvindex: int, alt: Any, is_java: Any) -> RuntimeTypeVar: """Return a type expression that maps from runtime type variable slots to the type variable in the given class with the given index. For example, assuming class A(Generic[T, S]): ... and class B(A[X, Y[U]], Generic[U]): ...: get_tvar_access_expression(<B>, 1) == RuntimeTypeVar(<self.__tv2.args[0]>) (with <...> represented as nodes) """ # First get the description of how to get from supertype type variables to # a subtype type variable. mapping = get_tvar_access_path(typ, tvindex) # The type checker should have noticed if there is no mapping. Be defensive # and make sure there is one. if mapping is None: raise RuntimeError('Could not find a typevar mapping') # Build the expression for getting at the subtype type variable # progressively. # First read the value of a supertype runtime type variable slot. s = self_expr() # type: Node if alt == OBJECT_VAR: o = '__o' if is_java: o = '__o_{}'.format(typ.name) s = MemberExpr(s, o) expr = MemberExpr(s, tvar_slot_name(mapping[0] - 1, alt)) # type: Node # Then, optionally look into arguments based on the description. for i in mapping[1:]: expr = MemberExpr(expr, 'args') expr = IndexExpr(expr, IntExpr(i - 1)) # Than add a final wrapper so that we have a valid type. return RuntimeTypeVar(expr)
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)], rvalue) self.tf.set_type(init.lvalues[0], Any())
# The type checker should have noticed if there is no mapping. Be defensive # and make sure there is one. if mapping is None: raise RuntimeError('Could not find a typevar mapping') # Build the expression for getting at the subtype type variable # progressively. # First read the value of a supertype runtime type variable slot. Node s = self_expr() if alt == OBJECT_VAR: o = '__o' if is_java: o = '__o_{}'.format(typ.name) s = MemberExpr(s, o) Node expr = MemberExpr(s, tvar_slot_name(mapping[0] - 1, alt)) # Then, optionally look into arguments based on the description. for i in mapping[1:]: expr = MemberExpr(expr, 'args') expr = IndexExpr(expr, IntExpr(i - 1)) # Than add a final wrapper so that we have a valid type. return RuntimeTypeVar(expr) int[] get_tvar_access_path(TypeInfo typ, int tvindex): """Determine how to calculate the value of a type variable of a type. The description is based on operations on type variable slot values embedded in an instance. The type variable and slot indexing is 1-based.