Exemple #1
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)
Exemple #2
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)
Exemple #3
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)
Exemple #4
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)
Exemple #5
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
Exemple #6
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
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
        
        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())
Exemple #10
0
    # 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.