183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Copyright 2006 Google, Inc. All Rights Reserved.
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Licensed to PSF under a Contributor Agreement.
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""Fixer for apply().
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehThis converts apply(func, v, k) into (func)(*v, **k)."""
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# Local imports
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom .. import pytree
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom ..pgen2 import token
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom .. import fixer_base
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom ..fixer_util import Call, Comma, parenthesize
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass FixApply(fixer_base.BaseFix):
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    BM_compatible = True
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    PATTERN = """
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    power< 'apply'
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        trailer<
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '('
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            arglist<
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                (not argument<NAME '=' any>) func=any ','
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                (not argument<NAME '=' any>) args=any [','
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                (not argument<NAME '=' any>) kwds=any] [',']
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            >
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ')'
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        >
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    >
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def transform(self, node, results):
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        syms = self.syms
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        assert results
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        func = results["func"]
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args = results["args"]
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        kwds = results.get("kwds")
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        prefix = node.prefix
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        func = func.clone()
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if (func.type not in (token.NAME, syms.atom) and
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            (func.type != syms.power or
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             func.children[-2].type == token.DOUBLESTAR)):
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Need to parenthesize
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            func = parenthesize(func)
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        func.prefix = ""
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args = args.clone()
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args.prefix = ""
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if kwds is not None:
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            kwds = kwds.clone()
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            kwds.prefix = ""
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l_newargs = [pytree.Leaf(token.STAR, u"*"), args]
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if kwds is not None:
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            l_newargs.extend([Comma(),
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              pytree.Leaf(token.DOUBLESTAR, u"**"),
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                              kwds])
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            l_newargs[-2].prefix = u" " # that's the ** token
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t)
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # can be translated into f(x, y, *t) instead of f(*(x, y) + t)
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #new = pytree.Node(syms.power, (func, ArgList(l_newargs)))
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        return Call(func, l_newargs, prefix=prefix)
60