示例#1
0
    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
示例#2
0
def compile_slot_mapping(typ: TypeInfo) -> List[Type]:
    """Return types that represent values of type variable slots of a type.

    The returned types are in terms of type variables of the type.

    For example, assume these definitions:

      class D(Generic[S]): ...
      class C(D[E[S]], Generic[T, S]): ...

    Now slot mappings for C is [E[S], T] (S and T refer to type variables of
    C).
    """
    exprs = []  # type: List[Type]

    for slot in range(num_slots(typ)):
        # Figure out the superclass which defines the slot; also figure out
        # the tvar index that maps to the slot.
        origin, tv = find_slot_origin(typ, slot)

        # Map self type to the superclass -> extract tvar with target index
        # (only contains subclass tvars?? PROBABLY NOT).
        selftype = self_type(typ)
        selftype = map_instance_to_supertype(selftype, origin)
        tvar = selftype.args[tv - 1]

        # tvar is the representation of the slot in terms of type arguments.
        exprs.append(tvar)

    return exprs
示例#3
0
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')
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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)
示例#9
0
    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)
示例#10
0
     
     This is added to a generic wrapper class.
     """
     # The type is 'any' since it should behave covariantly in subclasses.
     return [VarDef([Var(self.object_member_name(tdef.info),
                         Any())], False, None)]
 
 str object_member_name(self, TypeInfo info):
     if self.tf.is_java:
         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.
示例#11
0
Type[] compile_slot_mapping(TypeInfo typ):
    """Return types that represent values of type variable slots of a type.

    The returned types are in terms of type variables of the type.
    
    For example, assume these definitions:
    
    . class C<T, S>(D<E<S>>): ...
    . class D<S>(object): ...
    
    Now slot mappings for C is [E<S>, T] (S and T refer to type variables of
    C).
    """
    Type[] exprs = []
    
    for slot in range(num_slots(typ)):
        # Figure out the superclass which defines the slot; also figure out
        # the tvar index that maps to the slot.
        origin, tv = find_slot_origin(typ, slot)
        
        # Map self type to the superclass -> extract tvar with target index
        # (only contains subclass tvars?? PROBABLY NOT).
        selftype = self_type(typ)
        selftype = map_instance_to_supertype(selftype, origin)
        tvar = selftype.args[tv - 1]
        
        # tvar is the representation of the slot in terms of type arguments.
        exprs.append(tvar)
    
    return exprs