Пример #1
0
 def analyse_ref_expr(self, e):
     result = None
     node = e.node
     if isinstance(node, Var):
         # Variable or constant reference.
         v = node
         if not v.typ:
             # Implicit dynamic type.
             result = Any()
         else:
             # Local or global variable.
             result = v.typ.typ
     elif isinstance(node, FuncDef):
         # Reference to a global function.
         f = node
         result = function_type(f)
     elif isinstance(node, OverloadedFuncDef):
         o = node
         result = o.typ.typ
     elif isinstance(node, TypeInfo):
         # Reference to a type object.
         result = self.type_object_type(node)
     else:
         # Unknown reference; use dynamic type implicitly to avoid
         # generating extra type errors.
         result = Any()
     return result
Пример #2
0
 def visit_overloaded_func_def(self, defn):
     t = []
     for f in defn.items:
         f.is_overload = True
         f.accept(self)
         t.append(function_type(f))
     defn.typ = Annotation(Overloaded(t))
     defn.typ.set_line(defn.line)
     
     if self.typ:
         self.typ.methods[defn.name()] = defn
         defn.info = self.typ
Пример #3
0
 def make_overload_check(self, f, fixed_args, rest_args):
     a = []
     i = 0
     if rest_args:
         a.append(self.make_argument_count_check(f, len(fixed_args),
                                                 rest_args))
     for t in function_type(f).arg_types:
         if not isinstance(t, Any) and (t.repr or
                                        isinstance(t, Callable)):
             a.append(self.make_argument_check(
                 self.argument_ref(i, fixed_args, rest_args), t))
         i += 1
     return ' and '.join(a)
Пример #4
0
 def visit_func_expr(self, e):
     """Type check lambda expression."""
     inferred_type = self.infer_lambda_type(e)
     self.chk.check_func_item(e, type_override=inferred_type)
     ret_type = self.chk.type_map[e.expr()]
     if inferred_type:
         return replace_callable_return_type(inferred_type, ret_type)
     elif e.typ:
         return replace_callable_return_type(e.typ.typ, ret_type)
     else:
         # Use default type for lambda.
         # TODO infer return type?
         return function_type(e)
Пример #5
0
 def check_func_item(self, defn, type_override=None):
     # We may be checking a function definition or an anonymous function. In
     # the first case, set up another reference with the precise type.
     fdef = None
     if isinstance(defn, FuncDef):
         fdef = defn
     
     self.dynamic_funcs.append(defn.typ is None and not type_override)
     
     if fdef:
         self.errors.set_function(fdef.name())
     
     typ = function_type(defn)
     if type_override:
         typ = type_override
     if isinstance(typ, Callable):
         self.check_func_def(defn, typ)
     else:
         raise RuntimeError('Not supported')
     
     if fdef:
         self.errors.set_function(None)
     
     self.dynamic_funcs.pop()
Пример #6
0
 Typ analyse_ref_expr(self, RefExpr e):
     Typ result
     node = e.node
     if isinstance(node, Var):
         # Variable or constant reference.
         v = (Var)node
         if not v.typ:
             # Implicit dynamic type.
             result = Any()
         else:
             # Local or global variable.
             result = v.typ.typ
     elif isinstance(node, FuncDef):
         # Reference to a global function.
         f = (FuncDef)node
         result = function_type(f)
     elif isinstance(node, OverloadedFuncDef):
         o = (OverloadedFuncDef)node
         result = o.typ.typ
     elif isinstance(node, TypeInfo):
         # Reference to a type object.
         result = self.type_object_type((TypeInfo)node)
     else:
         # Unknown reference; use dynamic type implicitly to avoid
         # generating extra type errors.
         result = Any()
     return result
 
 Typ analyse_direct_member_access(self, str name, TypeInfo info,
                                  bool is_lvalue, Context context):
     """Analyse direct member access via a name expression
Пример #7
0
bool is_simple_override(FuncDef fdef, TypeInfo info):
    """Is function an override with the same type precision as the original?
    
    Compare to the original method in the superclass of info.
    """
    # If this is not an override, this can't be a simple override either.
    # Generic inheritance is not currently supported, since we need to map
    # type variables between types; in the future this restriction can be
    # lifted.
    if info.base is None or info.base.type_vars != []:
        return False
    orig = info.base.get_method(fdef.name())
    # Ignore the first argument (self) when determining type sameness.
    # TODO overloads
    newtype = (Callable)function_type(fdef)
    newtype = replace_self_type(newtype, Any())
    origtype = (Callable)function_type(orig)
    origtype = replace_self_type(origtype, Any())
    return is_same_type(newtype, origtype)


str tvar_slot_name(int n, any is_alt=False):
    """Return the name of the member that holds the runtime value of the given
    type variable slot.
    """
    if is_alt != BOUND_VAR:
        if n == 0:
            return '__tv'
        else:
            return '__tv{}'.format(n + 1)