Cleanup/update javadoc for jsinterop annotations. Change-Id: I3f64fab263d42705838a557021d5bd67755be7db Review-Link: https://gwt-review.googlesource.com/#/c/17124/
diff --git a/user/src/jsinterop/annotations/JsConstructor.java b/user/src/jsinterop/annotations/JsConstructor.java index 437d06d..f0152cc 100644 --- a/user/src/jsinterop/annotations/JsConstructor.java +++ b/user/src/jsinterop/annotations/JsConstructor.java
@@ -22,11 +22,13 @@ import java.lang.annotation.Target; /** - * JsConstructor marks a constructor that is the constructor function for the JavaScript - * type. - * <p> - * Note that there can only be one JsConstructor in a type; all other constructors must delegate - * to it. + * JsConstructor marks a constructor that will be translated into a JavaScript constructor function. + * + * <p>Due to ES6 class semantics, for non-native JsTypes only one JsConstructor is allowed to exist + * in the type which becomes the 'primary constructor'. All other constructors in the type must + * delegate to it. Subclasses of a type with JsConstructor should follow the same restriction with + * the exception that the primary constructor is not required to be marked as JsConstructor but + * still need to delegate to super primary constructor. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.CONSTRUCTOR)
diff --git a/user/src/jsinterop/annotations/JsFunction.java b/user/src/jsinterop/annotations/JsFunction.java index 4a9c80d..46aea7f 100644 --- a/user/src/jsinterop/annotations/JsFunction.java +++ b/user/src/jsinterop/annotations/JsFunction.java
@@ -22,22 +22,26 @@ import java.lang.annotation.Target; /** - * Marks a type containing a Single Abstract Method (SAM) as eligible for automatic conversion into - * a JavaScript function. - * <p> - * This enables lambda expressions to be passed directly to JavaScript as callbacks. - * <p> - * However there are some additional limitations that are imposed to make this practical and - * efficient: - * <li>A class may not implement more than one @JsFunction type. This restriction allows the - * compiler to construct a one-to-one mapping between the Java class and the generated JavaScript - * function and preserve referential equality. + * JsFunction marks a functional interface as being the definition of a JavaScript function. + * + * <p>There are some limitations exists on JsFunction to make them practical and efficient: + * + * <ul> * <li>A JsFunction interface cannot extend any other interfaces. - * <li>A JsFunction interface cannot have defender methods. - * <li>A class that implements a @JsFunction type (directly or indirectly) cannot be a @JsType. - * <p> - * As a best practice, we also recommend marking @JsFunction interfaces with @FunctionalInterface + * <li>A class may not implement more than one JsFunction interface. + * <li>A class that implements a JsFunction type cannot be a {@link JsType} (directly or + * indirectly). + * <li>Fields and defender methods of the interfaces should be marked with {@link JsOverlay} and + * cannot be overridden by the implementations. + * </ul> + * + * <p>As a best practice, we also recommend marking JsFunction interfaces with FunctionalInterface * to get improved checking in IDEs. + * + * <p><b>Instanceof and Castability:</b> + * + * <p>Instanceof and casting for JsFunction is effectively a JavaScript <tt>'typeof'</tt> check to + * determine if the instance is a function. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE)
diff --git a/user/src/jsinterop/annotations/JsIgnore.java b/user/src/jsinterop/annotations/JsIgnore.java index b2d745a..2cd0591 100644 --- a/user/src/jsinterop/annotations/JsIgnore.java +++ b/user/src/jsinterop/annotations/JsIgnore.java
@@ -23,12 +23,13 @@ /** * Marks a member to be ignored for JsInterop purposes. - * <p> - * This is particularly useful when {@link JsType} applied to a class and some members are needed to - * be ignored as they don't comply with restrictions (e.g. overloading) or shouldn't be exported. + * + * <p>This is particularly useful when {@link JsType} is applied to a class and some members need + * to be ignored as they don't comply with restrictions (e.g. overloading) or shouldn't be exported + * for other reasons. */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD}) +@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD}) @Documented public @interface JsIgnore { }
diff --git a/user/src/jsinterop/annotations/JsOverlay.java b/user/src/jsinterop/annotations/JsOverlay.java index d3b054e..a69be34 100644 --- a/user/src/jsinterop/annotations/JsOverlay.java +++ b/user/src/jsinterop/annotations/JsOverlay.java
@@ -22,13 +22,34 @@ import java.lang.annotation.Target; /** - * JsOverlay is used to add new helper APIs to existing JavaScript types. This is achieved by adding - * the new method/field to a @JsType(isNative=true) and marking it with this annotation. - * <p> - * Note that the JsOverlay methods cannot be called from JavaScript, cannot override any existing - * methods and needs to be marked as final. This is because underneath, the original type is not - * modified and the method is simply turned into a static dispatch. Similarly, JsOverlay fields can - * only be compile time constants. + * JsOverlay is used to enhance Java API of the native JsTypes and JsFunctions so richer and more + * Java friendly abstractions could be provided. + * + * <pre> + * {@literal @}JsType(isNative=true) + * class Person { + * {@literal @}JsOverlay + * private static final Person NO_BODY = new Person(); + * + * private String name; + * private String lastName; + * + * {@literal @}JsOverlay + * public String getFullName() { + * return (name + " " + lastName).trim(); + * } + * }</pre> + * + * <p>Note that: + * + * <ul> + * <li> JsOverlay methods cannot override any existing methods. + * <li> JsOverlay methods should be effectively final. + * <li> JsOverlay methods cannot be called from JavaScript + * </ul> + * + * These restrictions are in place to avoid polymorphism because underneath the original type is not + * modified and the overlay fields/methods are simply turned into static dispatches. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD})
diff --git a/user/src/jsinterop/annotations/JsPackage.java b/user/src/jsinterop/annotations/JsPackage.java index d7c766c..a8ea248 100644 --- a/user/src/jsinterop/annotations/JsPackage.java +++ b/user/src/jsinterop/annotations/JsPackage.java
@@ -30,7 +30,7 @@ @Documented public @interface JsPackage { /** - * Namespace for the global JavaScript object. + * Namespace of the global JavaScript object. */ String GLOBAL = "<global>";
diff --git a/user/src/jsinterop/annotations/JsProperty.java b/user/src/jsinterop/annotations/JsProperty.java index 7d03e03..4c2fb17 100644 --- a/user/src/jsinterop/annotations/JsProperty.java +++ b/user/src/jsinterop/annotations/JsProperty.java
@@ -24,22 +24,23 @@ /** * JsProperty marks a field or method that is translated directly into a JavaScript property * preserving its name. - * <p> - * If it is applied to a method, it will be treated as a property accessor. As a result, instead of - * translating method calls to JsProperty methods as method calls in JS, they will be translated as - * property lookups. When a JsProperty method implemented by a Java class, such methods will be - * generated as custom property setter and getter in JavaScript, hence the property access will - * trigger the execution of the matching getter or setter methods. - * <p> - * JsProperty follows JavaBean style naming convention to extract the default property name. If the - * JavaBean convention is not followed, the name should be set explicitly. For example: + * + * <p>If it is applied to a method, it will be treated as a property accessor. As a result, instead + * of translating method calls to JsProperty methods as method calls in JS, they will be translated + * as property lookups. When a JsProperty method implemented by a Java class, such methods will be + * generated as property accessor in JavaScript, hence the property access will trigger the + * execution of the matching getter or setter methods. + * + * <p>JsProperty follows JavaBean style naming convention to extract the default property name. If + * the JavaBean convention is not followed, the name should be set explicitly. For example: + * * <ul> * <li> {@code @JsProperty getX()} or {@code @JsProperty isX()} translates as <tt>this.x</tt> * <li> {@code @JsProperty setX(int y)} translates as <tt>this.x=y</tt> * </ul> - * <p> - * Note: In JavaScript, instance members are defined on the prototype and class members are defined - * on the constructor function of the type. + * + * <p>Note: In JavaScript, instance members are defined on the prototype and class members are + * defined on the constructor function of the type which mimics ES6 class style. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD}) @@ -48,9 +49,11 @@ /** * Customizes the name of the member in generated JavaScript. If none is provided; - * <p> + * + * <ul> * <li>if it is field, the simple Java name will be used. * <li>if it is a method, the name will be generated based on JavaBean conventions. + * </ul> */ String name() default "<auto>";
diff --git a/user/src/jsinterop/annotations/JsType.java b/user/src/jsinterop/annotations/JsType.java index 7a94109..c6c55c8 100644 --- a/user/src/jsinterop/annotations/JsType.java +++ b/user/src/jsinterop/annotations/JsType.java
@@ -25,31 +25,37 @@ * JsType is used to describe the JavaScript API of an object, either one that already exists from * the external JavaScript environment, or one that will be accessible from the external JavaScript * environment. - * <p> - * Marking an object with JsType is similar to marking each public member of the class with + * + * <p>Marking an object with JsType is similar to marking each public member of the class with * {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} respectively. In order for this to work * correctly the JavaScript name needs to be unique for each member. Some unobvious ways to cause - * name collisions are; - * <p> - * <li>Having method or constructor overloads. - * <li>Using the same name for a method and a field. - * <li>Shadowing a field from parent. - * <p> - * A name collision needs to be avoided by providing a custom name (e.g. {@link JsProperty#name}) or - * by completely ignoring the member using {@link JsIgnore}. - * <p> - * If the JsType is marked as "native", then the type is considered as stub for an existing class - * that is available in native JavaScript. If it is concrete type, the subclass will use the - * designated type as super type opposed to the ordinary one (e.g. java.lang.Object). - * <p> - * Instanceof and Castability: - * <p> - * If the JsTypes is native then the generated code will try to mimic Javascript semantics. - * <li>If it is concrete native JsType then cast checks and instanceof checks will be delegated to - * the native JavaScript instanceof operator. - * <li>If it is an interface and marked as native, no checks will be performed. - * <p> - * All non-native JsTypes will follow regular Java semantics in terms of castability. + * name collisions are: + * + * <ul> + * <li>having method or constructor overloads + * <li>using the same name for a method and a field + * <li>shadowing a field from parent + * </ul> + * + * <p>Name collisions must be avoided by providing custom names (e.g. {@link JsProperty#name}) or by + * ignoring members using {@link JsIgnore}. + * + * <p>If the JsType is marked as "native" via {@link #isNative}, then the type is considered a stub + * for an existing class that is available in native JavaScript. Unlike non-native JsTypes, all + * members are considered {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} unless they are + * explicitly marked with {@link JsOverlay}. + * + * <p><b>Instanceof and Castability:</b> + * + * <p>If the JsType is native, the generated code will try to mimic Javascript semantics. + * + * <p>All non-native JsTypes will follow regular Java semantics in terms of castability. + * + * <ul> + * <li>For concrete native JsTypes, cast checks and instanceof checks will be delegated to the + * native JavaScript instanceof operator. + * <li>For interface native JsTypes, instanceof is forbidden and casts to them always succeed. + * </ul> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE)