Replies: 1 comment
-
RE: Enum instance method support? Instance methods are allowed treated as if they were @JsOVerlay. That is possible because it is guaranteed that there are no subclasses of the particular enum and because JsEnums are not allowed to implement interfaces. The only potentially polymorphic methods are those inherited from Object or Enum. The ones from Enum are actually final and special cased (ordinal is only allowed on non custom valued enums, name is disallowed in all, etc). I don't recall which approach we took for Object, but those are trampolines to handle JS values, but we could be boxing also, not sure. Re: Extends Enum Enum.valueOf is not supported in J2CL for any Enum. The reason being is that using value of would prevent stripping of unused Enum values. Re: Boxing |
Beta Was this translation helpful? Give feedback.
-
The Javadoc for JsEnum specifically calls out that this is only implemented in J2CL, but omits some specific decisions that the J2CL implementation made. I've spent a few hours this weekend trying to build the same feature in GWT2, and my experience with JsEnum in J2CL is quite limited, so I was surprised by some of these decisions.
I went a little deeper into J2CL, reading docs, tests, and implementation specifics, and have found myself with many questions that possibly should go into the JsEnum javaodc, and possibly somewhere more like the J2CL docs where those decisions were deliberately unspec'd by jsinterop-annotations. I'm happy to try to make those changes myself, but the line of where some of them ought to end up isn't always clear.
I posted this originally as Q&A, but it could easily fall under another category, or possible even as a set of bugs? Please direct me if there is a better way to handle this.
Comparable
The Javadoc for JsInteropRestrictionsChecker includes this block:
j2cl/transpiler/java/com/google/j2cl/transpiler/passes/JsInteropRestrictionsChecker.java
Lines 294 to 313 in 0e13b9a
The truth table suggests that ordinal() and Comparable should both only function for JsEnums with
hasCustomValue=false
. However, the tests in https://github.com/google/j2cl/blob/0e13b9a49b68b8f048734b2330cbdfcd89681972/transpiler/javatests/com/google/j2cl/integration/java/jsenum/Main.java seem to disagree with that -StringNativeEnum
as the name implies is both a native JsEnum and has a String custom value, but tests confirm that instances correctly implementComparable
:j2cl/transpiler/javatests/com/google/j2cl/integration/java/jsenum/Main.java
Lines 213 to 219 in 0e13b9a
Both implementations of JsInteropUtils agree with the tests, rather than the documentation:
j2cl/transpiler/java/com/google/j2cl/transpiler/frontend/jdt/JsInteropUtils.java
Lines 100 to 101 in 0e13b9a
j2cl/transpiler/java/com/google/j2cl/transpiler/frontend/javac/JsInteropUtils.java
Lines 100 to 101 in 0e13b9a
I added the "supports ordinal" line in both to contrast with the truth table showing that they follow the same logic.
Boxing
It appears that in j2cl, an enum can be "boxed", where the underlying number/string/boolean is wrapped in an object. Among other things, this makes it possible to tell that an enum cast to Object is not an instanceof Double/String/Boolean, but is only an instance of its own class. This does have the tradeoff that most generic jsinterop-annotated methods will break when given a JsEnum - consider for example a
JsArray<MyEnum>
, where you callJsArray.of(MyEnum.FOO, MyEnum.BAR)
, or usearr.push(MyEnum.FOO)
to populate the collection before returning it to JS.(Additionally, arrays of enums aren't supported, so this example can't have a "JsArray vs MyEnum[]" compare/contrast.)
Is there a way to unbox consistently to avoid this issue? Generated
.impl.java.js
forMyEnum getValue()
andJsMap<String, MyEnum> getMap()
methods:If not, shouldn't BoxedLightEnum.value be marked as a JsProperty, so that JS is hypothetically able to unbox?
Note that boxing doesn't occur with native enums, which almost certainly should be documented as well. What benefits do non-native enums get from being able to be boxed to be worth these tradeoffs?
Extends Enum
Somewhat surprisingly, the previous point does not make a JsEnum actually extend java.lang.Enum, unlike other boxed java primitives. It seems like it would be clearer to document this directly in JsEnum as one of the main points, and discuss details about name()/ordinal()/values() as a subpoint.
Related, valueOf() isn't documented as not supported in JsEnum, but doesn't appear to be supported.
Enum instance method support?
I can't find any tests that verify this, nor any logic that implements it, and the JsEnum docs don't say they isn't allowed. What's up with enum instance methods? The enum type could handle this by implementing the abstract method with a switch/case to delegate to (or inline) the actual final/static implementation, right?
Beta Was this translation helpful? Give feedback.
All reactions