2017-03-02 21:22:11 +01:00

102 lines
3.0 KiB
Python

from __future__ import unicode_literals
from types import FunctionType
from ...compat import compat_str
from . import undefined
from .jsobject import JSObjectPrototype
from .jsfunction import JSFunctionPrototype
from .jsarray import JSArrayPrototype
from .jsboolean import JSBooleanPrototype
from .jsstring import JSStringPrototype
from .jsnumber import JSNumberPrototype
class JSBase(object):
def __init__(self, name):
self.name = name
self.props = {}
own = {}
class JSProtoBase(JSBase):
def __init__(self):
super(JSProtoBase, self).__init__('')
cls = self.__class__
while cls.__base__ is not JSProtoBase:
cls = cls.__base__
props = cls.own.copy()
props.update(self.props)
self.props = props
self.value = {}
def get_prop(self, prop):
result = self.value.get(prop) if hasattr(self.value, 'get') else None
if result is None:
result = self.own.get(prop)
if result is None:
result = self.props.get(prop)
return result
def call_prop(self, prop, *args, **kwargs):
func = self.get_prop(prop)
if isinstance(func, native_function):
return func(self, *args, **kwargs)
elif isinstance(func, staticmethod):
return func.__func__(*args, **kwargs)
elif isinstance(func, classmethod):
return func.__func__(self.__class__, *args, **kwargs)
elif isinstance(func, JSBase) and hasattr(func, 'call'):
return func.call(*args, **kwargs)
else:
# FIXME instead of prop should return the whole expression
# needs to use internal exception
# interpreter should raise JSTypeError
raise Exception('TypeError: %s is not a function' % prop)
jsclass = ''
def _get_formal_args(func):
return func.__code__.co_varnames[func.__code__.co_argcount - len((func.__defaults__))]
def to_js(o, name=None):
if isinstance(o, JSProtoBase):
return o
elif o is None:
return undefined
elif isinstance(o, native_bool):
return JSBooleanPrototype(o)
elif isinstance(o, native_string):
return JSStringPrototype(o)
elif isinstance(o, native_number):
return JSNumberPrototype(o)
elif isinstance(o, native_object):
return JSObjectPrototype(o)
elif isinstance(o, native_function):
return JSFunctionPrototype(name, o, _get_formal_args(o))
elif isinstance(o, JSBase) and hasattr(o, 'call'):
return JSFunctionPrototype(o.name, o, _get_formal_args(o.call))
elif isinstance(o, native_array):
return JSArrayPrototype(o)
else:
raise Exception('Not allowed conversion %s to js' % type(o))
def js(func):
def wrapper(*args, **kwargs):
return to_js(*func(*args, **kwargs))
return wrapper
native_bool = bool
native_string = compat_str
native_number = (int, float)
native_object = dict
native_array = (list, tuple)
native_function = FunctionType