update doc for 1.2.0

This commit is contained in:
Renaud Pawlak 2016-12-16 13:00:23 +01:00
parent 2f4e1acd0f
commit 5b1a183995
3 changed files with 143 additions and 68 deletions

View File

@ -37,7 +37,7 @@ Content
- [Initializers](#initializers)
- [Arrays initialization and allocation](#arrays-initialization-and-allocation)
- [Name clashes](#name-clashes)
- [Testing the type of an object (`instanceof`)](#testing-the-type-of-an-object-instanceof)
- [Testing the type of an object](#testing-the-type-of-an-object)
- [Variable scoping in lambda expressions](#variable-scoping-in-lambda-expressions)
- [Scope of *this*](#scope-of-this)
- [Packaging](#packaging)
@ -107,6 +107,8 @@ By default, JSweet maps core Java objects and methods to JavaScript through the
- allowed methods: `boolean equals()`
- allowed methods: `Class<?> getClass()`
- allowed methods: `String toString()`
- `java.lang.CharSequence`
@ -215,9 +217,9 @@ By default, JSweet maps core Java objects and methods to JavaScript through the
- allowed methods:
- `String getName()`: only on class literals
- `String getName()`
- `String getSimpleName()`: only on class literals
- `String getSimpleName()`
- `java.lang.Boolean`
@ -763,7 +765,7 @@ for (Node node : nodes) {
### Enums
JSweet allows the definition of enums similarly to Java, but with some restrictions. The following code declares an enum with tree possible values (`A`, `B`, and `C`).
JSweet allows the definition of enums similarly to Java. The following code declares an enum with tree possible values (`A`, `B`, and `C`).
``` java
enum MyEnum {
@ -782,31 +784,34 @@ assert MyEnum.valueOf("A") == e;
assert array(MyEnum.values()).indexOf(MyEnum.valueOf("C")) == 2;
```
On the other hand, unlike Java enums, other members than constants are not allowed, raising JSweet transpilation errors, as shown in the following code.
Like Java enums, additional methods, constructors and fields can be added to enums.
``` java
public enum WrongConstructsInEnums {
enum ScreenRatio {
FREE_RATIO(null),
RATIO_4_3(4f / 3),
RATIO_3_2(1.5f),
RATIO_16_9(16f / 9),
RATIO_2_1(2f / 1f),
SQUARE_RATIO(1f);
A, B, C;
// error: fields are not allowed
public long l = 4;
// error: constructors are not allowed
private WrongConstructsInEnums() {
l = 4;
private final Float value;
private MyComplexEnum(Float value) {
this.value = value;
}
// error: methods are not allowed
public void m2() {
l = 4;
}
// error: initializers are not allowed
{
l = 4;
public Float getValue() {
return value;
}
}
```
These constraints will be relaxed in future releases.
#### Enums portability notes
Simple enums are translated to regular TypeScript enums, that is to say numbers. In JavaScript, at runtime, an enum instance is simple encode as its ordinal. So, JSweet enums are easy to share with TypeScript enums and a JSweet program can interoperate with a TypeScript program even when using enums.
Enums with additional members are also mapped to TypeScript enums, but an additional class is generated to store the additional information. When interoperating with TypeScript, the ordinal will remain, but the additional information will be lost. The programmers wanting to share enums with TypeScript should be aware of that behavior.
### Globals
@ -918,7 +923,9 @@ Here is a list of rules and constraints that need to be followed when writing de
- In an interface, optional fields can be defined with the `@jsweet.lang.Optional` annotation.
Definitions can be embedded directly in a JSweet project to access an external library in a typed way, of they can be packaged in a candy (a Maven artifact), so that they can be shared by other projects. See the *Packaging* section for full details on how to create a candy. Note that you do not need to write definitions when a library is written with JSweet because the Java API is directly accessible and the TypeScript definitions can be automatically generated by JSweet using the `declaration` option.
Definitions can be embedded directly in a JSweet project to access an external library in a typed way. In that case, you should specify the `definitions` compilation option so that these definitions can be generated and used by the TypeScript transpiler.
Definitions can also be packaged in a candy (a Maven artifact), so that they can be shared by other projects. See the *Packaging* section for full details on how to create a candy. Note that you do not need to write definitions when a library is written with JSweet because the Java API is directly accessible and the TypeScript definitions can be automatically generated by JSweet using the `declaration` option.
### Untyped accesses
@ -1485,9 +1492,13 @@ public void m2() {
Note that this problem also happens when using fully qualified names when calling the global methods (that is because the qualification gets erased in TypeScript/JavaScript). In any case, JSweet will report sound errors when such problems happen so that programmers can adjust local variable names to avoid clashes with globals.
### Testing the type of an object (`instanceof`)
### Testing the type of an object
To test the type of a given object at runtime, one can use the `instanceof` Java operator. It is the advised and preferred way to test types at runtime. JSweet will transpile to a regular `instanceof` or to a `typeof` operator depending on the tested type (it will fallback on `typeof` for `number`, `string`, and `boolean` core types).
To test the type of a given object at runtime, one can use the `instanceof` Java operator, but also the `Object.getClass()` function.
#### `instanceof`
The `instanceof` is the advised and preferred way to test types at runtime. JSweet will transpile to a regular `instanceof` or to a `typeof` operator depending on the tested type (it will fallback on `typeof` for `number`, `string`, and `boolean` core types).
Although not necessary, it is also possible to directly use the `typeof` operator from JSweet with the `jsweet.util.Globals.typeof` utility method. Here are some examples of valid type tests:
@ -1519,6 +1530,25 @@ Point p1 = new Point() {{ x=1; y=1; }};
assert p1 instanceof Point
```
#### `Object.getClass()` and `X.class`
In JSweet, using the `Object.getClass()` on any instance is possible. It will actually return the constructor function of the class. Using `X.class` will also return the constructor if `X` is a class. So the following assertion will hold in JSweet:
``` java
String s = "abc";
assert String.class == s.getClass()
```
On a class, you can call the `getSimpleName()` or `getName()` functions.
``` java
String s = "abc";
assert "String" == s.getClass().getSimpleName()
assert String.class.getSimpleName() == s.getClass().getSimpleName()
```
Note that `getSimpleName()` or `getName()` functions will also work on an interface. However, you have to be aware that `X.class` will be encoded in a string (holding the interfaces name) if `X` is is an interface.
#### Limitations and constraints
Since all numbers are mapped to JavaScript numbers, JSweet make no distinction between integers and floats for example. So, `n instanceof Integer` and `n instanceof Float` will always give the same result whatever the actual type of `n` is. The same limitation exists for strings and chars, which are not distinguishable at runtime, but also for functions that have the same number of parameters. For example, an instance of `IntFunction<R>` will not be distinguishable at runtime from a `Function<String,R>`.
@ -1621,15 +1651,17 @@ Nowadays, a lot of libraries are packaged and accessible through modules. The st
#### Modules in JSweet
JSweet supports AMD, commonjs, and UMD module systems for packaging. JSweet defines a `module` option (value: `amd`, `commonjs` or `umd`). When specifying this option, JSweet automatically creates a default module organization following the simple rule: one package = one module generated in a single file called `module.js`.
JSweet supports AMD, commonjs, and UMD module systems for packaging. JSweet defines a `module` option (value: `amd`, `commonjs` or `umd`). When specifying this option, JSweet automatically creates a default module organization following the simple rule: one file = one module.
For example, when packaged with the `module` option set to `commonjs`, one can write:
```
> node target/js/x/y/z/module.js
> node target/js/x/y/z/MyMainClass.js
```
The module system will automatically take care of the references and require other modules when needed.
Where `MyMainClass` contains a `main` method.
The module system will automatically take care of the references and require other modules when needed. Under the hood, JSweet analysis the Java import statements and transform them to `require` instructions.
Note: once the program has been compiled with the `module` option, it is easy to package it as a bundle using appropriate tools such as Browserify, which would give similar output as using the `bundle` option of JSweet. Note also that JSweet will raise an error when specifying both `module` and `bundle`, which are exclusive options.
@ -1660,7 +1692,7 @@ package myprogram;
// }
```
Note that a JSweet project can only define one `module_defs.java` file, which shall contain all the module declarations in a comment.
Note that a JSweet project can only define one `module_defs.java` file, which shall contain all the module declarations in a comment. Note also that it is a hack and the preferred method would be to contribute to the candy to fix the problem.
### Root packages
@ -1705,7 +1737,7 @@ Here is an example of the `META-INF/candy-metadata.json` file:
``` java
{
"transpilerVersion": "1.0.0"
"transpilerVersion": "1.1.0"
}
```
@ -1764,11 +1796,10 @@ Appendix 1: JSweet transpiler options
[--definitions]
Tells the transpiler to generate definitions from def.* packages in d.ts
definition files. The output directory is given by the tsout
option. This option can be used to create candies for existing
JavaScript libraries and must not be confused with the 'declaration'
option, that generates the definitions along with a program written in
JSweet.
definition files. The output directory is given by the tsout option.
This option can be used to create candies for existing JavaScript
libraries and must not be confused with the 'declaration' option, that
generates the definitions along with a program written in JSweet.
[--declaration]
Tells the transpiler to generate the d.ts files along with the js files,
@ -1783,6 +1814,13 @@ Appendix 1: JSweet transpiler options
Specify where to place extracted JavaScript files from candies.
(default: js/candies)
[--sourceRoot <sourceRoot>]
Specifies the location where debugger should locate Java files instead
of source locations. Use this flag if the sources will be located at
run-time in a different location than that at design-time. The location
specified will be embedded in the sourceMap to direct the debugger where
the source files will be located.
[--classpath <classpath>]
The JSweet transpilation classpath (candy jars). This classpath should
at least contain the core candy.

View File

@ -63,7 +63,7 @@
\begin{document}
\title{JSweet Language Specifications\\{\large Version 1.2.x (snapshot)}}
\title{JSweet Language Specifications\\{\large Version 1.2.x}}
\author{%
Renaud Pawlak\\
{\normalsize renaud.pawlak@jsweet.org}\\
@ -129,6 +129,7 @@ By default, JSweet maps core Java objects and methods to JavaScript through the
\item \texttt{java.lang.Object}
\begin{itemize}
\item allowed methods: \texttt{boolean equals()}
\item allowed methods: \texttt{Class<?> getClass()}
\item allowed methods: \texttt{String toString()}
\end{itemize}
\item \texttt{java.lang.CharSequence}
@ -196,8 +197,8 @@ By default, JSweet maps core Java objects and methods to JavaScript through the
\begin{itemize}
\item allowed methods:
\begin{itemize}
\item \texttt{String getName()}: only on class literals
\item \texttt{String getSimpleName()}: only on class literals
\item \texttt{String getName()}
\item \texttt{String getSimpleName()}
\end{itemize}
\end{itemize}
\item \texttt{java.lang.Boolean}
@ -683,7 +684,7 @@ for (Node node : nodes) {
\section{Enums}
JSweet allows the definition of enums similarly to Java, but with some restrictions. The following code declares an enum with tree possible values (\texttt{A}, \texttt{B}, and \texttt{C}).
JSweet allows the definition of enums similarly to Java. The following code declares an enum with tree possible values (\texttt{A}, \texttt{B}, and \texttt{C}).
\begin{lstlisting}[language=Java]
enum MyEnum {
@ -702,31 +703,34 @@ assert MyEnum.valueOf("A") == e;
assert array(MyEnum.values()).indexOf(MyEnum.valueOf("C")) == 2;
\end{lstlisting}
On the other hand, unlike Java enums, other members than constants are not allowed, raising JSweet transpilation errors, as shown in the following code.
Like Java enums, additional methods, constructors and fields can be added to enums.
\begin{lstlisting}[language=Java]
public enum WrongConstructsInEnums {
enum ScreenRatio {
FREE_RATIO(null),
RATIO_4_3(4f / 3),
RATIO_3_2(1.5f),
RATIO_16_9(16f / 9),
RATIO_2_1(2f / 1f),
SQUARE_RATIO(1f);
A, B, C;
// error: fields are not allowed
public long l = 4;
// error: constructors are not allowed
private WrongConstructsInEnums() {
l = 4;
private final Float value;
private MyComplexEnum(Float value) {
this.value = value;
}
// error: methods are not allowed
public void m2() {
l = 4;
}
// error: initializers are not allowed
{
l = 4;
public Float getValue() {
return value;
}
}
\end{lstlisting}
These constraints will be relaxed in future releases.
\subsection*{Enums portability notes}
Simple enums are translated to regular TypeScript enums, that is to say numbers. In JavaScript, at runtime, an enum instance is simple encode as its ordinal. So, JSweet enums are easy to share with TypeScript enums and a JSweet program can interoperate with a TypeScript program even when using enums.
Enums with additional members are also mapped to TypeScript enums, but an additional class is generated to store the additional information. When interoperating with TypeScript, the ordinal will remain, but the additional information will be lost. The programmers wanting to share enums with TypeScript should be aware of that behavior.
\section{Globals}
@ -830,7 +834,9 @@ Here is a list of rules and constraints that need to be followed when writing de
\item In an interface, optional fields can be defined with the \texttt{@jsweet.lang.Optional} annotation.
\end{itemize}
Definitions can be embedded directly in a JSweet project to access an external library in a typed way, of they can be packaged in a candy (a Maven artifact), so that they can be shared by other projects. See the \emph{Packaging} section for full details on how to create a candy. Note that you do not need to write definitions when a library is written with JSweet because the Java API is directly accessible and the TypeScript definitions can be automatically generated by JSweet using the \texttt{declaration} option.
Definitions can be embedded directly in a JSweet project to access an external library in a typed way. In that case, you should specify the \texttt{definitions} compilation option so that these definitions can be generated and used by the TypeScript transpiler.
Definitions can also be packaged in a candy (a Maven artifact), so that they can be shared by other projects. See the \emph{Packaging} section for full details on how to create a candy. Note that you do not need to write definitions when a library is written with JSweet because the Java API is directly accessible and the TypeScript definitions can be automatically generated by JSweet using the \texttt{declaration} option.
\section{Untyped accesses}
@ -1400,9 +1406,13 @@ public void m2() {
Note that this problem also happens when using fully qualified names when calling the global methods (that is because the qualification gets erased in TypeScript/JavaScript). In any case, JSweet will report sound errors when such problems happen so that programmers can adjust local variable names to avoid clashes with globals.
\section{Testing the type of an object (\texttt{instanceof})}
\section{Testing the type of an object}
To test the type of a given object at runtime, one can use the \texttt{instanceof} Java operator. It is the advised and preferred way to test types at runtime. JSweet will transpile to a regular \texttt{instanceof} or to a \texttt{typeof} operator depending on the tested type (it will fallback on \texttt{typeof} for \texttt{number}, \texttt{string}, and \texttt{boolean} core types).
To test the type of a given object at runtime, one can use the \texttt{instanceof} Java operator, but also the \texttt{Object.getClass()} function.
\subsection{\texttt{instanceof}}
The \texttt{instanceof} is the advised and preferred way to test types at runtime. JSweet will transpile to a regular \texttt{instanceof} or to a \texttt{typeof} operator depending on the tested type (it will fallback on \texttt{typeof} for \texttt{number}, \texttt{string}, and \texttt{boolean} core types).
Although not necessary, it is also possible to directly use the \texttt{typeof} operator from JSweet with the \texttt{jsweet.\-util.\-Globals.\-typeof} utility method. Here are some examples of valid type tests:
@ -1434,6 +1444,25 @@ Point p1 = new Point() {{ x=1; y=1; }};
assert p1 instanceof Point
\end{lstlisting}
\subsection{\texttt{Object.getClass()} and \texttt{X.class}}
In JSweet, using the \texttt{Object.getClass()} on any instance is possible. It will actually return the constructor function of the class. Using \texttt{X.class} will also return the constructor if \texttt{X} is a class. So the following assertion will hold in JSweet:
\begin{lstlisting}[language=Java]
String s = "abc";
assert String.class == s.getClass()
\end{lstlisting}
On a class, you can call the \texttt{getSimpleName()} or \texttt{getName()} functions.
\begin{lstlisting}[language=Java]
String s = "abc";
assert "String" == s.getClass().getSimpleName()
assert String.class.getSimpleName() == s.getClass().getSimpleName()
\end{lstlisting}
Note that \texttt{getSimpleName()} or \texttt{getName()} functions will also work on an interface. However, you have to be aware that \texttt{X.class} will be encoded in a string (holding the interface's name) if \texttt{X} is is an interface.
\subsection{Limitations and constraints}
Since all numbers are mapped to JavaScript numbers, JSweet make no distinction between integers and floats for example. So, \texttt{n instanceof Integer} and \texttt{n instanceof Float} will always give the same result whatever the actual type of \texttt{n} is. The same limitation exists for strings and chars, which are not distinguishable at runtime, but also for functions that have the same number of parameters. For example, an instance of \texttt{IntFunction<R>} will not be distinguishable at runtime from a \texttt{Function<String,R>}.
@ -1537,15 +1566,17 @@ Nowadays, a lot of libraries are packaged and accessible through modules. The st
\subsection{Modules in JSweet}
JSweet supports AMD, commonjs, and UMD module systems for packaging. JSweet defines a \texttt{module} option (value: \texttt{amd}, \texttt{commonjs} or \texttt{umd}). When specifying this option, JSweet automatically creates a default module organization following the simple rule: one package = one module generated in a single file called \texttt{module.js}.
JSweet supports AMD, commonjs, and UMD module systems for packaging. JSweet defines a \texttt{module} option (value: \texttt{amd}, \texttt{commonjs} or \texttt{umd}). When specifying this option, JSweet automatically creates a default module organization following the simple rule: one file = one module.
For example, when packaged with the \texttt{module} option set to \texttt{commonjs}, one can write:
\begin{lstlisting}[language=html]
> node target/js/x/y/z/module.js
> node target/js/x/y/z/MyMainClass.js
\end{lstlisting}
The module system will automatically take care of the references and require other modules when needed.
Where \texttt{MyMainClass} contains a \texttt{main} method.
The module system will automatically take care of the references and require other modules when needed. Under the hood, JSweet analysis the Java import statements and transform them to \texttt{require} instructions.
Note: once the program has been compiled with the \texttt{module} option, it is easy to package it as a bundle using appropriate tools such as Browserify, which would give similar output as using the \texttt{bundle} option of JSweet. Note also that JSweet will raise an error when specifying both \texttt{module} and \texttt{bundle}, which are exclusive options.
@ -1576,7 +1607,7 @@ package myprogram;
// }
\end{lstlisting}
Note that a JSweet project can only define one \texttt{module\_defs.java} file, which shall contain all the module declarations in a comment.
Note that a JSweet project can only define one \texttt{module\_defs.java} file, which shall contain all the module declarations in a comment. Note also that it is a hack and the preferred method would be to contribute to the candy to fix the problem.
\section{Root packages}
@ -1620,7 +1651,7 @@ Here is an example of the \texttt{META-INF/candy-metadata.json} file:
\begin{lstlisting}[language=Java]
{
"transpilerVersion": "1.0.0"
"transpilerVersion": "1.1.0"
}
\end{lstlisting}
@ -1680,11 +1711,10 @@ We provide a quick start project to help you starting with such a use case: \url
[--definitions]
Tells the transpiler to generate definitions from def.* packages in d.ts
definition files. The output directory is given by the tsout
option. This option can be used to create candies for existing
JavaScript libraries and must not be confused with the 'declaration'
option, that generates the definitions along with a program written in
JSweet.
definition files. The output directory is given by the tsout option.
This option can be used to create candies for existing JavaScript
libraries and must not be confused with the 'declaration' option, that
generates the definitions along with a program written in JSweet.
[--declaration]
Tells the transpiler to generate the d.ts files along with the js files,
@ -1699,6 +1729,13 @@ We provide a quick start project to help you starting with such a use case: \url
Specify where to place extracted JavaScript files from candies.
(default: js/candies)
[--sourceRoot <sourceRoot>]
Specifies the location where debugger should locate Java files instead
of source locations. Use this flag if the sources will be located at
run-time in a different location than that at design-time. The location
specified will be embedded in the sourceMap to direct the debugger where
the source files will be located.
[--classpath <classpath>]
The JSweet transpilation classpath (candy jars). This classpath should
at least contain the core candy.