-
Notifications
You must be signed in to change notification settings - Fork 850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADD: ES6 Object.values / Object.entries / Object.fromEntries #902
Conversation
After deleting these lines, try running rhino/testsrc/test262.properties Lines 732 to 771 in b0fb5f8
rhino/testsrc/test262.properties Lines 826 to 841 in b0fb5f8
|
I could enable some of the tests. I also applied spotless in an extra commit. (is it correct, that spotless has to be applied on each modified file?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice progress
The JavaScript specification is defined in ECMA262. It is difficult to read ECMA262 right off the bat, so I recommend reading MDN first. |
Regarding spotless - yes every modified file needs spotless applied. Greg merges as soon as he finds the time for reviewing. It will be great if you like to work further on this making more test passing. |
Thanks for doing this! Now that we're getting better at doing this stuff, I'd prefer if we could first figure out if we can implement a feature with as many of the test262 tests passing as possible before merging it. Looking at the spec, Object.entries and Object.values are pretty straightforward and the implementation looks like it's probably pretty close. On the other hand, Object.fromEntries is one of those JS functions with a bunch of edge cases and things that have to be generalized. You might want to take a look at the implementation of Array.from, for example. One way I've found to figure out what I'm missing is to start with the V8 "mjsunit" test suite, and comment out things that don't work because other parts of the spec aren't implemented yet. For example: It's often more productive to get things working by running those tests over and over before trying to wade through test262. What would you think of just trying to finish "entries" and "values" to pass as many tests as we can and then tackling "fromEntries" separately? |
for (int i = 0; i < ids.length; i++) { | ||
if (ids[i] instanceof Integer) { | ||
Integer key = (Integer) ids[i]; | ||
ids[i] = cx.newArray(scope, new Object[]{ ids[i], obj.get(key, scope) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the first element of the new Array should be a String, even when you need the integer index to do the lookup. Have you thought about implementing the EnumerableOwnPropertyNames abstract method and using it for keys, entries, and values?
Looks like someone is waiting for this :-) |
So, I got all of the "entries" and "values" test working. Most of the "fromEntries" tests are using computed-properties like in this example: var iterable = {
[Symbol.iterator]: function() {
...
}
} Unfortunately, they are currently not yet parseable. I gave it a try in this commit 3756fa1 and extended the parser and codegenerators to handle computed properties. Somehow it seems to work, but I need help here because I'm not sure why ;) |
The fact that we don't have support for new syntax is a fine reason to disable some test262 tests. But if you have entries() and values() working I'll reiterate my suggestion that you put those in their own PR so that we can all look at it and possibly merge it. |
Why not also merge the fromEntries(). Most of the tests are passing - we have the same situation for other methods/tests. |
Btw: have done a test of this whole pr using it in HtmlUnit and it works great |
…ect.entries # Conflicts: # src/org/mozilla/javascript/NativeObject.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gbrail @rbri
I see, the "fromEntries" has a lot of edge cases and discovered other bugs or unimplemented features in rhino.
So I am also torn between leaving the code "as it ist" or remove "fromEntries" again.
Some of the test262 test cases I got working:
They require some special code, e.g. to check Symbol.toPrimitive
or if "key" is a function, that it is invoked.
I'm not sure, if this is a speciality of "fromEntries" or should be handled at some other place.
The other test cases often use "computed properties", so either the tests have to be rewritten or computed property support has to be added. I've done this in a very experimental commit
FOCONIS@98ef815
Are there plans, that computed-properties will be added? Maybe someone with more experience can take that commit as basis, as it will fix a lot of other testcases, too (See test262.properties
if (so.has(SymbolKey.TO_PRIMITIVE, so)) { | ||
key = so.get(SymbolKey.TO_PRIMITIVE, so); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge case? if object has Symbol.toPrimitive
-> take it.
Shouldn't this be handled by ScriptRuntime.toPrimitive
- respectively ScriptableObject.getDefaultValue
?
if (key instanceof Function) { | ||
Function fun = (Function)key; | ||
key = fun.call(cx, fun.getParentScope(), entry, ScriptRuntime.emptyArgs); | ||
Function fun = (Function) key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test fromEntries/evaluation-order.js
expects, that method is called.
Can someone point out, where this happens in https://tc39.es/ecma262/#sec-object.fromentries ?
as far as I understand, it calls CreateDataPropertyOnObject and then ToPropertyKey, which calls ToPrimitive
I assume it may happen in "ToPrimitive", but I use ScriptRuntime.toString(key)
which invokes ScriptabbleObject.getDefaultValue(String.class)
- so maybe there is an implementation error.
@@ -4291,23 +4291,29 @@ public static Scriptable newObjectLiteral( | |||
Object id = propertyIds[i]; | |||
int getterSetter = getterSetters == null ? 0 : getterSetters[i]; | |||
Object value = propertyValues[i]; | |||
if (id instanceof String) { | |||
if (id instanceof Symbol) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required to support arrays like this:
var key = Symbol();
var arr = [key, 'value'];
Object result = | ||
cx.evaluateString( | ||
scope, | ||
"var obj = {};" + "res = Object.assign(obj);" + "res === obj;", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does spotless mess this up?
@@ -740,35 +739,8 @@ built-ins/Object | |||
! fromEntries/iterator-not-closed-for-throwing-done-accessor.js | |||
! fromEntries/iterator-not-closed-for-throwing-next.js | |||
! fromEntries/iterator-not-closed-for-uncallable-next.js | |||
! fromEntries/key-order.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more of the from-entries tests are passing now. The other tests use "computed-properties" which are currently not supported.
If computed props were supported (or tests would be rewritten) only these tests would fail:
! fromEntries/iterator-closed-for-null-entry.js
! fromEntries/iterator-closed-for-string-entry.js
! fromEntries/iterator-closed-for-throwing-entry-key-accessor.js
! fromEntries/iterator-closed-for-throwing-entry-key-tostring.js
! fromEntries/iterator-closed-for-throwing-entry-value-accessor.js
which comes to my next question: How do you close an iterator?
Do we need something like ScriptRuntime.enumClose
beside enumInit
/ enumNext
I'm sorry that I didn't realize this sooner, but according to the spec, the basic algorithm for pulling items from the iterator and loading the object is the same basic algorithm (in the spec) as the constructors for Map and WeakMap objects. So, you can look at NativeMap's constructor, specifically the "loadFromIterable" function. You could possibly move that function somewhere else, like ScriptRuntime, and just use it -- it may do a lot of what you already need including closing the iterator. |
…ect.entries # Conflicts: # src/org/mozilla/javascript/ScriptRuntime.java
ScriptableObject dummy = ensureScriptableObject(cx.newObject(scope, map.getClassName())); | ||
final Callable set = | ||
ScriptRuntime.getPropFunctionAndThis(dummy.getPrototype(), "set", cx, scope); | ||
Scriptable proto = ScriptableObject.getClassPrototype(scope, map.getClassName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the only code change in this class.
I have changed this to getClassPrototype
instead of creating a dummy object and I reuse the code in
ScriptRuntime.loadFromIterable
int attrs = so.getAttributes((Symbol) arg); | ||
result = ((attrs & ScriptableObject.DONTENUM) == 0); | ||
} | ||
result = result && isEnumerable((Symbol) arg, thisObj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved code to "isEnumerable" method
} | ||
} else { | ||
ScriptableObject so = (ScriptableObject) object; | ||
Callable getterOrSetter = (Callable) value; | ||
boolean isSetter = getterSetter == 1; | ||
// XXX: Do we have to handle Symbol here. | ||
// This will be required, when conputedprops are supported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we need to check this. See FOCONIS@6d2a459
But I think this should be done in a separate PR
@gbrail Thanks for the hint. Maybe you can also take a look at this PR again. |
Thanks for cleaning this up. This looks good for now... However, we had a whole bunch of new formatting changes and this requires another merge. Can you please try to merge with the latest master and resolve conflicts? Thanks! |
…ect.entries # Conflicts: # src/org/mozilla/javascript/NativeMap.java
@gbrail Conflicts are solved and build is passing again |
Thanks a lot for all the work on this and all the others |
Thanks for working all that out! |
Adds the missing Object.values / Object.entries / Object.fromEntries methods.