Exemple #1
0
def map_type_from_supertype( typ, sub_info, super_info):
    """Map type variables in a type defined in a supertype context to be valid
    in the subtype context. Assume that the result is unique; if more than
    one type is possible, return one of the alternatives.
    
    For example, assume
    
      class D<S> ...
      class C<T> is D<E<T>> ...
    
    Now S in the context of D would be mapped to E<T> in the context of C.
    """
    # Create the type of self in subtype, of form t<a1, ...>.
    inst_type = self_type(sub_info)
    # Map the type of self to supertype. This gets us a description of the
    # supertype type variables in terms of subtype variables, i.e. t<t1, ...>
    # so that any type variables in tN are to be interpreted in subtype
    # context.
    inst_type = map_instance_to_supertype(inst_type, super_info)
    # Finally expand the type variables in type with those in the previously
    # constructed type. Note that both type and inst_type may have type
    # variables, but in type they are interpreterd in supertype context while
    # in inst_type they are interpreted in subtype context. This works even if
    # the names of type variables in supertype and subtype overlap.
    return expand_type_by_instance(typ, inst_type)
Exemple #2
0
 def analyse_super(self, e, is_lvalue):
     """Type check a super expression."""
     if e.info and e.info.base:
         return analyse_member_access(e.name, self_type(e.info), e,
                                      is_lvalue, True,
                                      self.chk.tuple_type(), self.msg,
                                      e.info.base)
     else:
         # Invalid super. This has been reported by the semantic analyser.
         return Any()
Exemple #3
0
    def class_callable(self, init_type, info):
        """Create a type object type based on the signature of __init__."""
        variables = []
        for i in range(len(info.type_vars)): # TODO bounds
            variables.append(TypeVarDef(info.type_vars[i], i + 1, None))

        initvars = init_type.variables.items
        variables.extend(initvars)
        
        c = Callable(init_type.arg_types,
                     init_type.arg_kinds,
                     init_type.arg_names,
                     self_type(info),
                     True,
                     None,
                     TypeVars(variables)).with_name(
                                          '"{}"'.format(info.name()))
        return convert_class_tvars_to_func_tvars(c, len(initvars))
Exemple #4
0
                                                              e.value_type])
 
 Typ visit_func_expr(self, FuncExpr e):
     """Type check lambda expression."""
     # TODO implement properly
     return Any()
 
 Typ visit_super_expr(self, SuperExpr e):
     """Type check a super expression (non-lvalue)."""
     t = self.analyse_super(e, False)
     return t
 
 Typ analyse_super(self, SuperExpr e, bool is_lvalue):
     """Type check a super expression."""
     if e.info and e.info.base:
         return analyse_member_access(e.name, self_type(e.info), e,
                                      is_lvalue, True,
                                      self.chk.tuple_type(), self.msg,
                                      e.info.base)
     else:
         # Invalid super. This has been reported by the semantic analyser.
         return Any()
 
 Typ visit_paren_expr(self, ParenExpr e):
     """Type check a parenthesised expression."""
     return self.accept(e.expr, self.chk.type_context[-1])
 
 Typ visit_slice_expr(self, SliceExpr e):
     for index in [e.begin_index, e.end_index, e.stride]:
         if index:
             t = self.accept(index)
Exemple #5
0
        .     self.__tv = <int>
        .     super().__init__(<int>)
        """
        
        # FIX overloading, default args / varargs, keyword args

        info = tdef.info
        
        if '__init__' not in info.methods and (tdef.is_generic() or
                                               info.base.is_generic()):
            # Generic class with no explicit __init__ method
            # (i.e. __init__ inherited from superclass). Generate a
            # wrapper that initializes type variable slots and calls
            # the superclass __init__ method.
            
            selftype = self_type(info)    
            callee_type = (Callable)analyse_member_access(
                '__init__', selftype, None, False, True, None, None,
                info.base)
            
            # Now the callee type may contain the type variables of a
            # grandparent as bound type variables, but we want the
            # type variables of the parent class. Explicitly set the
            # bound type variables.
            callee_type = self.fix_bound_init_tvars(callee_type,
                map_instance_to_supertype(selftype, info.base))
            
            super_init = (FuncDef)info.base.get_method('__init__')
            
            # Build argument list.
            args = [Var('self')]
Exemple #6
0
    . 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


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).