Skip to content

Commit

Permalink
fixes: setProp, hasProperty/hasOwnProperty; update todo
Browse files Browse the repository at this point in the history
  • Loading branch information
sstur committed Jan 3, 2015
1 parent befe72a commit 8518b30
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 14 deletions.
5 changes: 0 additions & 5 deletions +todo.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use node-commander instead of yargs
json parse reviver
get/setters
'length' in [] even though it is a "computed property" in php-land
Object.getOwnPropertyDescriptor(array, 'length') //{value: 0, writable: true, enumerable: false, configurable: false}
new Func(function() {}) should use name where possible
fs: readStream encoding; createReadStream(directory) should throw

Expand All @@ -24,13 +21,11 @@ Transform:
Test:
function scope stuff including named function expression
for (i in array) {}
`Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };`
array set returns value
new Boolean().valueOf() === false
new Number().valueOf() === 0
parse `for (;;) {}`
support `string[1]`
date constructed with no args
Don't encode toString as $toString_
Unicode in strings
including surrogate pairs: "\uD835\uDFD8"
Expand Down
2 changes: 2 additions & 0 deletions php/classes/Array.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Arr extends Object {
function __construct() {
parent::__construct();
$this->proto = self::$protoObject;
//set a non-enumerable, non-configurable property descriptor for length
$this->setProp('length', null, true, false, false);
if (func_num_args() > 0) {
$this->init(func_get_args());
} else {
Expand Down
27 changes: 19 additions & 8 deletions php/classes/Object.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,16 @@ function remove($key) {
//determine if the given property exists (don't walk proto)
function hasOwnProperty($key) {
$key = (string)$key;
if (method_exists($this, 'get_' . $key)) {
return true;
}
return array_key_exists($key, $this->data);
}

//determine if the given property exists (walk proto)
function hasProperty($key) {
$key = (string)$key;
if (array_key_exists($key, $this->data)) {
if ($this->hasOwnProperty($key)) {
return true;
}
$proto = $this->proto;
Expand Down Expand Up @@ -143,7 +146,7 @@ function setProp($key, $value, $writable = null, $enumerable = null, $configurab
} else {
$result = new Descriptor(true, true, true);
}
//we don't care to check if it is configurable because we only use this method internally
//here we do NOT check if it is configurable (this method is only used internally)
if ($writable !== null) {
$result->writable = !!$writable;
}
Expand All @@ -157,7 +160,7 @@ function setProp($key, $value, $writable = null, $enumerable = null, $configurab
if (!$result->writable || !$result->enumerable || !$result->configurable) {
$this->dscr[$key] = $result;
}
//todo: check for set_x method
//here we do NOT check for a setter (this method is only used internally)
$this->data[$key] = $value;
return $value;
}
Expand Down Expand Up @@ -309,11 +312,16 @@ static function getDefault($value = null) {
if (!($obj instanceof Object)) {
throw new Ex(Error::create('Object.getOwnPropertyDescriptor called on non-object'));
}
//todo: get value (use get_x method when present)
$value = array_key_exists($key, $obj->data) ? $obj->data[$key] : null;
if (method_exists($obj, 'get_' . $key)) {
$hasProperty = true;
$value = $obj->{'get_' . $key}();
} else {
$hasProperty = array_key_exists($key, $obj->data);
$value = $hasProperty ? $obj->data[$key] : null;
}
if (array_key_exists($key, $obj->dscr)) {
return $obj->dscr[$key]->toObject($value);
} else if (array_key_exists($key, $obj->data)) {
} else if ($hasProperty) {
return Descriptor::getDefault($value);
} else {
return null;
Expand Down Expand Up @@ -362,8 +370,11 @@ static function getDefault($value = null) {
$updateValue = true;
}
if ($updateValue) {
//todo: check for set_x method
$obj->data[$key] = $value;
if (method_exists($obj, 'set_' . $key)) {
$obj->{'set_' . $key}($value);
} else {
$obj->data[$key] = $value;
}
}
},
'defineProperties' => function($obj, $items) {
Expand Down
6 changes: 5 additions & 1 deletion test/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ testSuite('array', function(assert) {

testSuite('constructor', function() {
var a = new Array(5);
assert('specify length', a.length === 5);
assert('length', a.length === 5);
assert('length property exists', 'length' in a);
var d = Object.getOwnPropertyDescriptor(a, 'length');
assert('length property exists', d.value === 5 && d.writable === true && d.enumerable === false && d.configurable === false);
assert('property names', Object.getOwnPropertyNames(a).join(',') === 'length');
assert('is empty', a.join('').length === 0);
var b = new Array('5');
assert('specify element', b.length === 1);
Expand Down

0 comments on commit 8518b30

Please sign in to comment.