Skip to content
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

improve java.util.{List,Map} interop #713

Merged
merged 1 commit into from
Jun 19, 2020

Conversation

syjer
Copy link
Contributor

@syjer syjer commented Jun 15, 2020

Hi, this PR is based on #561 to improve the interoperability with java.util.List and java.util.Map.

As a main difference with #561, instead of creating 2 new wrapper, I've modified the NativeJavaObject class, as I think it's a little less disruptive and more easily reviewable.

It add some additional overhead (2 new boolean fields and some additional checks in has/get/put methods, but I would hope it's acceptable.

(Btw, I've noticed the travis build fail, but locally the tests passes)

@gbrail
Copy link
Collaborator

gbrail commented Jun 16, 2020

Thanks! I can see how this will be useful for people who embed Java in Rhino a lot.

Whenever I see a pattern in which we introduce a bunch of flags set in the constructor as "isThis" or "isThat", and then many methods start with "if (isThis) { do this } else if (isThat) { doThat }", I find myself asking, "would inheritance be a cleaner way to implement this?"

What if:

  1. You introduced two new subclasses of NativeObject called "NativeJavaList" and "NativeJavaArray" with the necessary specializations for each
  2. You modified ScriptRuntime.wrapAsJavaObject to test the class and create the appropriate form of the three subtypes.

I think this might also be handy someday because you could easily extend the pattern for other types of classes if people would like.

Would that be a painful change? I think it'd make things cleaner in the long run.

@syjer
Copy link
Contributor Author

syjer commented Jun 16, 2020

hi @gbrail , thank you for reviewing the PR :)

I find myself asking, "would inheritance be a cleaner way to implement this?"

Agree, I was a little bit unsure which approach would be more acceptable :).

Would that be a painful change? I think it'd make things cleaner in the long run.

not painful at all :), in fact I had the other variant in another branch (https://github.com/mozilla/rhino/compare/master...syjer:interop-java-list-map?expand=1) :). I'll take your feedback and incorporate the changes :)

@syjer
Copy link
Contributor Author

syjer commented Jun 16, 2020

by the way, by ScriptRuntime.wrapAsJavaObject you mean WrapFactory.wrapAsJavaObject right?

I can't find the method wrapAsJavaObject in ScriptRuntime.

@gbrail
Copy link
Collaborator

gbrail commented Jun 16, 2020 via email

@syjer
Copy link
Contributor Author

syjer commented Jun 17, 2020

I've updated the PR following your feedback :)

The tests run successfully locally too.

Copy link
Collaborator

@gbrail gbrail left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great. I have two minor suggestions -- if you like them, then please give them a try, and otherwise let me know if you'd rather not!

src/org/mozilla/javascript/NativeJavaList.java Outdated Show resolved Hide resolved
src/org/mozilla/javascript/NativeJavaMap.java Outdated Show resolved Hide resolved

@Override
public Object[] getIds() {
return map.keySet().toArray();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be over-complication but JavaScript has taught me to that anything is possible...

Is it possible that a user would use this with a map that has keys that are not strings or integers? If so, then it might aid interop with JavaScript if we iterated through the list and ensured that each key is either a string or an integer by calling ScriptRuntime.toInt32 or ScriptRuntime.toString depending on the type, and letting those methods throw a JavaScript exception if something doesn't work (for instance, if they try to use a Symbol or something).

Copy link
Contributor Author

@syjer syjer Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be over-complication but JavaScript has taught me to that anything is possible...

Haha, i feel your pain ;).

Is it possible that a user would use this with a map that has keys that are not strings or integers? If so, then it might aid interop with JavaScript if we iterated through the list and ensured that each key is either a string or an integer by calling ScriptRuntime.toInt32 or ScriptRuntime.toString depending on the type, and letting those methods throw a JavaScript exception if something doesn't work (for instance, if they try to use a Symbol or something).

Ok for ensuring the type :). I'll update the PR with your feedback. Thank you for your help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, what about filtering out non String/Integer keys instead of converting them?

@syjer
Copy link
Contributor Author

syjer commented Jun 18, 2020

I've updated the PR incorporating the feedback.

./gradlew check pass as expected.

(By the way, I noticed that running it with java 11 testsrc/tests/ecma_3/Date/15.9.5.5.js and string.trim.doctest fail: it's something that should be fixed?)

@gbrail
Copy link
Collaborator

gbrail commented Jun 18, 2020

This looks good now. Thanks!

@gbrail gbrail merged commit f2331c6 into mozilla:master Jun 19, 2020
@syjer
Copy link
Contributor Author

syjer commented Jun 19, 2020

thank you for guiding me in the process 👍

@gbrail
Copy link
Collaborator

gbrail commented Jun 19, 2020

Yes -- whatever is happening in Java 11 with the Date tests should be fixed. It's possible that Rhino's date handling is no longer valid in Java 11, but it's a lot more possible that the particular tests makes assumptions that are no longer valid and should be replaced by a new test.

@syjer
Copy link
Contributor Author

syjer commented Jun 19, 2020

ok, I'll have a look at the failing tests :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants