From a91bd7ec8f213d674c3b086c412742553b067f3c Mon Sep 17 00:00:00 2001 From: Renaud Pawlak Date: Thu, 11 May 2017 17:31:32 +0200 Subject: [PATCH] support for $noarrow macro By default, JSweet generates arrow functions for Java lambda (the 'this' semantics is closer to Java). Wrapping a function in $noarrow will force JSweet to produce a plain old JavaScript function rather than an arrow function. --- .../es5/src/main/java/jsweet/util/Lang.java | 1174 +++++++++-------- .../es6/src/main/java/jsweet/util/Lang.java | 1174 +++++++++-------- .../transpiler/Java2TypeScriptTranslator.java | 3 +- .../extension/Java2TypeScriptAdapter.java | 4 + .../transpiler/util/AbstractTreeScanner.java | 11 + .../source/decorator/SimpleDecorator.java | 4 +- 6 files changed, 1205 insertions(+), 1165 deletions(-) diff --git a/core-lib/es5/src/main/java/jsweet/util/Lang.java b/core-lib/es5/src/main/java/jsweet/util/Lang.java index 0fbf6051..b0c2715e 100644 --- a/core-lib/es5/src/main/java/jsweet/util/Lang.java +++ b/core-lib/es5/src/main/java/jsweet/util/Lang.java @@ -58,638 +58,650 @@ import jsweet.util.union.Union4; */ public final class Lang { - private static final ThreadLocal> EXPORTED_VARS = new ThreadLocal<>(); + private static final ThreadLocal> EXPORTED_VARS = new ThreadLocal<>(); - private Lang() { - } + private Lang() { + } - /** - * An accessor to the module id, only when using modules. - */ - public static final class module { - public final static String id = null; - } + /** + * An accessor to the module id, only when using modules. + */ + public static final class module { + public final static String id = null; + } - /** - * Casts a JavaScript array object to a native Java array. - * - * @param array - * a JavaScript array - * @return a Java array - */ - native public static T[] array(def.js.Array array); + /** + * Casts a JavaScript array object to a native Java array. + * + * @param array + * a JavaScript array + * @return a Java array + */ + native public static T[] array(def.js.Array array); - /** - * Casts a native Java array to a JavaScript array object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(T[] array); + /** + * Casts a native Java array to a JavaScript array object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(T[] array); - /** - * Casts a native Java array of primitive booleans to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(boolean[] array); + /** + * Casts a native Java array of primitive booleans to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(boolean[] array); - /** - * Casts a native Java array of primitive ints to a JavaScript array object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(int[] array); + /** + * Casts a native Java array of primitive ints to a JavaScript array object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(int[] array); - /** - * Casts a native Java array of primitive doubles to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(double[] array); + /** + * Casts a native Java array of primitive doubles to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(double[] array); - /** - * Casts a native Java array of primitive shorts to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(short[] array); + /** + * Casts a native Java array of primitive shorts to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(short[] array); - /** - * Casts a native Java array of primitive bytes to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(byte[] array); + /** + * Casts a native Java array of primitive bytes to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(byte[] array); - /** - * Casts a native Java array of primitive longs to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(long[] array); + /** + * Casts a native Java array of primitive longs to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(long[] array); - /** - * Casts a native Java array of primitive floats to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(float[] array); + /** + * Casts a native Java array of primitive floats to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(float[] array); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Runnable function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Runnable function); - /** - * Casts a type to a JavaScript function object. - * - *

- * Indeed, type references are functions in javascript. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Class type); + /** + * Casts a type to a JavaScript function object. + * + *

+ * Indeed, type references are functions in javascript. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Class type); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Supplier function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Supplier function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(BiConsumer function); + /** + * Forces JSweet to create a plain JavaScript function rather than an + * "arrow" function. + * + *

+ * Hence, function((a) -> { return a * a; }) transpiles to + * (a) => { return a * a; }. But + * $noarrow(function((a) -> { return a * a; })) transpiles to + * function(a) { return a * a; } + */ + native public static def.js.Function $noarrow(def.js.Function function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(TriConsumer function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(BiConsumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer4 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(TriConsumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer5 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer4 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer6 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer5 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer6 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(BiFunction function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(TriFunction function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(BiFunction function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function4 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(TriFunction function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function5 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function4 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function6 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function5 function); - /** - * Casts a native Java Boolean to a JavaScript Boolean. - */ - native public static def.js.Boolean bool(Boolean bool); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function6 function); - /** - * Casts back a JavaScript boolean to a Java boolean. - */ - native public static Boolean bool(def.js.Boolean bool); + /** + * Casts a native Java Boolean to a JavaScript Boolean. + */ + native public static def.js.Boolean bool(Boolean bool); - /** - * Casts a native Java number to a JavaScript Number. - */ - native public static def.js.Number number(Number number); + /** + * Casts back a JavaScript boolean to a Java boolean. + */ + native public static Boolean bool(def.js.Boolean bool); - /** - * Casts back a JavaScript number to a Java integer. - */ - native public static Integer integer(def.js.Number number); + /** + * Casts a native Java number to a JavaScript Number. + */ + native public static def.js.Number number(Number number); - /** - * Casts back a JavaScript number to a Java integer. - */ - native public static Double number(def.js.Number number); + /** + * Casts back a JavaScript number to a Java integer. + */ + native public static Integer integer(def.js.Number number); - /** - * Casts a native Java string to a JavaScript string. - * - *

- * By default, JSweet API use plain Java strings so that the program can - * easily use string literals. However, when the programmer needs to access - * to runtime string manipulation functions, then need to cast to a - * JavaScript string, which allows the access to the standard Web API. - */ - native public static def.js.String string(String string); + /** + * Casts back a JavaScript number to a Java integer. + */ + native public static Double number(def.js.Number number); - /** - * Casts a native Java char to a JavaScript string. - */ - native public static def.js.String string(char c); + /** + * Casts a native Java string to a JavaScript string. + * + *

+ * By default, JSweet API use plain Java strings so that the program can + * easily use string literals. However, when the programmer needs to access + * to runtime string manipulation functions, then need to cast to a + * JavaScript string, which allows the access to the standard Web API. + */ + native public static def.js.String string(String string); - /** - * Casts back a JavaScript string to a Java string. - * - *

- * By default, JSweet API use plain Java strings so that the program can - * easily use string literals. However, when the programmer needs to access - * to runtime string manipulation functions, then need to cast to a - * JavaScript string, which allows the access to the standard Web API. - */ - native public static String string(def.js.String string); + /** + * Casts a native Java char to a JavaScript string. + */ + native public static def.js.String string(char c); - /** - * Casts a native Java object to a JavaScript object. - * - *

- * By default, JSweet API use plain Java objects. However, when the - * programmer needs to access to the standard Web API, they need to cast - * through this function. - */ - native public static def.js.Object object(Object object); + /** + * Casts back a JavaScript string to a Java string. + * + *

+ * By default, JSweet API use plain Java strings so that the program can + * easily use string literals. However, when the programmer needs to access + * to runtime string manipulation functions, then need to cast to a + * JavaScript string, which allows the access to the standard Web API. + */ + native public static String string(def.js.String string); - /** - * This syntax macro should be used to create untyped JavaScript - * objects/maps. It takes a list of key/value pairs, where the keys must be - * string literals and values are objects. - * - *

- * For instance, the expression: - * - *

-	 * $map("responsive", true, "defaultSize", "100px")
-	 * 
- * - *

- * Will be transpiled to: - * - *

-	 * {responsive:true, defaultSize:"100px"}
-	 * 
- * - * @param keyValues - * the key values pairs that initialize the object (keys must be - * string literals) - * @return an untyped object containing the given key/value pairs - */ - native public static def.js.Object $map(Object... keyValues); + /** + * Casts a native Java object to a JavaScript object. + * + *

+ * By default, JSweet API use plain Java objects. However, when the + * programmer needs to access to the standard Web API, they need to cast + * through this function. + */ + native public static def.js.Object object(Object object); - /** - * A syntax macro to construct an array with the given elements. - * - *

- * For instance, the expression: - * - *

-	 * $array("a", "b", "c")
-	 * 
- * - *

- * Will be transpiled to: - * - *

-	 * ["a", "b", "c"]
-	 * 
- * - * - * @param elements - * the elements initializing the array - * @return a new array - */ - @SafeVarargs - native public static def.js.Array $array(E... elements); + /** + * This syntax macro should be used to create untyped JavaScript + * objects/maps. It takes a list of key/value pairs, where the keys must be + * string literals and values are objects. + * + *

+ * For instance, the expression: + * + *

+     * $map("responsive", true, "defaultSize", "100px")
+     * 
+ * + *

+ * Will be transpiled to: + * + *

+     * {responsive:true, defaultSize:"100px"}
+     * 
+ * + * @param keyValues + * the key values pairs that initialize the object (keys must be + * string literals) + * @return an untyped object containing the given key/value pairs + */ + native public static def.js.Object $map(Object... keyValues); - /** - * Uses the target object as a function and call it. This is not typesafe - * and should be avoided. - * - * @param target - * the functional object - * @param arguments - * the call arguments - * @return the function result - */ - native public static T $apply(Object target, Object... arguments); + /** + * A syntax macro to construct an array with the given elements. + * + *

+ * For instance, the expression: + * + *

+     * $array("a", "b", "c")
+     * 
+ * + *

+ * Will be transpiled to: + * + *

+     * ["a", "b", "c"]
+     * 
+ * + * + * @param elements + * the elements initializing the array + * @return a new array + */ + @SafeVarargs + native public static def.js.Array $array(E... elements); - /** - * Uses the target object as a constructor and call it. This is not typesafe - * and should be avoided. - * - * @param target - * the constructor object - * @param arguments - * the call arguments - * @return the constructor result - */ - native public static T $new(Object target, Object... arguments); + /** + * Uses the target object as a function and call it. This is not typesafe + * and should be avoided. + * + * @param target + * the functional object + * @param arguments + * the call arguments + * @return the function result + */ + native public static T $apply(Object target, Object... arguments); - /** - * This helper casts an object to one of the types in a given union type. - * - *

- * The JSweet transpiler will ensure that T is one of T1 and T2. If not, it - * will raise an error. - * - * @param union - * the object typed after a union type - * @return the same object, but typed after one of the types of the union - * type - */ - native public static T union(Union union); + /** + * Uses the target object as a constructor and call it. This is not typesafe + * and should be avoided. + * + * @param target + * the constructor object + * @param arguments + * the call arguments + * @return the constructor result + */ + native public static T $new(Object target, Object... arguments); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static , T> U union(T object); + /** + * This helper casts an object to one of the types in a given union type. + * + *

+ * The JSweet transpiler will ensure that T is one of T1 and T2. If not, it + * will raise an error. + * + * @param union + * the object typed after a union type + * @return the same object, but typed after one of the types of the union + * type + */ + native public static T union(Union union); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static Union3 union3(T object); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static , T> U union(T object); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static Union4 union4(T object); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static Union3 union3(T object); - /** - * This utility function allows using the typeof JavaScript - * operator. - * - * The expression typeof(o) transpiles to typeof o - * . See the JavaScript documentation for more details. - */ - native public static String typeof(Object o); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static Union4 union4(T object); - /** - * This syntax macro allows using the == or != - * JavaScript operators. Note that this macro will have no effect on other - * operators than == or !=, but will recursively - * apply to all operators contained in the macro. - * - *

- * Since JSweet version 1.1, the Java expression o1!=o2 - * transpiles to o1!==o2 to remain close to the Java strict - * inequality (except when diffing with the null literal where - * the == operator is used). - * - *

- * Examples: - * - *

-	 * if(a == b) { ... }
-	 * if(a != b) { ... }
-	 * if($loose(a == b)) { ... }
-	 * if($loose(a != b)) { ... }
-	 * if($strict(a == b)) { ... }
-	 * if(a == undefined) { ... }
-	 * if(a != null) { ... }
-	 * if($strict(a != null)) { ... }
-	 * if($loose(a == f(b != a))) { ... }
-	 * 
- * - * Transpile to: - * - *
-	 * if(a === b) { ... }
-	 * if(a !== b) { ... }
-	 * if(a == b) { ... }
-	 * if(a != b) { ... }
-	 * if(a === b) { ... }
-	 * if(a === undefined) { ... }
-	 * if(a != null) { ... }
-	 * if(a !== null) { ... }
-	 * if(a == f(b != a)) { ... }
-	 * 
- * - * @param expression - * can be any expression returning a boolean, but only - * (in)equalities operators will be impacted - * @return the expression modified to use loose JavaScript (in)equalities - * operators - * @since 2.0 - */ - native public static boolean $loose(boolean expression); + /** + * This utility function allows using the typeof JavaScript + * operator. + * + * The expression typeof(o) transpiles to typeof o + * . See the JavaScript documentation for more details. + */ + native public static String typeof(Object o); - /** - * This syntax macro is the reverse of {@link #$loose(boolean)}, and - * enforces strict (in)equalities when it makes sense. - * - * @param expression - * can be any expression returning a boolean, but only - * (in)equalities operators will be impacted - * @return the expression modified to use strict JavaScript (in)equalities - * operators - */ - native public static boolean $strict(boolean expression); + /** + * This syntax macro allows using the == or != + * JavaScript operators. Note that this macro will have no effect on other + * operators than == or !=, but will recursively + * apply to all operators contained in the macro. + * + *

+ * Since JSweet version 1.1, the Java expression o1!=o2 + * transpiles to o1!==o2 to remain close to the Java strict + * inequality (except when diffing with the null literal where + * the == operator is used). + * + *

+ * Examples: + * + *

+     * if(a == b) { ... }
+     * if(a != b) { ... }
+     * if($loose(a == b)) { ... }
+     * if($loose(a != b)) { ... }
+     * if($strict(a == b)) { ... }
+     * if(a == undefined) { ... }
+     * if(a != null) { ... }
+     * if($strict(a != null)) { ... }
+     * if($loose(a == f(b != a))) { ... }
+     * 
+ * + * Transpile to: + * + *
+     * if(a === b) { ... }
+     * if(a !== b) { ... }
+     * if(a == b) { ... }
+     * if(a != b) { ... }
+     * if(a === b) { ... }
+     * if(a === undefined) { ... }
+     * if(a != null) { ... }
+     * if(a !== null) { ... }
+     * if(a == f(b != a)) { ... }
+     * 
+ * + * @param expression + * can be any expression returning a boolean, but only + * (in)equalities operators will be impacted + * @return the expression modified to use loose JavaScript (in)equalities + * operators + * @since 2.0 + */ + native public static boolean $loose(boolean expression); - /** - * Disable type checking on the target object (cast to any). This helper is - * valid in Java. - */ - @SuppressWarnings("unchecked") - public static T any(Object object) { - return (T) object; - } + /** + * This syntax macro is the reverse of {@link #$loose(boolean)}, and + * enforces strict (in)equalities when it makes sense. + * + * @param expression + * can be any expression returning a boolean, but only + * (in)equalities operators will be impacted + * @return the expression modified to use strict JavaScript (in)equalities + * operators + */ + native public static boolean $strict(boolean expression); - /** - * This helper function allows the programmer to reflectively set a global - * variable named "_exportedVar_"+name. - * - *

- * This function must only be used in specifically cases, typically to - * define results when testing from Java. - * - * @param name - * the base name of the exported global variable, necessarily as - * a string literal - * @param value - * the value to set to the variable - */ - public static void $export(String name, Object value) { - // default Java implementation when running in Java (usually for testing - // purposes) - EXPORTED_VARS.get().put("_exportedVar_" + name, value); - } + /** + * Disable type checking on the target object (cast to any). This helper is + * valid in Java. + */ + @SuppressWarnings("unchecked") + public static T any(Object object) { + return (T) object; + } - /** - * Accesses the current JavaScript this. Within an object - * scope, $this corresponds to a regular object oriented - * this. Outside on an object (i.e. within a global function), - * $this has the JavaScript meaning, representing the current - * function object. - */ - public static final def.js.Object $this = null; + /** + * This helper function allows the programmer to reflectively set a global + * variable named "_exportedVar_"+name. + * + *

+ * This function must only be used in specifically cases, typically to + * define results when testing from Java. + * + * @param name + * the base name of the exported global variable, necessarily as + * a string literal + * @param value + * the value to set to the variable + */ + public static void $export(String name, Object value) { + // default Java implementation when running in Java (usually for testing + // purposes) + EXPORTED_VARS.get().put("_exportedVar_" + name, value); + } - /** - * Defines a template string. - * - *

- * For example: - * - *

-	 * console.info($template("Get: ${key} => ${_val}"));
-	 * 
- * - *

- * gets transpiled to: - *

- * - *
-	 * console.info(`Get: ${key} => ${_val}`));
-	 * 
- * - * @param templateString - * the regular Java string to be turned into a template string - * @return a JavaScript template string - */ - public static native String $template(String templateString); + /** + * Accesses the current JavaScript this. Within an object + * scope, $this corresponds to a regular object oriented + * this. Outside on an object (i.e. within a global function), + * $this has the JavaScript meaning, representing the current + * function object. + */ + public static final def.js.Object $this = null; - /** - * Defines a template string with a tag. - * - * @see #$template(String) - */ - public static native String $template(Object tag, String templateString); + /** + * Defines a template string. + * + *

+ * For example: + * + *

+     * console.info($template("Get: ${key} => ${_val}"));
+     * 
+ * + *

+ * gets transpiled to: + *

+ * + *
+     * console.info(`Get: ${key} => ${_val}`));
+     * 
+ * + * @param templateString + * the regular Java string to be turned into a template string + * @return a JavaScript template string + */ + public static native String $template(String templateString); - /** - * Inserts a TypeScript string as is in the generated program (not - * recommended). This can be seen as a compile-time eval. - * - *

- * Although the TypeScript compiler will check the inserted code by - * compiling it, it is obviously a dangerous macro that should be used only - * in last resort. - * - * @see def.js.Globals#eval(String) - */ - public static native String $insert(String typescriptString); + /** + * Defines a template string with a tag. + * + * @see #$template(String) + */ + public static native String $template(Object tag, String templateString); + + /** + * Inserts a TypeScript string as is in the generated program (not + * recommended). This can be seen as a compile-time eval. + * + *

+ * Although the TypeScript compiler will check the inserted code by + * compiling it, it is obviously a dangerous macro that should be used only + * in last resort. + * + * @see def.js.Globals#eval(String) + */ + public static native String $insert(String typescriptString); } diff --git a/core-lib/es6/src/main/java/jsweet/util/Lang.java b/core-lib/es6/src/main/java/jsweet/util/Lang.java index d7812280..72f98026 100644 --- a/core-lib/es6/src/main/java/jsweet/util/Lang.java +++ b/core-lib/es6/src/main/java/jsweet/util/Lang.java @@ -58,638 +58,650 @@ import jsweet.util.union.Union4; */ public final class Lang { - private static final ThreadLocal> EXPORTED_VARS = new ThreadLocal<>(); + private static final ThreadLocal> EXPORTED_VARS = new ThreadLocal<>(); - private Lang() { - } + private Lang() { + } - /** - * An accessor to the module id, only when using modules. - */ - public static final class module { - public final static String id = null; - } + /** + * An accessor to the module id, only when using modules. + */ + public static final class module { + public final static String id = null; + } - /** - * Casts a JavaScript array object to a native Java array. - * - * @param array - * a JavaScript array - * @return a Java array - */ - native public static T[] array(def.js.Array array); + /** + * Casts a JavaScript array object to a native Java array. + * + * @param array + * a JavaScript array + * @return a Java array + */ + native public static T[] array(def.js.Array array); - /** - * Casts a native Java array to a JavaScript array object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(T[] array); + /** + * Casts a native Java array to a JavaScript array object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(T[] array); - /** - * Casts a native Java array of primitive booleans to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(boolean[] array); + /** + * Casts a native Java array of primitive booleans to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(boolean[] array); - /** - * Casts a native Java array of primitive ints to a JavaScript array object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(int[] array); + /** + * Casts a native Java array of primitive ints to a JavaScript array object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(int[] array); - /** - * Casts a native Java array of primitive doubles to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(double[] array); + /** + * Casts a native Java array of primitive doubles to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(double[] array); - /** - * Casts a native Java array of primitive shorts to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(short[] array); + /** + * Casts a native Java array of primitive shorts to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(short[] array); - /** - * Casts a native Java array of primitive bytes to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(byte[] array); + /** + * Casts a native Java array of primitive bytes to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(byte[] array); - /** - * Casts a native Java array of primitive longs to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(long[] array); + /** + * Casts a native Java array of primitive longs to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(long[] array); - /** - * Casts a native Java array of primitive floats to a JavaScript array - * object. - * - * @param array - * a Java array - * @return a JavaScript array - */ - native public static def.js.Array array(float[] array); + /** + * Casts a native Java array of primitive floats to a JavaScript array + * object. + * + * @param array + * a Java array + * @return a JavaScript array + */ + native public static def.js.Array array(float[] array); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Runnable function); + /** + * Forces JSweet to create a plain JavaScript function rather than an + * "arrow" function. + * + *

+ * Hence, function((a) -> { return a * a; }) transpiles to + * (a) => { return a * a; }. But + * $noarrow(function((a) -> { return a * a; })) transpiles to + * function(a) { return a * a; } + */ + native public static def.js.Function $noarrow(def.js.Function function); - /** - * Casts a type to a JavaScript function object. - * - *

- * Indeed, type references are functions in javascript. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Class type); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Runnable function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer function); + /** + * Casts a type to a JavaScript function object. + * + *

+ * Indeed, type references are functions in javascript. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Class type); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Supplier function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(BiConsumer function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Supplier function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(TriConsumer function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(BiConsumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer4 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(TriConsumer function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer5 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer4 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Consumer6 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer5 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Consumer6 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(BiFunction function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(TriFunction function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(BiFunction function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function4 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(TriFunction function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function5 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function4 function); - /** - * Casts a functional interface to a JavaScript function object. - * - *

- * Note that this casts allows for a reflective access to the function as a - * plain object, but it looses the actual function type. Various APIs take - * function objects as arguments, and this function can be useful in such - * circumstances. - * - * @see jsweet.util.function - */ - native public static def.js.Function function(Function6 function); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function5 function); - /** - * Casts a native Java Boolean to a JavaScript Boolean. - */ - native public static def.js.Boolean bool(Boolean bool); + /** + * Casts a functional interface to a JavaScript function object. + * + *

+ * Note that this casts allows for a reflective access to the function as a + * plain object, but it looses the actual function type. Various APIs take + * function objects as arguments, and this function can be useful in such + * circumstances. + * + * @see jsweet.util.function + */ + native public static def.js.Function function(Function6 function); - /** - * Casts back a JavaScript boolean to a Java boolean. - */ - native public static Boolean bool(def.js.Boolean bool); + /** + * Casts a native Java Boolean to a JavaScript Boolean. + */ + native public static def.js.Boolean bool(Boolean bool); - /** - * Casts a native Java number to a JavaScript Number. - */ - native public static def.js.Number number(Number number); + /** + * Casts back a JavaScript boolean to a Java boolean. + */ + native public static Boolean bool(def.js.Boolean bool); - /** - * Casts back a JavaScript number to a Java integer. - */ - native public static Integer integer(def.js.Number number); + /** + * Casts a native Java number to a JavaScript Number. + */ + native public static def.js.Number number(Number number); - /** - * Casts back a JavaScript number to a Java integer. - */ - native public static Double number(def.js.Number number); + /** + * Casts back a JavaScript number to a Java integer. + */ + native public static Integer integer(def.js.Number number); - /** - * Casts a native Java string to a JavaScript string. - * - *

- * By default, JSweet API use plain Java strings so that the program can - * easily use string literals. However, when the programmer needs to access - * to runtime string manipulation functions, then need to cast to a - * JavaScript string, which allows the access to the standard Web API. - */ - native public static def.js.String string(String string); + /** + * Casts back a JavaScript number to a Java integer. + */ + native public static Double number(def.js.Number number); - /** - * Casts a native Java char to a JavaScript string. - */ - native public static def.js.String string(char c); + /** + * Casts a native Java string to a JavaScript string. + * + *

+ * By default, JSweet API use plain Java strings so that the program can + * easily use string literals. However, when the programmer needs to access + * to runtime string manipulation functions, then need to cast to a + * JavaScript string, which allows the access to the standard Web API. + */ + native public static def.js.String string(String string); - /** - * Casts back a JavaScript string to a Java string. - * - *

- * By default, JSweet API use plain Java strings so that the program can - * easily use string literals. However, when the programmer needs to access - * to runtime string manipulation functions, then need to cast to a - * JavaScript string, which allows the access to the standard Web API. - */ - native public static String string(def.js.String string); + /** + * Casts a native Java char to a JavaScript string. + */ + native public static def.js.String string(char c); - /** - * Casts a native Java object to a JavaScript object. - * - *

- * By default, JSweet API use plain Java objects. However, when the - * programmer needs to access to the standard Web API, they need to cast - * through this function. - */ - native public static def.js.Object object(Object object); + /** + * Casts back a JavaScript string to a Java string. + * + *

+ * By default, JSweet API use plain Java strings so that the program can + * easily use string literals. However, when the programmer needs to access + * to runtime string manipulation functions, then need to cast to a + * JavaScript string, which allows the access to the standard Web API. + */ + native public static String string(def.js.String string); - /** - * This syntax macro should be used to create untyped JavaScript - * objects/maps. It takes a list of key/value pairs, where the keys must be - * string literals and values are objects. - * - *

- * For instance, the expression: - * - *

-	 * $map("responsive", true, "defaultSize", "100px")
-	 * 
- * - *

- * Will be transpiled to: - * - *

-	 * {responsive:true, defaultSize:"100px"}
-	 * 
- * - * @param keyValues - * the key values pairs that initialize the object (keys must be - * string literals) - * @return an untyped object containing the given key/value pairs - */ - native public static def.js.Object $map(Object... keyValues); + /** + * Casts a native Java object to a JavaScript object. + * + *

+ * By default, JSweet API use plain Java objects. However, when the + * programmer needs to access to the standard Web API, they need to cast + * through this function. + */ + native public static def.js.Object object(Object object); - /** - * A syntax macro to construct an array with the given elements. - * - *

- * For instance, the expression: - * - *

-	 * $array("a", "b", "c")
-	 * 
- * - *

- * Will be transpiled to: - * - *

-	 * ["a", "b", "c"]
-	 * 
- * - * - * @param elements - * the elements initializing the array - * @return a new array - */ - @SafeVarargs - native public static def.js.Array $array(E... elements); + /** + * This syntax macro should be used to create untyped JavaScript + * objects/maps. It takes a list of key/value pairs, where the keys must be + * string literals and values are objects. + * + *

+ * For instance, the expression: + * + *

+     * $map("responsive", true, "defaultSize", "100px")
+     * 
+ * + *

+ * Will be transpiled to: + * + *

+     * {responsive:true, defaultSize:"100px"}
+     * 
+ * + * @param keyValues + * the key values pairs that initialize the object (keys must be + * string literals) + * @return an untyped object containing the given key/value pairs + */ + native public static def.js.Object $map(Object... keyValues); - /** - * Uses the target object as a function and call it. This is not typesafe - * and should be avoided. - * - * @param target - * the functional object - * @param arguments - * the call arguments - * @return the function result - */ - native public static T $apply(Object target, Object... arguments); + /** + * A syntax macro to construct an array with the given elements. + * + *

+ * For instance, the expression: + * + *

+     * $array("a", "b", "c")
+     * 
+ * + *

+ * Will be transpiled to: + * + *

+     * ["a", "b", "c"]
+     * 
+ * + * + * @param elements + * the elements initializing the array + * @return a new array + */ + @SafeVarargs + native public static def.js.Array $array(E... elements); - /** - * Uses the target object as a constructor and call it. This is not typesafe - * and should be avoided. - * - * @param target - * the constructor object - * @param arguments - * the call arguments - * @return the constructor result - */ - native public static T $new(Object target, Object... arguments); + /** + * Uses the target object as a function and call it. This is not typesafe + * and should be avoided. + * + * @param target + * the functional object + * @param arguments + * the call arguments + * @return the function result + */ + native public static T $apply(Object target, Object... arguments); - /** - * This helper casts an object to one of the types in a given union type. - * - *

- * The JSweet transpiler will ensure that T is one of T1 and T2. If not, it - * will raise an error. - * - * @param union - * the object typed after a union type - * @return the same object, but typed after one of the types of the union - * type - */ - native public static T union(Union union); + /** + * Uses the target object as a constructor and call it. This is not typesafe + * and should be avoided. + * + * @param target + * the constructor object + * @param arguments + * the call arguments + * @return the constructor result + */ + native public static T $new(Object target, Object... arguments); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static , T> U union(T object); + /** + * This helper casts an object to one of the types in a given union type. + * + *

+ * The JSweet transpiler will ensure that T is one of T1 and T2. If not, it + * will raise an error. + * + * @param union + * the object typed after a union type + * @return the same object, but typed after one of the types of the union + * type + */ + native public static T union(Union union); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static Union3 union3(T object); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static , T> U union(T object); - /** - * This helper casts an object to an union type. - * - *

- * The JSweet transpiler will ensure that T is one of actual type elements - * of U. If not, it will raise an error. - * - * @param union - * the object typed after one of the types of the union type - * @return the same object, but typed after a union type - */ - native public static Union4 union4(T object); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static Union3 union3(T object); - /** - * This utility function allows using the typeof JavaScript - * operator. - * - * The expression typeof(o) transpiles to typeof o - * . See the JavaScript documentation for more details. - */ - native public static String typeof(Object o); + /** + * This helper casts an object to an union type. + * + *

+ * The JSweet transpiler will ensure that T is one of actual type elements + * of U. If not, it will raise an error. + * + * @param union + * the object typed after one of the types of the union type + * @return the same object, but typed after a union type + */ + native public static Union4 union4(T object); - /** - * This syntax macro allows using the == or != - * JavaScript operators. Note that this macro will have no effect on other - * operators than == or !=, but will recursively - * apply to all operators contained in the macro. - * - *

- * Since JSweet version 1.1, the Java expression o1!=o2 - * transpiles to o1!==o2 to remain close to the Java strict - * inequality (except when diffing with the null literal where - * the == operator is used). - * - *

- * Examples: - * - *

-	 * if(a == b) { ... }
-	 * if(a != b) { ... }
-	 * if($loose(a == b)) { ... }
-	 * if($loose(a != b)) { ... }
-	 * if($strict(a == b)) { ... }
-	 * if(a == undefined) { ... }
-	 * if(a != null) { ... }
-	 * if($strict(a != null)) { ... }
-	 * if($loose(a == f(b != a))) { ... }
-	 * 
- * - * Transpile to: - * - *
-	 * if(a === b) { ... }
-	 * if(a !== b) { ... }
-	 * if(a == b) { ... }
-	 * if(a != b) { ... }
-	 * if(a === b) { ... }
-	 * if(a === undefined) { ... }
-	 * if(a != null) { ... }
-	 * if(a !== null) { ... }
-	 * if(a == f(b != a)) { ... }
-	 * 
- * - * @param expression - * can be any expression returning a boolean, but only - * (in)equalities operators will be impacted - * @return the expression modified to use loose JavaScript (in)equalities - * operators - * @since 2.0 - */ - native public static boolean $loose(boolean expression); + /** + * This utility function allows using the typeof JavaScript + * operator. + * + * The expression typeof(o) transpiles to typeof o + * . See the JavaScript documentation for more details. + */ + native public static String typeof(Object o); - /** - * This syntax macro is the reverse of {@link #$loose(boolean)}, and - * enforces strict (in)equalities when it makes sense. - * - * @param expression - * can be any expression returning a boolean, but only - * (in)equalities operators will be impacted - * @return the expression modified to use strict JavaScript (in)equalities - * operators - */ - native public static boolean $strict(boolean expression); + /** + * This syntax macro allows using the == or != + * JavaScript operators. Note that this macro will have no effect on other + * operators than == or !=, but will recursively + * apply to all operators contained in the macro. + * + *

+ * Since JSweet version 1.1, the Java expression o1!=o2 + * transpiles to o1!==o2 to remain close to the Java strict + * inequality (except when diffing with the null literal where + * the == operator is used). + * + *

+ * Examples: + * + *

+     * if(a == b) { ... }
+     * if(a != b) { ... }
+     * if($loose(a == b)) { ... }
+     * if($loose(a != b)) { ... }
+     * if($strict(a == b)) { ... }
+     * if(a == undefined) { ... }
+     * if(a != null) { ... }
+     * if($strict(a != null)) { ... }
+     * if($loose(a == f(b != a))) { ... }
+     * 
+ * + * Transpile to: + * + *
+     * if(a === b) { ... }
+     * if(a !== b) { ... }
+     * if(a == b) { ... }
+     * if(a != b) { ... }
+     * if(a === b) { ... }
+     * if(a === undefined) { ... }
+     * if(a != null) { ... }
+     * if(a !== null) { ... }
+     * if(a == f(b != a)) { ... }
+     * 
+ * + * @param expression + * can be any expression returning a boolean, but only + * (in)equalities operators will be impacted + * @return the expression modified to use loose JavaScript (in)equalities + * operators + * @since 2.0 + */ + native public static boolean $loose(boolean expression); - /** - * Disable type checking on the target object (cast to any). This helper is - * valid in Java. - */ - @SuppressWarnings("unchecked") - public static T any(Object object) { - return (T) object; - } + /** + * This syntax macro is the reverse of {@link #$loose(boolean)}, and + * enforces strict (in)equalities when it makes sense. + * + * @param expression + * can be any expression returning a boolean, but only + * (in)equalities operators will be impacted + * @return the expression modified to use strict JavaScript (in)equalities + * operators + */ + native public static boolean $strict(boolean expression); - /** - * This helper function allows the programmer to reflectively set a global - * variable named "_exportedVar_"+name. - * - *

- * This function must only be used in specifically cases, typically to - * define results when testing from Java. - * - * @param name - * the base name of the exported global variable, necessarily as - * a string literal - * @param value - * the value to set to the variable - */ - public static void $export(String name, Object value) { - // default Java implementation when running in Java (usually for testing - // purposes) - EXPORTED_VARS.get().put("_exportedVar_" + name, value); - } + /** + * Disable type checking on the target object (cast to any). This helper is + * valid in Java. + */ + @SuppressWarnings("unchecked") + public static T any(Object object) { + return (T) object; + } - /** - * Accesses the current JavaScript this. Within an object - * scope, $this corresponds to a regular object oriented - * this. Outside on an object (i.e. within a global function), - * $this has the JavaScript meaning, representing the current - * function object. - */ - public static final def.js.Object $this = null; + /** + * This helper function allows the programmer to reflectively set a global + * variable named "_exportedVar_"+name. + * + *

+ * This function must only be used in specifically cases, typically to + * define results when testing from Java. + * + * @param name + * the base name of the exported global variable, necessarily as + * a string literal + * @param value + * the value to set to the variable + */ + public static void $export(String name, Object value) { + // default Java implementation when running in Java (usually for testing + // purposes) + EXPORTED_VARS.get().put("_exportedVar_" + name, value); + } - /** - * Defines a template string. - * - *

- * For example: - * - *

-	 * console.info($template("Get: ${key} => ${_val}"));
-	 * 
- * - *

- * gets transpiled to: - *

- * - *
-	 * console.info(`Get: ${key} => ${_val}`));
-	 * 
- * - * @param templateString - * the regular Java string to be turned into a template string - * @return a JavaScript template string - */ - public static native String $template(String templateString); + /** + * Accesses the current JavaScript this. Within an object + * scope, $this corresponds to a regular object oriented + * this. Outside on an object (i.e. within a global function), + * $this has the JavaScript meaning, representing the current + * function object. + */ + public static final def.js.Object $this = null; - /** - * Defines a template string with a tag. - * - * @see #$template(String) - */ - public static native String $template(Object tag, String templateString); + /** + * Defines a template string. + * + *

+ * For example: + * + *

+     * console.info($template("Get: ${key} => ${_val}"));
+     * 
+ * + *

+ * gets transpiled to: + *

+ * + *
+     * console.info(`Get: ${key} => ${_val}`));
+     * 
+ * + * @param templateString + * the regular Java string to be turned into a template string + * @return a JavaScript template string + */ + public static native String $template(String templateString); - /** - * Inserts a TypeScript string as is in the generated program (not - * recommended). This can be seen as a compile-time eval. - * - *

- * Although the TypeScript compiler will check the inserted code by - * compiling it, it is obviously a dangerous macro that should be used only - * in last resort. - * - * @see def.js.Globals#eval(String) - */ - public static native String $insert(String typescriptString); + /** + * Defines a template string with a tag. + * + * @see #$template(String) + */ + public static native String $template(Object tag, String templateString); + + /** + * Inserts a TypeScript string as is in the generated program (not + * recommended). This can be seen as a compile-time eval. + * + *

+ * Although the TypeScript compiler will check the inserted code by + * compiling it, it is obviously a dangerous macro that should be used only + * in last resort. + * + * @see def.js.Globals#eval(String) + */ + public static native String $insert(String typescriptString); } diff --git a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java index 1bb89e6c..ed7565a4 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java @@ -4508,7 +4508,8 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { public void visitLambda(JCLambda lamba) { boolean regularFunction = false; if (getParent() instanceof JCMethodInvocation - && ((JCMethodInvocation) getParent()).meth.toString().endsWith("function")) { + && ((JCMethodInvocation) getParent()).meth.toString().endsWith("function") && getParentOfParent() instanceof JCMethodInvocation + && ((JCMethodInvocation) getParentOfParent()).meth.toString().endsWith("$noarrow")) { MethodInvocationElement invocation = (MethodInvocationElement) ExtendedElementFactory.INSTANCE .create(getParent()); if (JSweetConfig.UTIL_CLASSNAME.equals(invocation.getMethod().getEnclosingElement().toString())) { diff --git a/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java b/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java index 2c2eaec1..a52d0d8a 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java @@ -495,6 +495,10 @@ public class Java2TypeScriptAdapter extends PrinterAdapter { print("typeof ").print(invocationElement.getArgument(0)); return true; + case "$noarrow": + print(invocationElement.getArgument(0)); + return true; + case "equalsStrict": print("(").print(invocationElement.getArgument(0)).print(" === ") .print(invocationElement.getArgument(1)).print(")"); diff --git a/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreeScanner.java b/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreeScanner.java index a1c10916..79b63078 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreeScanner.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreeScanner.java @@ -266,6 +266,17 @@ public abstract class AbstractTreeScanner extends TreeScanner { } } + /** + * Returns the parent of the immediate parent in the printer's scanning stack. + */ + public JCTree getParentOfParent() { + if (this.stack.size() >= 3) { + return this.stack.get(this.stack.size() - 3); + } else { + return null; + } + } + /** * Gets the parent element in the printer's scanning stack. */ diff --git a/transpiler/src/test/java/source/decorator/SimpleDecorator.java b/transpiler/src/test/java/source/decorator/SimpleDecorator.java index d0b88f4f..43be3572 100644 --- a/transpiler/src/test/java/source/decorator/SimpleDecorator.java +++ b/transpiler/src/test/java/source/decorator/SimpleDecorator.java @@ -46,7 +46,7 @@ class Globals { Function originalMethod = (Function) descriptor.$get("value"); // editing the descriptor/value parameter - descriptor.$set("value", function(() -> { + descriptor.$set("value", $noarrow(function(() -> { Array args = $array(); for (int _i = 0; _i < arguments.length; _i++) { array(args)[_i - 0] = arguments[_i]; @@ -58,7 +58,7 @@ class Globals { console.log("Call: " + key + "(" + a + ") => " + r); trace.push("Call: " + key + "(" + a + ") => " + r); return result; - })); + }))); // return edited descriptor as opposed to overwriting the descriptor return descriptor;