Overview
This PR does the following:
-
Proposes an implementation for
Reflect.ownKeys() -
WARNING: DO NOT MERGE. DOES NOT COMPILE. See following point.
-
For this implementation to compile, Rhino's
ScriptableObject.javaneeds a new method (e.g.getAllIdsIncludingSymbols()) that allows retrieval of all properties (enumerable or not not) including both strings and symbols:public Object[] getAllIdsIncludingSymbols() { return getIds(true, true); }
Test case
(This test case is also implemented in ReflectTest.java.)
var obj = { [Symbol.for('foo')]: 0, "str": 0, 773: 0, "55": 0, 0: 0, "-1": 0, 8: 0, "6": 8, [Symbol.for('bar')]: 0, "str2": 0, }; // Chrome: [ "0", "6", "8", "55", "773", "str", "-1", "str2", Symbol("foo"), Symbol("bar") ] // HtmlUnit: [ "-1", "0", "6", "8", "55", "773", "str", "str2", "Symbol(foo)", "Symbol(bar)" ] console.log(Reflect.ownKeys(obj));
Points of note
About the javadoc
The javadoc for ownKeys() is very basic because:
- We aren't sure if licensing allows us to copy mdn docs' words or whether we need to reword to our own words
- Perhaps writing fully descriptive API docs in the javadoc of these methods is not all that useful since they're JS methods, and a basic javadoc is easier to produce
Regarding the ordering of property keys returned
Notice -1 is in the wrong place.:
- Chrome:
[ "0", "6", "8", "55", "773", "str", "-1", "str2", Symbol("foo"), Symbol("bar") ] - HtmlUnit:
[ "-1", "0", "6", "8", "55", "773", "str", "str2", "Symbol(foo)", "Symbol(bar)" ]
The specs for Reflect.ownKeys() provide clear description for the ordering of these:
- Non-negative integer indexes in increasing numeric order (but as strings)
- Other string keys in the order of property creation
- Symbol keys in the order of property creation.
We cannot accommodate this for -1 and other negative integers because Rhino does not preserve the property creation order of negative integer keys. This appears to be a bug in Rhino:
- Rhino DOES preserve the property creation order of non-integer keys adhering to specs
- Rhino DOES orders "positive integer" keys in canonical order adhering to specs
- Rhino DOES NOT preserve the property creation order of "negative integer" since it seems to be incorrectly treating these as an integer index even though they're not in the defined range of
0 <= i <= F[1]
[1] https://262.ecma-international.org/13.0/#sec-object-type
Regarding the initialization of the test case
var obj = { [Symbol.for('foo')]: 0, "str": 0, 773: 0, ... };
HtmlUnit throws invalid property id error on the [Symbol.for('foo')] part which is a computed property name. The object is instead initialized in ReflectTest.java as such:
var obj = {}; obj[Symbol.for('foo')] = 0; obj['str'] = 0; obj[773] = 0; obj["55"] = 0; obj[0] = 0; obj['-1'] = 0; obj[8] = 0; obj["6"] = 0; obj[Symbol.for('bar')] = 0; obj['str2'] = 0;