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
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)
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
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
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)