Esempio n. 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)
Esempio n. 2
0
def analyse_member_var_access( name, itype, info, node, is_lvalue, is_super, msg):
    """Analyse member access that does not target a method. This is logically
    part of analyse_member_access and the arguments are similar.
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)
    
    if isinstance(v, Var):
        # Found a member variable.
        var = v
        itype = map_instance_to_supertype(itype, var.info)
        # FIX what if more than one?
        if var.typ:
            return expand_type_by_instance(var.typ.typ, itype)
        else:
            # Implicit dynamic type.
            return Any()
    elif isinstance(v, FuncDef):
        # Found a getter or a setter.
        raise NotImplementedError()
        #func = (FuncDef)v
        #itype = map_instance_to_supertype(itype, func.info)
        #return expand_type_by_instance(checker.accessor_type(v), itype)
    
    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return Any()
    else:
        return msg.has_no_member(itype, name, node)
Esempio n. 3
0
def analyse_member_access( name, typ, node, is_lvalue, is_super, tuple_type, msg, override_info=None):
    """Analyse member access. This is a general operation that supports various
    different variations:
    
      1. lvalue or non-lvalue access (i.e. setter or getter access)
      2. supertype access (when using the super keyword; is_super == True and
         override_info should refer to the supertype)
    
    Note that this function may return a RangeCallable type.
    """
    if isinstance(typ, Instance):
        # The base object has an instance type.
        itype = typ
        
        info = itype.typ
        if override_info:
            info = override_info
        
        # Look up the member. First look up the method dictionary.
        method = None
        if not is_lvalue:
            method = info.get_method(name)
        
        if method:
            # Found a method. The call below has a unique result for all valid
            # programs.
            itype = map_instance_to_supertype(itype, method.info)
            return expand_type_by_instance(method_type(method), itype)
        else:
            # Not a method.
            return analyse_member_var_access(name, itype, info, node,
                                             is_lvalue, is_super, msg)
    elif isinstance(typ, Any):
        # The base object has dynamic type.
        return Any()
    elif isinstance(typ, TupleType):
        # Actually look up from the tuple type.
        return analyse_member_access(name, tuple_type, node, is_lvalue,
                                     is_super, tuple_type, msg)
    else:
        # The base object has an unsupported type.
        return msg.has_no_member(typ, name, node)
Esempio n. 4
0
     itype = (Instance)typ
     
     info = itype.type
     if override_info:
         info = override_info
     
     # Look up the member. First look up the method dictionary.
     FuncBase method = None
     if not is_lvalue:
         method = info.get_method(name)
     
     if method:
         # Found a method. The call below has a unique result for all valid
         # programs.
         itype = map_instance_to_supertype(itype, method.info)
         return expand_type_by_instance(method_type(method), itype)
     else:
         # Not a method.
         return analyse_member_var_access(name, itype, info, node,
                                          is_lvalue, is_super, msg)
 elif isinstance(typ, Any):
     # The base object has dynamic type.
     return Any()
 elif isinstance(typ, TupleType):
     # Actually look up from the tuple type.
     return analyse_member_access(name, tuple_type, node, is_lvalue,
                                  is_super, tuple_type, msg)
 elif isinstance(typ, Callable) and ((Callable)typ).is_type_obj():
     # Class attribute access.
     return msg.not_implemented('class attributes', node)
 else: