[jsbuilt-ins] fixing constructors
This commit is contained in:
parent
4d386f0273
commit
0136be4a19
@ -60,6 +60,10 @@ class JSProtoBase(JSBase):
|
|||||||
jsclass = ''
|
jsclass = ''
|
||||||
|
|
||||||
|
|
||||||
|
def _get_formal_args(func):
|
||||||
|
return func.__code__.co_varnames[func.__code__.co_argcount - len((func.__defaults__))]
|
||||||
|
|
||||||
|
|
||||||
def to_js(o, name=None):
|
def to_js(o, name=None):
|
||||||
if isinstance(o, JSProtoBase):
|
if isinstance(o, JSProtoBase):
|
||||||
return o
|
return o
|
||||||
@ -74,9 +78,9 @@ def to_js(o, name=None):
|
|||||||
elif isinstance(o, native_object):
|
elif isinstance(o, native_object):
|
||||||
return JSObjectPrototype(o)
|
return JSObjectPrototype(o)
|
||||||
elif isinstance(o, native_function):
|
elif isinstance(o, native_function):
|
||||||
return JSFunctionPrototype(name, o, [])
|
return JSFunctionPrototype(name, o, _get_formal_args(o))
|
||||||
elif isinstance(o, JSBase) and hasattr(o, 'call'):
|
elif isinstance(o, JSBase) and hasattr(o, 'call'):
|
||||||
return JSFunctionPrototype(o.name, o, [])
|
return JSFunctionPrototype(o.name, o, _get_formal_args(o.call))
|
||||||
elif isinstance(o, native_array):
|
elif isinstance(o, native_array):
|
||||||
return JSArrayPrototype(o)
|
return JSArrayPrototype(o)
|
||||||
else:
|
else:
|
||||||
|
@ -12,6 +12,13 @@ from .jsstring import JSStringPrototype
|
|||||||
from .jsnumber import JSNumberPrototype
|
from .jsnumber import JSNumberPrototype
|
||||||
from ..jsgrammar import __HEXADECIMAL_RE
|
from ..jsgrammar import __HEXADECIMAL_RE
|
||||||
|
|
||||||
|
undefined_type = object()
|
||||||
|
null_type = object()
|
||||||
|
boolean_type = object()
|
||||||
|
string_type = object()
|
||||||
|
number_type = object()
|
||||||
|
object_type = object()
|
||||||
|
|
||||||
|
|
||||||
def jstype(o):
|
def jstype(o):
|
||||||
if o is undefined:
|
if o is undefined:
|
||||||
@ -189,9 +196,6 @@ def to_object(o):
|
|||||||
return o
|
return o
|
||||||
|
|
||||||
|
|
||||||
undefined_type = object()
|
def throw_type_error():
|
||||||
null_type = object()
|
# TODO [[ThrowTypeError]] (13.2.3)
|
||||||
boolean_type = object()
|
pass
|
||||||
string_type = object()
|
|
||||||
number_type = object()
|
|
||||||
object_type = object()
|
|
||||||
|
@ -10,8 +10,13 @@ class JSArrayPrototype(JSObjectPrototype):
|
|||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
super(JSArrayPrototype, self).__init__()
|
super(JSArrayPrototype, self).__init__()
|
||||||
self.value = [] if value is None else list(value)
|
if value is None:
|
||||||
self.own = {'length': self._length}
|
# prototype
|
||||||
|
self.value = []
|
||||||
|
else:
|
||||||
|
self.value = value
|
||||||
|
self.own = dict((str(i), v) for i, v in enumerate(value))
|
||||||
|
self.own['length'] = self._length
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'JSArrayPrototype: %s' % self.value
|
return 'JSArrayPrototype: %s' % self.value
|
||||||
@ -136,7 +141,7 @@ class JSArray(JSObject):
|
|||||||
if args:
|
if args:
|
||||||
return JSArrayPrototype(args)
|
return JSArrayPrototype(args)
|
||||||
else:
|
else:
|
||||||
return JSArrayPrototype()
|
return JSArrayPrototype([])
|
||||||
|
|
||||||
def _is_array(self, arg):
|
def _is_array(self, arg):
|
||||||
return 'array is array'
|
return 'array is array'
|
||||||
|
@ -9,10 +9,13 @@ from .jsobject import JSObject, JSObjectPrototype
|
|||||||
class JSBooleanPrototype(JSObjectPrototype):
|
class JSBooleanPrototype(JSObjectPrototype):
|
||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
|
super(JSBooleanPrototype, self).__init__()
|
||||||
if value is None:
|
if value is None:
|
||||||
# prototype
|
# prototype
|
||||||
value = False
|
value = False
|
||||||
super(JSBooleanPrototype, self).__init__(value)
|
else:
|
||||||
|
self.value = value
|
||||||
|
self.own = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _constructor(value=None):
|
def _constructor(value=None):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from . import undefined, null
|
from . import undefined, null
|
||||||
from .internals import to_string
|
from .internals import to_string, throw_type_error
|
||||||
from .base import to_js, native_function, JSBase
|
from .base import to_js, native_function, JSBase
|
||||||
from .jsobject import JSObject, JSObjectPrototype
|
from .jsobject import JSObject, JSObjectPrototype
|
||||||
|
|
||||||
@ -27,6 +27,17 @@ class JSFunctionPrototype(JSObjectPrototype):
|
|||||||
self.body = to_string(body) if body is not undefined or body is not null else ''
|
self.body = to_string(body) if body is not undefined or body is not null else ''
|
||||||
self.f_name = name
|
self.f_name = name
|
||||||
self.arguments = list(formal_args)
|
self.arguments = list(formal_args)
|
||||||
|
proto = JSObject.construct()
|
||||||
|
proto.own['constructor'] = self
|
||||||
|
self.own = {'length': self._length,
|
||||||
|
'prototype': proto
|
||||||
|
}
|
||||||
|
# TODO Handle strict mode
|
||||||
|
strict = True
|
||||||
|
if strict:
|
||||||
|
thrower = throw_type_error
|
||||||
|
self.own['caller'] = thrower
|
||||||
|
self.own['arguments'] = thrower
|
||||||
# FIXME: JSProtoBase sets body to '' instead of None
|
# FIXME: JSProtoBase sets body to '' instead of None
|
||||||
# TODO check if self._args can be parsed as formal parameter list
|
# TODO check if self._args can be parsed as formal parameter list
|
||||||
# TODO check if self._body can be parsed as function body
|
# TODO check if self._body can be parsed as function body
|
||||||
@ -36,8 +47,7 @@ class JSFunctionPrototype(JSObjectPrototype):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _length(self):
|
def _length(self):
|
||||||
# Yeesh, I dare you to find anything like that in the python specification.
|
return len(self.arguments)
|
||||||
return len([arg for arg, init in self.arguments if init is not None])
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _constructor(arguments=None):
|
def _constructor(arguments=None):
|
||||||
@ -51,7 +61,7 @@ class JSFunctionPrototype(JSObjectPrototype):
|
|||||||
body = ''
|
body = ''
|
||||||
return 'function %s(%s) {%s\n}' % (
|
return 'function %s(%s) {%s\n}' % (
|
||||||
self.f_name,
|
self.f_name,
|
||||||
', '.join(arg if init is None else arg + '=' + init for arg, init in self.arguments),
|
', '.join(self.arguments),
|
||||||
body)
|
body)
|
||||||
|
|
||||||
def _apply(self, this_arg, arg_array):
|
def _apply(self, this_arg, arg_array):
|
||||||
@ -82,12 +92,14 @@ class JSFunction(JSObject):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def construct(formal_args=None):
|
def construct(formal_args=None):
|
||||||
if formal_args is None:
|
if formal_args is not None and formal_args:
|
||||||
|
body = formal_args[-1]
|
||||||
|
formal_args = []
|
||||||
|
for arg in formal_args[:-1]:
|
||||||
|
formal_args.extend(a.strip() for a in arg.split(','))
|
||||||
|
else:
|
||||||
body = ''
|
body = ''
|
||||||
formal_args = []
|
formal_args = []
|
||||||
else:
|
|
||||||
body = formal_args[-1] if formal_args else ''
|
|
||||||
formal_args = formal_args[:-1]
|
|
||||||
return JSFunctionPrototype('anonymous', body, formal_args)
|
return JSFunctionPrototype('anonymous', body, formal_args)
|
||||||
|
|
||||||
name = JSFunctionPrototype.jsclass
|
name = JSFunctionPrototype.jsclass
|
||||||
|
@ -7,6 +7,15 @@ from .jsobject import JSObject, JSObjectPrototype
|
|||||||
|
|
||||||
class JSNumberPrototype(JSObjectPrototype):
|
class JSNumberPrototype(JSObjectPrototype):
|
||||||
|
|
||||||
|
def __init__(self, value=None):
|
||||||
|
super(JSNumberPrototype, self).__init__()
|
||||||
|
if value is None:
|
||||||
|
# prototype
|
||||||
|
value = 0
|
||||||
|
else:
|
||||||
|
self.value = value
|
||||||
|
self.own = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _constructor(value=None):
|
def _constructor(value=None):
|
||||||
return JSNumber.construct(value)
|
return JSNumber.construct(value)
|
||||||
|
@ -12,7 +12,9 @@ class JSObjectPrototype(JSProtoBase):
|
|||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
super(JSObjectPrototype, self).__init__()
|
super(JSObjectPrototype, self).__init__()
|
||||||
self.value = {} if value is None else value
|
if value is not None:
|
||||||
|
self.props.update(self.own)
|
||||||
|
self.own = self.value = value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _constructor(value=None):
|
def _constructor(value=None):
|
||||||
@ -64,7 +66,7 @@ class JSObject(JSBase):
|
|||||||
value = to_js(value)
|
value = to_js(value)
|
||||||
# TODO set [[Prototype]], [[Class]], [[Extensible]], internal methods
|
# TODO set [[Prototype]], [[Class]], [[Extensible]], internal methods
|
||||||
if value is undefined or value is null:
|
if value is undefined or value is null:
|
||||||
return JSObjectPrototype()
|
return JSObjectPrototype({})
|
||||||
elif isinstance(value, JSObjectPrototype):
|
elif isinstance(value, JSObjectPrototype):
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, (JSStringPrototype, JSNumberPrototype, JSBooleanPrototype)):
|
elif isinstance(value, (JSStringPrototype, JSNumberPrototype, JSBooleanPrototype)):
|
||||||
|
@ -7,10 +7,13 @@ from .jsobject import JSObject, JSObjectPrototype
|
|||||||
class JSStringPrototype(JSObjectPrototype):
|
class JSStringPrototype(JSObjectPrototype):
|
||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
|
super(JSStringPrototype, self).__init__()
|
||||||
if value is None:
|
if value is None:
|
||||||
# prototype
|
# prototype
|
||||||
value = ''
|
value = ''
|
||||||
super(JSStringPrototype, self).__init__(value)
|
else:
|
||||||
|
self.value = value
|
||||||
|
self.own = {'length': self._length}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _length(self):
|
def _length(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user