Skip to content

Commit 0cf1806

Browse files
gkdncopybara-github
authored andcommitted
Open-source "Data Types and Semantics" doc.
It looks like we postponed open-sourcing the doc until the cleanup but it is useful as it is so releasing it as well. PiperOrigin-RevId: 718159048
1 parent 0831e53 commit 0cf1806

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Guides
3737
- [JsInterop Cookbook](docs/jsinterop-by-example.md)
3838
- [J2CL Best Practices](docs/best-practices.md)
3939
- [Emulation Limitations](docs/limitations.md)
40+
- [Data Types and Semantics](docs/semantics.md)
4041
- [Bazel Tutorial](https://docs.bazel.build/versions/master/tutorial/java.html)
4142
- [Bazel Best Practices](https://docs.bazel.build/versions/master/best-practices.html)
4243

docs/semantics.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<!-- TOC -->
2+
3+
# Notes on language semantics for J2CL
4+
5+
## Java to JavaScript Data Type Mapping
6+
7+
Java Type | JS Type | Clarification
8+
------------------- | --------------------------- | ------------------------
9+
boolean | boolean |
10+
byte | number |
11+
char | number |
12+
short | number |
13+
int | number |
14+
long | goog.math.Long |
15+
float | number |
16+
double | number |
17+
java.lang.Boolean | boolean \| null | See Boxing section below
18+
java.lang.Byte | java.lang.Byte \| null |
19+
java.lang.Character | java.lang.Character \| null |
20+
java.lang.Short | java.lang.Short \| null |
21+
java.lang.Integer | java.lang.Integer \| null |
22+
java.lang.Long | java.lang.Long \| null |
23+
java.lang.Float | java.lang.Float \| null |
24+
java.lang.Double | number \| null | See Boxing section below
25+
java.lang.String | string \| null | See Boxing section below
26+
java.lang.Object | \* | See Boxing section below
27+
28+
### Boxing
29+
30+
[Boxed types](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
31+
add a noticeable amount of performance overhead to JavaScript. To eliminate this
32+
overhead, J2CL never uses boxed representation for Double, String and Boolean.
33+
Double becomes a JavaScript number and Boolean becomes a JavaScript boolean.
34+
It's not possible to use plain numbers for boxed Integers because it leads to
35+
ambiguity. For example, the instanceof operator wouldn't be able to distinguish
36+
between Integer and Double:
37+
38+
```java
39+
Object foo = new Double(42)
40+
41+
// If both Integer and Double were represented with plain js number then there would be no way
42+
// to perform this runtime check for the type.
43+
if (foo instanceof Integer) {
44+
x--;
45+
} else if (foo instanceof Double) {
46+
x++;
47+
}
48+
```
49+
50+
Note that no such ambiguity exists for primitive ints, which is why they can be
51+
represented using a native JavaScript number.
52+
53+
### String
54+
55+
JavaScript natively supports strings and J2CL automatically unboxes Strings. So
56+
there is a one-to-one mapping between Java String and the native JavaScript
57+
string type.
58+
59+
### Integer
60+
61+
JavaScript does not natively support integers. J2CL emulates integers using the
62+
native JavaScript number type: a 64-bit double. Note that boxed Integers remain
63+
boxed, unlike Double and Boolean.
64+
65+
### Double
66+
67+
JavaScript natively supports doubles and J2CL automatically unboxes Doubles. So
68+
there is a one-to-one mapping between Java Double/double and the native
69+
JavaScript number type.
70+
71+
### Long
72+
73+
JavaScript does not natively support longs. J2CL emulates longs using the
74+
Closure long library:
75+
[goog.math.Long](http://google3/third_party/javascript/closure/math/long.js)
76+
77+
### Boolean
78+
79+
JavaScript natively supports booleans and J2CL automatically unboxes Booleans.
80+
So there is a one-to-one mapping between Java Boolean/boolean and the native
81+
JavaScript boolean type.
82+
83+
### Null vs Undefined
84+
85+
From J2CL's perspective `null` and `undefined` are the same type. If you check
86+
if a value is equal to null then it will return true if the value is `null` *or*
87+
`undefined`.
88+
89+
## Behavior of java.lang.Object methods
90+
91+
TODO(rluble): complete the following table
92+
93+
| | `toString()` | `equals()` | `hashcode()` | `getClass()` |
94+
| -------------- | ------------ | ---------- | ------------ | ------------ |
95+
| Arrays | | | | |
96+
| Native arrays | | | | |
97+
| JsFunction | | | | |
98+
| JsFunction | | | | |
99+
: implementation : : : : :
100+
101+
## Differences in J2CL JsInterop vs. GWT JsInterop
102+
103+
* Namespaces on non-native JsMethods are forbidden (i.e. J2CL does not allow
104+
to define a method out of its module's scope). GWT allowed this only due to
105+
providing a way to export functions to global scope; J2CL relies on
106+
goog.export for the same functionality.
107+
* Namespace JsPackage.GLOBAL is special. Native JsTypes within this namespace
108+
are considered externs hence no goog.require will be generated for them.
109+
* Instances of `java.lang.Object[]` are not stamped. `new Object[]{ "a" }` in
110+
Java and `["a"]` in JS are effectively same.
111+
* instanceof on a class F implementing a @JsFunction interface returns true if
112+
and only if the instance is actually an instance of class F.
113+
* Subclasses of classes that have a `@JsConstructor` are required to have a
114+
`@JsConstructor`.
115+
* The constructor of an anonymous inner class that extends a class with a
116+
`@JsConstructor` is implicitly a `@JsConstructor`.

0 commit comments

Comments
 (0)