102 lines
3.0 KiB
Python
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
|