def instantiate_return(self, node, subst, sources): return_type = self.pytd_sig.return_type for param in pytd_utils.GetTypeParameters(return_type): if param.full_name in subst: # This value, which was instantiated by the matcher, will end up in the # return value. Since the matcher does not call __init__, we need to do # that now. node = self.vm.call_init(node, subst[param.full_name]) try: ret = self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) except self.vm.convert.TypeParameterError: # The return type contains a type parameter without a substitution. subst = subst.copy() visitor = visitors.CollectTypeParameters() return_type.Visit(visitor) for t in visitor.params: if t.full_name not in subst: subst[t.full_name] = self.vm.convert.empty.to_variable( node) return node, self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) if not ret.bindings and isinstance(return_type, pytd.TypeParameter): ret.AddBinding(self.vm.convert.empty, [], node) return node, ret
def instantiate_return(self, node, subst, sources): return_type = self.pytd_sig.return_type # Type parameter values, which are instantiated by the matcher, will end up # in the return value. Since the matcher does not call __init__, we need to # do that now. The one exception is that Type[X] does not instantiate X, so # we do not call X.__init__. if (not isinstance(return_type, pytd.GenericType) or return_type.base_type.name != "__builtin__.type"): for param in pytd_utils.GetTypeParameters(return_type): if param.full_name in subst: node = self.vm.call_init(node, subst[param.full_name]) try: ret = self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) except self.vm.convert.TypeParameterError: # The return type contains a type parameter without a substitution. subst = subst.copy() visitor = visitors.CollectTypeParameters() return_type.Visit(visitor) for t in visitor.params: if t.full_name not in subst: subst[t.full_name] = self.vm.convert.empty.to_variable( node) return node, self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) if not ret.bindings and isinstance(return_type, pytd.TypeParameter): ret.AddBinding(self.vm.convert.empty, [], node) return node, ret
def call_with_args(self, node, func, arg_dict, subst, ret_map, alias_map=None): """Call this signature. Used by PyTDFunction.""" return_type = self.pytd_sig.return_type t = (return_type, subst) sources = [func] + list(arg_dict.values()) if t not in ret_map: for param in pytd_utils.GetTypeParameters(return_type): if param.full_name in subst: # This value, which was instantiated by the matcher, will end up in # the return value. Since the matcher does not call __init__, we need # to do that now. node = self.vm.call_init(node, subst[param.full_name]) try: ret_map[t] = self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) except self.vm.convert.TypeParameterError: # The return type contains a type parameter without a substitution. subst = subst.copy() visitor = visitors.CollectTypeParameters() return_type.Visit(visitor) for t in visitor.params: if t.full_name not in subst: subst[t.full_name] = self.vm.convert.empty.to_variable( node) ret_map[t] = self.vm.convert.constant_to_var( abstract_utils.AsReturnValue(return_type), subst, node, source_sets=[sources]) else: if (not ret_map[t].bindings and isinstance(return_type, pytd.TypeParameter)): ret_map[t].AddBinding(self.vm.convert.empty, [], node) else: # add the new sources for data in ret_map[t].data: ret_map[t].AddBinding(data, sources, node) mutations = self._get_mutation(node, arg_dict, subst) self.vm.trace_call( node, func, (self, ), tuple(arg_dict[p.name] for p in self.pytd_sig.params), {}, ret_map[t]) return node, ret_map[t], mutations