Esempio n. 1
0
 def assert_expand(self, orig, map_items, result):
     lower_bounds = {}
     
     for id, t in map_items:
         lower_bounds[id] = t
     
     exp = expand_type(orig, lower_bounds)
     # Remove erased tags (asterisks).
     assert_equal(str(exp).replace('*', ''), str(result))
Esempio n. 2
0
    def apply_generic_arguments(self, callable, types, context):
        """Apply generic type arguments to a callable type.

        For example, applying [int] to 'def <T> (T) -> T' results in
        'def [int] (int) -> int'. Here '[int]' is an implicit bound type
        variable.
        
        Note that each type can be None; in this case, it will not be applied.
        """
        tvars = callable.variables.items        
        if len(tvars) != len(types):
            self.msg.incompatible_type_application(len(tvars), len(types),
                                                   context)
            return Any()
        
        # Create a map from type variable id to target type.
        id_to_type = {}
        for i, tv in enumerate(tvars):
            if types[i]:
                id_to_type[tv.id] = types[i]

        # Apply arguments to argument types.
        arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]
        
        bound_vars = [(tv.id, id_to_type[tv.id])
                      for tv in tvars
                      if tv.id in id_to_type]

        # The callable may retain some type vars if only some were applied.
        remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type]
        
        return Callable(arg_types,
                        callable.arg_kinds,
                        callable.arg_names,
                        expand_type(callable.ret_type, id_to_type),
                        callable.is_type_obj(),
                        callable.name,
                        TypeVars(remaining_tvars),
                        callable.bound_vars + bound_vars,
                        callable.line, callable.repr)
Esempio n. 3
0
def map_instance_to_direct_supertype( instance, supertype):
    typ = instance.typ
    
    for b in typ.bases:
        # The cast below cannot fail since we require that semantic analysis
        # was successful, so bases cannot contain unbound types.
        if b and (b).typ == supertype:
            map = type_var_map(typ, instance.args)
            return expand_type(b, map)
    
    # Relationship with the supertype not specified explicitly. Use dynamic
    # type arguments implicitly.
    return Instance(typ.base, [Any()] * len(typ.base.type_vars))
Esempio n. 4
0
def map_instance_to_direct_supertypes( instance, supertype):
    # FIX: There should only be one supertypes, always.
    typ = instance.typ
    result = []
    
    for b in typ.bases:
        # The cast below cannot fail since we require that semantic analysis
        # was successful, so bases cannot contain unbound types.
        if b and (b).typ == supertype:
            map = type_var_map(typ, instance.args)
            result.append(expand_type(b, map))
    
    if result:
        return result
    else:
        # Relationship with the supertype not specified explicitly. Use dynamic
        # type arguments implicitly.
        return [Instance(supertype, [Any()] * len(supertype.type_vars))]
Esempio n. 5
0
 tvars.extend(callable.variables.items)
 
 if len(tvars) != len(types):
     self.msg.incompatible_type_application(len(tvars), len(types),
                                            context)
     return Any()
 
 # Create a map from type variable name to target type.
 dict<int, Typ> map = {}
 for i in range(len(tvars)):
     if types[i]:
         map[tvars[i].id] = types[i]
 
 Typ[] arg_types = []
 for at in callable.arg_types:
     arg_types.append(expand_type(at, map))
 
 list<tuple<int, Typ>> bound_vars = []
 for tv in tvars:
     if tv.id in map:
         bound_vars.append((tv.id, map[tv.id]))
 
 return Callable(arg_types,
                 callable.arg_kinds,
                 callable.arg_names,
                 expand_type(callable.ret_type, map),
                 callable.is_type_obj(),
                 callable.name,
                 TypeVars([]),
                 callable.bound_vars + bound_vars,
                 callable.line, callable.repr)
Esempio n. 6
0
                                                    instance.type.base)
        if instance.type == supertype: break
    
    return instance


Instance map_instance_to_direct_supertype(Instance instance,
                                          TypeInfo supertype):
    typ = instance.type
    
    for b in typ.bases:
        # The cast below cannot fail since we require that semantic analysis
        # was successful, so bases cannot contain unbound types.
        if b and ((Instance)b).type == supertype:
            map = type_var_map(typ, instance.args)
            return (Instance)expand_type(b, map)
    
    # Relationship with the supertype not specified explicitly. Use dynamic
    # type arguments implicitly.
    return Instance(typ.base, <Type> [Any()] * len(typ.base.type_vars))


dict<int, Type> type_var_map(TypeInfo typ, Type[] args):
    if not args:
        return None
    else:
        tvars = <int, Type> {}
        for i in range(len(args)):
            tvars[i + 1] = args[i]
        return tvars