1from __future__ import unicode_literals
2
3from ..conversions import *
4from ..func_utils import *
5
6# python 3 support
7import six
8if six.PY3:
9    basestring = str
10    long = int
11    xrange = range
12    unicode = str
13
14# todo fix apply and bind
15
16
17class FunctionPrototype:
18    def toString(this, args):
19        if not is_callable(this):
20            raise MakeError('TypeError',
21                            'Function.prototype.toString is not generic')
22
23        args = u', '.join(map(unicode, this.params))
24        return u'function %s(%s) { [native code] }' % (this.name if this.name
25                                                       else u'', args)
26
27    def call(this, args):
28        if not is_callable(this):
29            raise MakeError('TypeError',
30                            'Function.prototype.call is not generic')
31        _this = get_arg(args, 0)
32        _args = tuple(args)[1:]
33        return this.call(_this, _args)
34
35    def apply(this, args):
36        if not is_callable(this):
37            raise MakeError('TypeError',
38                            'Function.prototype.apply is not generic')
39        _args = get_arg(args, 1)
40        if not is_object(_args):
41            raise MakeError(
42                'TypeError',
43                'argList argument to Function.prototype.apply must an Object')
44        _this = get_arg(args, 0)
45        return this.call(_this, js_array_to_tuple(_args))
46
47    def bind(this, args):
48        if not is_callable(this):
49            raise MakeError('TypeError',
50                            'Function.prototype.bind is not generic')
51        bound_this = get_arg(args, 0)
52        bound_args = tuple(args)[1:]
53
54        def bound(dummy_this, extra_args):
55            return this.call(bound_this, bound_args + tuple(extra_args))
56
57        js_bound = args.space.NewFunction(bound, this.ctx, (), u'', False, ())
58        js_bound.put(u'length',
59                     float(max(len(this.params) - len(bound_args), 0.)))
60        js_bound.put(u'name', u'boundFunc')
61        return js_bound
62