Example #1
0
 def check_method_or_accessor_override_for_base(self, defn, base):
     """Check that function definition is compatible with any overridden
     definition in the specified supertype.
     """
     if base:
         if defn.name() != '__init__':
             # Check method override (create is special).
             base_method = base.get_method(defn.name())
             if base_method and base_method.info == base:
                 # There is an overridden method in the supertype.
                 
                 # Construct the type of the overriding method.
                 typ = method_type(defn)
                 # Map the overridden method type to subtype context so that
                 # it can be checked for compatibility. Note that multiple
                 # types from multiple implemented interface instances may
                 # be present.
                 original_type = map_type_from_supertype(
                     method_type(base_method), defn.info, base)
                 # Check that the types are compatible.
                 # TODO overloaded signatures
                 self.check_override(typ,
                                     original_type,
                                     defn.name(),
                                     base_method.info.name(),
                                     defn)
         
         # Also check interface implementations.
         for iface in base.interfaces:
             self.check_method_or_accessor_override_for_base(defn, iface)
         
         # We have to check that the member is compatible with all
         # supertypes due to the dynamic type. Otherwise we could first
         # override with dynamic and then with an arbitary type.
         self.check_method_or_accessor_override_for_base(defn, base.base)
Example #2
0
 def type_object_type(self, info):
     """Return the type of a type object.
     
     For a generic type G with type variables T and S the type is of form
     
       def <T, S>(...) as G<T, S>,
     
     where ... are argument types for the __init__ method.
     """
     if info.is_interface:
         return self.chk.type_type()
     init_method = info.get_method('__init__')
     if not init_method:
         # Must be an invalid class definition.
         return Any()
     else:
         # Construct callable type based on signature of __init__. Adjust
         # return type and insert type arguments.
         init_type = method_type(init_method)
         if isinstance(init_type, Callable):
             return self.class_callable(init_type, info)
         else:
             # Overloaded __init__.
             items = []
             for it in (init_type).items():
                 items.append(self.class_callable(it, info))
             return Overloaded(items)
Example #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)
Example #4
0
        For a generic type G with type variables T and S the type is of form
        
          def <T, S>(...) as G<T, S>,
        
        where ... are argument types for the __init__ method.
        """
        if info.is_interface:
            return self.chk.type_type()
        init_method = info.get_method('__init__')
        if not init_method:
            # Must be an invalid class definition.
            return Any()
        else:
            # Construct callable type based on signature of __init__. Adjust
            # return type and insert type arguments.
            init_type = method_type(init_method)
            if isinstance(init_type, Callable):
                return self.class_callable((Callable)init_type, info)
            else:
                # Overloaded __init__.
                Callable[] items = []
                for it in ((Overloaded)init_type).items():
                    items.append(self.class_callable(it, info))
                return Overloaded(items)
    
    Callable class_callable(self, Callable init_type, TypeInfo info):
        """Create a type object type based on the signature of __init__."""
        variables = <TypeVarDef> []
        for i in range(len(info.type_vars)): # TODO bounds
            variables.append(TypeVarDef(info.type_vars[i], i + 1, None))
Example #5
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: