Exemple #1
0
def coerce(expr: Node,
           target_type: Type,
           source_type: Type,
           context: TypeInfo,
           is_wrapper_class: bool = False,
           is_java: bool = False) -> Node:
    """Build an expression that coerces expr from source_type to target_type.

    Return bare expr if the coercion is trivial (always a no-op).
    """
    if is_trivial_coercion(target_type, source_type, is_java):
        res = expr
    else:
        # Translate type variables to expressions that fetch the value of a
        # runtime type variable.
        target = translate_runtime_type_vars_in_context(
            target_type, context, is_java)
        source = translate_runtime_type_vars_in_context(
            source_type, context, is_java)
        res = CoerceExpr(expr, target, source, is_wrapper_class)

    if is_java and (
        (isinstance(source_type, Instance) and
         (cast(Instance, source_type)).erased) or
        (isinstance(res, CoerceExpr) and isinstance(target_type, Instance))):
        res = JavaCast(res, target_type)

    return res
Exemple #2
0
 def coerce_to_dynamic(self, expr: Node, source_type: Type,
                       context: TypeInfo) -> Node:
     if isinstance(source_type, AnyType):
         return expr
     source_type = translate_runtime_type_vars_in_context(
         source_type, context, self.is_java)
     return CoerceExpr(expr, AnyType(), source_type, False)
Exemple #3
0
 def coerce_to_dynamic(self, expr: Node, source_type: Type,
                       context: TypeInfo) -> Node:
     if isinstance(source_type, AnyType):
         return expr
     source_type = translate_runtime_type_vars_in_context(
         source_type, context, self.is_java)
     return CoerceExpr(expr, AnyType(), source_type, False)
Exemple #4
0
def coerce(expr, target_type, source_type, context, is_wrapper_class=False, is_java=False):
    """Build an expression that coerces expr from source_type to target_type.

    Return bare expr if the coercion is trivial (always a no-op).
    """
    if is_trivial_coercion(target_type, source_type, is_java):
        res = expr
    else:
        # Translate type variables to expressions that fetch the value of a
        # runtime type variable.
        target = translate_runtime_type_vars_in_context(target_type, context,
                                                        is_java)
        source = translate_runtime_type_vars_in_context(source_type, context,
                                                        is_java)
        res = CoerceExpr(expr, target, source, is_wrapper_class)
    
    if is_java and ((isinstance(source_type, Instance) and
                     (source_type).erased)
                    or (isinstance(res, CoerceExpr) and
                        isinstance(target_type, Instance))):
        res = JavaCast(res, target_type)
    
    return res                  
Exemple #5
0
    def visit_call_expr(self, e: CallExpr) -> None:
        if e.analyzed:
            # This is not an ordinary call.
            e.analyzed.accept(self)
            return

        super().visit_call_expr(e)

        # Do no coercions if this is a call to debugging facilities.
        if self.is_debugging_call_expr(e):
            return

        # Get the type of the callable (type variables in the context of the
        # enclosing class).
        ctype = self.get_type(e.callee)

        # Add coercions for the arguments.
        for i in range(len(e.args)):
            arg_type = AnyType()  # type: Type
            if isinstance(ctype, Callable):
                arg_type = ctype.arg_types[i]
            e.args[i] = self.coerce2(e.args[i], arg_type,
                                     self.get_type(e.args[i]),
                                     self.type_context())

        # Prepend type argument values to the call as needed.
        if isinstance(ctype, Callable) and cast(Callable,
                                                ctype).bound_vars != []:
            bound_vars = (cast(Callable, ctype)).bound_vars

            # If this is a constructor call (target is the constructor
            # of a generic type or superclass __init__), include also
            # instance type variables.  Otherwise filter them away --
            # include only generic function type variables.
            if (not (cast(Callable, ctype)).is_type_obj() and
                    not (isinstance(e.callee, SuperExpr) and
                         (cast(SuperExpr, e.callee)).name == '__init__')):
                # Filter instance type variables; only include function tvars.
                bound_vars = [(id, t) for id, t in bound_vars if id < 0]

            args = []  # type: List[Node]
            for i in range(len(bound_vars)):
                # Compile type variables to runtime type variable expressions.
                tv = translate_runtime_type_vars_in_context(
                    bound_vars[i][1],
                    self.type_context(),
                    self.is_java)
                args.append(TypeExpr(tv))
            e.args = args + e.args
Exemple #6
0
    def visit_call_expr(self, e: CallExpr) -> None:
        if e.analyzed:
            # This is not an ordinary call.
            e.analyzed.accept(self)
            return

        super().visit_call_expr(e)

        # Do no coercions if this is a call to debugging facilities.
        if self.is_debugging_call_expr(e):
            return

        # Get the type of the callable (type variables in the context of the
        # enclosing class).
        ctype = self.get_type(e.callee)

        # Add coercions for the arguments.
        for i in range(len(e.args)):
            arg_type = AnyType()  # type: Type
            if isinstance(ctype, Callable):
                arg_type = ctype.arg_types[i]
            e.args[i] = self.coerce2(e.args[i], arg_type,
                                     self.get_type(e.args[i]),
                                     self.type_context())

        # Prepend type argument values to the call as needed.
        if isinstance(ctype,
                      Callable) and cast(Callable, ctype).bound_vars != []:
            bound_vars = (cast(Callable, ctype)).bound_vars

            # If this is a constructor call (target is the constructor
            # of a generic type or superclass __init__), include also
            # instance type variables.  Otherwise filter them away --
            # include only generic function type variables.
            if (not (cast(Callable, ctype)).is_type_obj()
                    and not (isinstance(e.callee, SuperExpr) and
                             (cast(SuperExpr, e.callee)).name == '__init__')):
                # Filter instance type variables; only include function tvars.
                bound_vars = [(id, t) for id, t in bound_vars if id < 0]

            args = []  # type: List[Node]
            for i in range(len(bound_vars)):
                # Compile type variables to runtime type variable expressions.
                tv = translate_runtime_type_vars_in_context(
                    bound_vars[i][1], self.type_context(), self.is_java)
                args.append(TypeExpr(tv))
            e.args = args + e.args
Exemple #7
0
 def coerce_to_dynamic(self, expr, source_type, context):
     if isinstance(source_type, Any):
         return expr
     source_type = translate_runtime_type_vars_in_context(
         source_type, context, self.is_java)
     return CoerceExpr(expr, Any(), source_type, False)