-
Notifications
You must be signed in to change notification settings - Fork 851
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
Update static getProperty(Scriptable, Symbol) to no longer throw when not SymbolScriptable #1615
base: master
Are you sure you want to change the base?
Conversation
Think this needs some unit test |
Yes please...do it |
If this simplifies a bunch of other code, and it should, then this makes sense to me too. It's especially nice if we can avoid having JavaScript code break because some internal thing does not implement SymbolScriptable. |
Yep, in an interface the "public" is irrelevant and lots of times we leave
it out.
…On Wed, Sep 11, 2024 at 6:09 AM Tony Germano ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In rhino/src/main/java/org/mozilla/javascript/Scriptable.java
<#1615 (comment)>:
> @@ -33,10 +33,10 @@ public interface Scriptable {
*
* <p>See ECMA 8.6.2 and 15.2.4.2.
*/
- public String getClassName();
+ String getClassName();
From the Java Spec:
https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.4
A method in the body of an interface may be declared public or private (
§6.6
<https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-6.6>).
If no access modifier is given, the method is implicitly public. It is
permitted, but discouraged as a matter of style, to redundantly specify the
public modifier for a method declaration in an interface.
SymbolScriptable (a newer interface) already omitted the public
modifiers, but Scriptable did not. I was adding additional methods to
Scriptable and wanted to keep them consistent.
—
Reply to this email directly, view it on GitHub
<#1615 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAD7I22XPEP2WAZYHF3LRVDZWA6KFAVCNFSM6AAAAABN2XE6VCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDEOJWHE2TONBSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
interface methods are implicitly public and it is best practice to not explicitly specify public
It is already expected that objects which implement SymbolScriptable also implement Scriptable. Make this expectation enforced.
…Symbol-based method no longer throws Methods in ScriptableObject have been deprecated.
ScriptableObject.getProperty methods have been replaced by Scriptable.getProperty. Also remove redundant super interface Scriptable from classes which implement SymbolScriptable.
21281da
to
519cb58
Compare
After looking at this for a while, I determined the getProperty methods I moved actually implement the abstract operation |
I'm getting a little discouraged here discovering what most of you probably already knew about how much of the behavior for JS Objects is actually defined in the ScriptableObject class and the rest of the code's dependency on ScriptableObject. Our This is made apparent by the fact that js> Object.getOwnPropertyNames(new java.util.HashMap())
js: uncaught JavaScript runtime exception: TypeError: Expected argument of type object, but instead had type object
at (unknown):11 Our The So, I'm kind of stuck on how to move forward without breaking a bunch of stuff.
|
#1629 is another example I came across while looking into this where a method that should work on all Scriptables only works for ScriptableObjects. |
This is one of the challenges to tackle I guess, moving Rhino guard. I knew some of the issues, but you uncovered some more details 😛 I think we need some comprehensive plan to get to a s state we're happy with and the first step is determining what that state would look like The Scriptable interface was defined a long, long, long time ago, when JavaScript didn't have all the bells and whistles it has nowadays, but since it's a public API, we're stuck with it, unless we either able to polyfill in missing behaviour, so Scriptable implementations out there in the wild with automatically become compatible, or we introduce a (big) breaking change' Having said that, EcmaScript allows custom host objects that don't follow the 'rules' of EcmaScript On the flipside: what is a Scriptable that doesn't extend ScriptableObject or what is it not? It's a host object, exposing method and properties, but without PropertyDescriptors, so no way to freeze or seal, introspect the setup of the properties etc. So, on plain Scriptable implementations, one should be able to call Object.keys and Object.getOwnPropertyNames, but not the get/define propertyDescriptor(s) methods and the Object.freeze/seal method. Whether you can add me properties to a plain Scriptable implementation really depends on the implementation and thus not something Rhino can know. But I think that Rhino itself shouldn't create Scriptable that don't extend ScriptableObject: the NativeJavaXxxxc family could extend ScriptableObject I think and would be always sealed (cannot add/remove properties), support propertyDescriptors and thus could possibly be frozen We should make all relevant methods support non-ScriptableObject Scriptables and throw TypeErrors in others that cannot support plain Scriptables, when called on/with a plain Scriptable All this probably means moving some code around, branching in some method to properly deal with non-ScriptableObject Scriptables, but looking at it from s high level it seems doable to me |
I feel the pain about Scriptable and ScriptableObject! It's a big change for someone but if anyone is brave enough to write up a proposal I think that we should keep talking about it. |
While I'm on my soapbox about this, trying to use the same class (ScriptableObject) to represent both an object and also to represent the current scope has also seemed crazy to me and also inefficient. I've often thought about trying to break that apart but I'm not sure it's possible... |
Any updates on this? It seems like a nice way to clean up, if we can reconcile it with other things that people are doing. |
Opening this as a draft PR as a result of comment #1611 (comment) and the resulting discussion.
I made
SymbolScriptable
now extendScriptable
to enforce the assumption stated in the interface description that classes which implementSymbolScriptable
should also implementScriptable
. ASymbolScriptable
which isn't alsoScriptable
would be pretty useless. I have not run the full test suite yet, but this did not break anything during compilation.I moved the static
getProperty
methods which operate onScriptable
s and utilize only interface methods to theScriptable
interface itself fromScriptableObject
and deprecated them inScriptableObject
. It made more sense to me to locate them there, understanding that when these were originally written, interfaces did not support static methods.If everyone seems ok with this approach, I'll do the same to move additional static methods and update the calling references elsewhere in the code. I'll make similar adjustments to the symbol versions of the
hasProperty
andsetProperty
methods according to the previously mentioned discussion.