def make_generic_wrapper_init(self, info: TypeInfo) -> FuncDef: """Build constructor of a generic wrapper class.""" nslots = num_slots(info) cdefs = [] # type: List[Node] # Build superclass constructor call. base = info.mro[1] if base.fullname() != 'builtins.object' and self.tf.is_java: s = SuperExpr('__init__') cargs = [NameExpr('__o')] # type: List[Node] for n in range(num_slots(base)): cargs.append(NameExpr(tvar_arg_name(n + 1))) for n in range(num_slots(base)): cargs.append(NameExpr(tvar_arg_name(n + 1, BOUND_VAR))) c = CallExpr(s, cargs, [nodes.ARG_POS] * len(cargs)) cdefs.append(ExpressionStmt(c)) # Create initialization of the wrapped object. cdefs.append(AssignmentStmt([MemberExpr( self_expr(), self.object_member_name(info), direct=True)], NameExpr('__o'))) # Build constructor arguments. args = [Var('self'), Var('__o')] init = [None, None] # type: List[Node] for alt in [False, BOUND_VAR]: for n in range(nslots): args.append(Var(tvar_arg_name(n + 1, alt))) init.append(None) nargs = nslots * 2 + 2 fdef = FuncDef('__init__', args, [nodes.ARG_POS] * nargs, init, Block(cdefs), Callable( [AnyType()] * nargs, [nodes.ARG_POS] * nargs, [None] * nargs, Void(), is_type_obj=False)) fdef.info = info self.make_wrapper_slot_initializer(fdef) return fdef
def visit_type_var(self, t): if t.id < 0: # Generic function type variable; always in a local variable. return RuntimeTypeVar(NameExpr(tvar_arg_name(t.id))) else: # Instance type variables are stored in the instance. return get_tvar_access_expression(self.context, t.id, t.is_wrapper_var, self.is_java)
def visit_type_var(self, t: TypeVar) -> Type: if t.id < 0: # Generic function type variable; always in a local variable. return RuntimeTypeVar(NameExpr(tvar_arg_name(t.id))) else: # Instance type variables are stored in the instance. return get_tvar_access_expression(self.context, t.id, t.is_wrapper_var, self.is_java)
def prepend_generic_function_tvar_args(self, fdef: FuncDef) -> None: """Add implicit function type variable arguments if fdef is generic.""" sig = cast(Callable, function_type(fdef)) tvars = sig.variables if not fdef.type: fdef.type = sig tv = [] # type: List[Var] ntvars = len(tvars) if fdef.is_method(): # For methods, add type variable arguments after the self arg. for n in range(ntvars): tv.append(Var(tvar_arg_name(-1 - n))) fdef.type = add_arg_type_after_self(cast(Callable, fdef.type), AnyType()) fdef.args = [fdef.args[0]] + tv + fdef.args[1:] else: # For ordinary functions, prepend type variable arguments. for n in range(ntvars): tv.append(Var(tvar_arg_name(-1 - n))) fdef.type = prepend_arg_type(cast(Callable, fdef.type), AnyType()) fdef.args = tv + fdef.args fdef.init = List[AssignmentStmt]([None]) * ntvars + fdef.init
def prepend_generic_function_tvar_args(self, fdef): """Add implicit function type variable arguments if fdef is generic.""" sig = function_type(fdef) tvars = sig.variables.items if not fdef.type: fdef.type = sig tv = [] ntvars = len(tvars) if fdef.is_method(): # For methods, add type variable arguments after the self arg. for n in range(ntvars): tv.append(Var(tvar_arg_name(-1 - n))) fdef.type = add_arg_type_after_self(fdef.type, Any()) fdef.args = [fdef.args[0]] + tv + fdef.args[1:] else: # For ordinary functions, prepend type variable arguments. for n in range(ntvars): tv.append(Var(tvar_arg_name(-1 - n))) fdef.type = prepend_arg_type(fdef.type, Any()) fdef.args = tv + fdef.args fdef.init = [None] * ntvars + fdef.init
def \ add_constructor_tvar_args( self, fdef, typ, args, arg_kinds, init): """Add type variable arguments for __init__ of a generic type. Return tuple (new args, new kinds, new inits). """ tv = [] ntvars = len(fdef.info.type_vars) for n in range(ntvars): tv.append(Var(tvar_arg_name(n + 1))) typ = add_arg_type_after_self(typ, Any()) args = [args[0]] + tv + args[1:] arg_kinds = [arg_kinds[0]] + [nodes.ARG_POS] * ntvars + arg_kinds[1:] init = [None] * ntvars + init return (args, arg_kinds, init, typ)
def add_constructor_tvar_args( self, fdef: FuncDef, typ: Type, args: List[Var], arg_kinds: List[int], init: List[Node]) -> Tuple[List[Var], List[int], List[Node], Type]: """Add type variable arguments for __init__ of a generic type. Return tuple (new args, new kinds, new inits). """ tv = [] # type: List[Var] ntvars = len(fdef.info.type_vars) for n in range(ntvars): tv.append(Var(tvar_arg_name(n + 1))) typ = add_arg_type_after_self(cast(Callable, typ), AnyType()) args = [args[0]] + tv + args[1:] arg_kinds = [arg_kinds[0]] + [nodes.ARG_POS] * ntvars + arg_kinds[1:] init = List[Node]([None]) * ntvars + init return (args, arg_kinds, init, typ)
def call_args(self, vars: List[Var], target_ann: Callable, cur_ann: Callable, is_dynamic: bool, is_wrapper_class: bool, bound_sig: Callable = None, ismethod: bool = False) -> List[Node]: """Construct the arguments of a wrapper call expression. Insert coercions as needed. """ args = [] # type: List[Node] # Add ordinary arguments, including self (for methods). for i in range(len(vars)): a = vars[i] name = NameExpr(a.name()) if bound_sig is None: args.append( self.tf.coerce(name, target_ann.arg_types[i], cur_ann.arg_types[i], self.tf.type_context(), is_wrapper_class)) else: c = self.tf.coerce(name, bound_sig.arg_types[i], cur_ann.arg_types[i], self.tf.type_context(), is_wrapper_class) args.append( self.tf.coerce(c, target_ann.arg_types[i], bound_sig.arg_types[i], self.tf.type_context(), is_wrapper_class)) # Add type variable arguments for a generic function. for i in range(len(target_ann.variables)): # Non-dynamic wrapper method in a wrapper class passes # generic function type arguments to the target function; # otherwise use dynamic types. index = i if ismethod: index += 1 if is_wrapper_class and not is_dynamic: args.insert( index, TypeExpr(RuntimeTypeVar(NameExpr(tvar_arg_name(-i - 1))))) else: args.insert(index, TypeExpr(AnyType())) return args
def call_args(self, vars: List[Var], target_ann: Callable, cur_ann: Callable, is_dynamic: bool, is_wrapper_class: bool, bound_sig: Callable = None, ismethod: bool = False) -> List[Node]: """Construct the arguments of a wrapper call expression. Insert coercions as needed. """ args = [] # type: List[Node] # Add ordinary arguments, including self (for methods). for i in range(len(vars)): a = vars[i] name = NameExpr(a.name()) if bound_sig is None: args.append(self.tf.coerce(name, target_ann.arg_types[i], cur_ann.arg_types[i], self.tf.type_context(), is_wrapper_class)) else: c = self.tf.coerce(name, bound_sig.arg_types[i], cur_ann.arg_types[i], self.tf.type_context(), is_wrapper_class) args.append(self.tf.coerce(c, target_ann.arg_types[i], bound_sig.arg_types[i], self.tf.type_context(), is_wrapper_class)) # Add type variable arguments for a generic function. for i in range(len(target_ann.variables)): # Non-dynamic wrapper method in a wrapper class passes # generic function type arguments to the target function; # otherwise use dynamic types. index = i if ismethod: index += 1 if is_wrapper_class and not is_dynamic: args.insert(index, TypeExpr(RuntimeTypeVar(NameExpr(tvar_arg_name(-i - 1))))) else: args.insert(index, TypeExpr(AnyType())) return args
def visit_type_var(self, t): # FIX function type variables return RuntimeTypeVar(NameExpr(tvar_arg_name(t.id)))
return '__o_{}'.format(info.name) else: return '__o' FuncDef make_generic_wrapper_init(self, TypeInfo info): """Build constructor of a generic wrapper class.""" nslots = num_slots(info) cdefs = <Node> [] # Build superclass constructor call. if info.base.full_name() != 'builtins.object' and self.tf.is_java: s = SuperExpr('__init__') cargs = <Node> [NameExpr('__o')] for n in range(num_slots(info.base)): cargs.append(NameExpr(tvar_arg_name(n + 1))) for n in range(num_slots(info.base)): cargs.append(NameExpr(tvar_arg_name(n + 1, BOUND_VAR))) c = CallExpr(s, cargs, [nodes.ARG_POS] * len(cargs)) cdefs.append(ExpressionStmt(c)) # Create initialization of the wrapped object. cdefs.append(AssignmentStmt([MemberExpr( self_expr(), self.object_member_name(info), direct=True)], NameExpr('__o'))) # Build constructor arguments. args = [Var('self'), Var('__o')] Node[] init = [None, None]
def visit_type_var(self, t: TypeVar) -> Type: # FIX function type variables return RuntimeTypeVar(NameExpr(tvar_arg_name(t.id)))
return fdef2 tuple<Var[], int[], Node[], Type> \ add_constructor_tvar_args( self, FuncDef fdef, Type typ, Var[] args, int[] arg_kinds, Node[] init): """Add type variable arguments for __init__ of a generic type. Return tuple (new args, new kinds, new inits). """ Var[] tv = [] ntvars = len(fdef.info.type_vars) for n in range(ntvars): tv.append(Var(tvar_arg_name(n + 1))) typ = add_arg_type_after_self((Callable)typ, Any()) args = [args[0]] + tv + args[1:] arg_kinds = [arg_kinds[0]] + [nodes.ARG_POS] * ntvars + arg_kinds[1:] init = <Node> [None] * ntvars + init return (args, arg_kinds, init, typ) FuncDef override_method_wrapper(self, FuncDef fdef): """Construct a method wrapper for an overridden method.""" orig_fdef = fdef.info.base.get_method(fdef.name()) return self.method_wrapper((FuncDef)orig_fdef, fdef, False, False) FuncDef dynamic_method_wrapper(self, FuncDef fdef): """Construct a dynamically typed method wrapper.""" return self.method_wrapper(fdef, fdef, True, False)