예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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