[jsbuilt-ins] String mock up Function constructor fix, to_string placeholder

limits js wrapper
This commit is contained in:
sulyi 2017-01-28 20:32:08 +01:00
parent a500c34cbd
commit 598f5f227a

View File

@ -63,6 +63,10 @@ def to_object(o):
return o
def to_string(value):
return value
class JSBase(object):
def __init__(self, name):
@ -87,29 +91,24 @@ class JSProtoBase(JSBase):
def __str__(self):
return ''
def __get_prop(self, prop):
result = self.value.get(prop)
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
@js
def get_prop(self, prop):
return self.__get_prop(prop), prop
@js
def call_prop(self, prop, *args, **kwargs):
func = self.__get_prop(prop)
if isinstance(func, FunctionType):
return func(self, *args, **kwargs), prop
func = self.get_prop(prop)
if isinstance(func, _native_function):
return func(self, *args, **kwargs)
elif isinstance(func, staticmethod):
return func.__func__(*args, **kwargs), prop
return func.__func__(*args, **kwargs)
elif isinstance(func, classmethod):
return func.__func__(self.__class__, *args, **kwargs), prop
return func.__func__(self.__class__, *args, **kwargs)
elif isinstance(func, JSBase) and hasattr(func, 'call'):
return func.call(*args, **kwargs), prop
return func.call(*args, **kwargs)
else:
# FIXME instead of prop should return the whole expression
# needs to use internal exception
@ -125,13 +124,7 @@ class JSObjectPrototype(JSProtoBase):
@staticmethod
def _constructor(value=None):
value = _to_js(value)
if value is undefined or value is null:
return JSObjectPrototype()
elif isinstance(value, JSObjectPrototype):
return value
elif isinstance(value, (JSStringPrototype, JSNumberPrototype, JSBooleanPrototype)):
return to_object(value)
return JSObject.construct(value)
def _to_string(self):
return 'object to string'
@ -168,12 +161,21 @@ class JSObject(JSBase):
super(JSObject, self).__init__(self.name)
@staticmethod
def construct(value=None):
return JSObjectPrototype._constructor(value)
def call(value=None):
if value is null or value is undefined or value is None:
return JSObject.construct(value)
return to_object(_to_js(value))
@staticmethod
def call(value=None):
return JSObject.construct(value)
def construct(value=None):
value = _to_js(value)
# TODO set [[Prototype]], [[Class]], [[Extensible]], internal methods
if value is undefined or value is null:
return JSObjectPrototype()
elif isinstance(value, JSObjectPrototype):
return value
elif isinstance(value, (JSStringPrototype, JSNumberPrototype, JSBooleanPrototype)):
return to_object(value)
def _get_prototype_of(self, o):
return 'object get prototype of'
@ -181,6 +183,7 @@ class JSObject(JSBase):
def _get_own_property_descriptor(self, o, p):
return 'object desc'
@js
def _get_own_property_names(self, o):
return list(o.own.keys())
@ -236,8 +239,8 @@ class JSObject(JSBase):
class JSFunctionPrototype(JSObjectPrototype):
def __init__(self, name, body, arguments):
if name is None and body is None and arguments is None:
def __init__(self, name, body, formal_args):
if name is None and body is None and formal_args is None:
# prototype
super(JSFunctionPrototype, self).__init__()
self.f_name = ''
@ -251,10 +254,10 @@ class JSFunctionPrototype(JSObjectPrototype):
self.body = '[native code]'
else:
super(JSFunctionPrototype, self).__init__()
body = _to_js(name, body)
body = _to_js(body)
self.body = body.call_prop('toString') if body is not undefined or body is not null else ''
self.f_name = name
self.arguments = list(arguments)
self.arguments = list(formal_args)
# FIXME: JSProtoBase sets body to '' instead of None
# TODO check if self._args can be parsed as formal parameter list
# TODO check if self._body can be parsed as function body
@ -269,13 +272,7 @@ class JSFunctionPrototype(JSObjectPrototype):
@staticmethod
def _constructor(arguments=None):
if arguments is None:
body = ''
arguments = []
else:
body = arguments[-1] if arguments else ''
arguments = arguments[:-1]
return JSFunctionPrototype('anonymous', body, arguments)
return JSFunction.construct(arguments)
def _to_string(self):
if self.body is not None:
@ -310,12 +307,18 @@ class JSFunctionPrototype(JSObjectPrototype):
class JSFunction(JSObject):
@staticmethod
def construct(*args, **kwargs):
return JSFunctionPrototype._constructor(*args)
def call(formal_args=None):
return JSFunction.construct(formal_args)
@staticmethod
def call(*args, **kwargs):
return JSFunction.construct(*args, **kwargs)
def construct(formal_args=None):
if formal_args is None:
body = ''
formal_args = []
else:
body = formal_args[-1] if formal_args else ''
formal_args = formal_args[:-1]
return JSFunctionPrototype('anonymous', body, formal_args)
name = 'Function'
own = {
@ -326,13 +329,10 @@ class JSFunction(JSObject):
class JSArrayPrototype(JSObjectPrototype):
def __init__(self, value=None, length=0):
def __init__(self, value=None):
super(JSArrayPrototype, self).__init__()
self.value = [] if value is None else value
@property
def _length(self):
return len(self.value)
self.value = [] if value is None else list(value)
self.own = {'length': self._length}
def __str__(self):
return 'JSArrayPrototype: %s' % self.value
@ -340,11 +340,13 @@ class JSArrayPrototype(JSObjectPrototype):
def __repr__(self):
return 'JSArrayPrototype(%s, %s)' % (self.value, self._length)
@property
def _length(self):
return len(self.value)
@staticmethod
def _constructor(value=None):
array = JSArrayPrototype(value)
array.own = {'length': array._length}
return array
def _constructor(*args):
return JSArray.construct(*args)
def _to_string(self):
return 'array to string'
@ -412,7 +414,7 @@ class JSArrayPrototype(JSObjectPrototype):
return 'array reduce right'
own = {
'length': 0,
'length': _length,
'constructor': _constructor,
'toString': _to_string,
'toLocaleString': _to_locale_string,
@ -440,6 +442,22 @@ class JSArrayPrototype(JSObjectPrototype):
class JSArray(JSObject):
@staticmethod
def call(*args):
return JSArray.construct(*args)
@staticmethod
def construct(*args):
if len(args) == 1:
if isinstance(args[0], _native_number):
return JSArrayPrototype([undefined] * args[0])
elif isinstance(args[0], JSNumberPrototype):
return JSArrayPrototype([undefined] * args[0]._value_of())
if args:
return JSArrayPrototype(args)
else:
return JSArrayPrototype()
def _is_array(self, arg):
return 'array is array'
@ -452,11 +470,123 @@ class JSArray(JSObject):
class JSStringPrototype(JSObjectPrototype):
pass
def __init__(self, value=None):
if value is None:
# prototype
value = ''
super(JSStringPrototype, self).__init__(value)
@property
def _length(self):
return len(self.value)
@staticmethod
def _constructor(value=None):
return JSString.construct(value)
def _to_string(self):
return self.value
def _value_of(self):
return self.value
def _char_at(self, pos):
return 'string char at'
def _char_code_at(self, pos):
return 'string char code at'
def _concat(self, *args):
return 'string concat'
def _index_of(self, search, pos):
return 'string index of'
def _last_index_of(self, search, pos):
return 'string last index of'
def _locale_compare(self, that):
return 'string locale compare'
def _match(self, regexp):
return 'string match'
def _replace(self, search, value):
return 'string replace'
def _search(self, regexp):
return 'string search'
def _slice(self, start, end):
return 'string slice'
def _split(self, sep):
return 'string split'
def _substring(self, start, end):
return 'string substring'
def _to_lower_case(self):
return 'string to lower case'
def _to_local_lower_case(self):
return 'string to local lower case'
def _to_upper_case(self):
return 'string to upper case'
def _to_local_upper_case(self):
return 'string to local upper case'
def _trim(self):
return 'string trim'
own = {
'length': _length,
'constructor': _constructor,
'toString': _to_string,
'valueOf': _value_of,
'charAt': _char_at,
'charCodeAt': _char_code_at,
'concat': _concat,
'indexOf': _index_of,
'lastIndexOf': _last_index_of,
'localeCompare': _locale_compare,
'match': _match,
'replace': _replace,
'search': _search,
'slice': _slice,
'split': _split,
'substring': _substring,
'toLowerCase': _to_lower_case,
'toLocalLowerCase': _to_local_lower_case,
'toUpperCase': _to_upper_case,
'toLocalUpperCase': _to_local_upper_case,
'trim': _trim
}
class JSString(JSObject):
pass
@staticmethod
def call(value=None):
return '' if value is None else to_string(value)
@staticmethod
def construct(value=None):
return JSStringPrototype('' if value is None else to_string(value))
def _from_char_code(self, *args):
return 'String from char code'
name = 'String'
own = {
'length': 1,
'prototype': JSStringPrototype(),
'fromCharCode': _from_char_code
}
class JSBooleanPrototype(JSObjectPrototype):
@ -499,4 +629,6 @@ _object_type = object()
global_obj = JSObject.construct({'Object': JSObject(),
'Array': JSArray(),
'Function': JSFunction()})
'Function': JSFunction(),
'String': JSString()
})