Move Precondition.gwt.xml logic to Java.
This both makes the logic more Java developer friendly
but also enables us to share it across GWT & J2CL.
This patch removes JSNI flags as it is not used yet.
Change-Id: Ib19dc82c861631dd51767fb2d0d6f21a1d5e7b2a
diff --git a/user/super/com/google/gwt/emul/Preconditions.gwt.xml b/user/super/com/google/gwt/emul/Preconditions.gwt.xml
index 6948ea3..8fc04df 100644
--- a/user/super/com/google/gwt/emul/Preconditions.gwt.xml
+++ b/user/super/com/google/gwt/emul/Preconditions.gwt.xml
@@ -12,116 +12,23 @@
<!-- implied. License for the specific language governing permissions and -->
<!-- limitations under the License. -->
-<!-- Defines support configurable preconditions -->
+<!-- Defines configurable preconditions -->
<module type="fileset">
- <!--
- ┌────────┬─────────────────────────────────────────────────────┬───────────────────────────────┐
- │Group │Description │Common Exception Types │
- ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
- │JSNI │Checks related to arguments and return types of │ClassCastException │
- │ │JSNI methods. (Not implemented yet) │ │
- ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
- │BOUNDS │Checks related to the bound checking in collections. │IndexOutBoundsException │
- │ │ │ArrayIndexOutOfBoundsException │
- ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
- │API │Checks related to the correct usage of APIs. │IllegalStateException │
- │ │ │NoSuchElementException │
- │ │ │NullPointerException │
- │ │ │IllegalArgumentException │
- │ │ │ConcurrentModificationException│
- ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
- │TYPE │Checks related to java type system. │ClassCastException │
- │ │ │ArrayStoreException │
- ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
- │CRITICAL│Checks for cases where not failing-fast will keep │IllegalArgumentException │
- │ │the object in an inconsistent state and/or degrade │ │
- │ │debugging significantly. Currently disabling these │ │
- │ │checks is not supported. │ │
- └────────┴─────────────────────────────────────────────────────┴───────────────────────────────┘
- -->
- <define-property name="jre.checks.jsni" values="ENABLED,DISABLED" />
- <define-property name="jre.checks.bounds" values="ENABLED,DISABLED" />
- <define-property name="jre.checks.api" values="ENABLED,DISABLED" />
- <define-property name="jre.checks.type" values="ENABLED,DISABLED" />
- <define-property name="jre.checks.critical" values="ENABLED" />
+ <define-property name="jre.checks.bounds" values="AUTO,ENABLED,DISABLED" />
+ <define-property name="jre.checks.api" values="AUTO,ENABLED,DISABLED" />
+ <define-property name="jre.checks.type" values="AUTO,ENABLED,DISABLED" />
+ <set-property name="jre.checks.bounds" value="AUTO" />
+ <set-property name="jre.checks.api" value="AUTO" />
+ <set-property name="jre.checks.type" value="AUTO" />
-
- <!--
- ┌────────────────┬─────────┬──────────┬─────────┬─────────┬─────────┐
- │Check level │ JSNI │ BOUNDS │ API │ TYPE │CRITICAL │
- ├────────────────┼─────────┼──────────┼─────────┼─────────┼─────────┤
- │Full │ X │ X │ X │ X │ X │
- ├────────────────┼─────────┼──────────┼─────────┼─────────┼─────────┤
- │Normal (default)│ │ X │ X │ X │ X │
- ├────────────────┼─────────┼──────────┼─────────┼─────────┼─────────┤
- │Optimized │ │ │ │ X │ X │
- ├────────────────┼─────────┼──────────┼─────────┼─────────┼─────────┤
- │Minimal │ │ │ │ │ X │
- ├────────────────┼─────────┼──────────┼─────────┼─────────┼─────────┤
- │None (N/A yet) │ │ │ │ │ │
- └────────────────┴─────────┴──────────┴─────────┴─────────┴─────────┘
- -->
- <define-property name="jre.checks.checkLevel" values="FULL,NORMAL,OPTIMIZED,MINIMAL" />
-
-
- <!-- Associate individual checks with levels -->
-
- <set-property name="jre.checks.jsni" value="DISABLED" />
- <set-property name="jre.checks.jsni" value="ENABLED">
- <any>
- <when-property-is name="jre.checks.checkLevel" value="FULL" />
- </any>
- </set-property>
-
- <set-property name="jre.checks.bounds" value="DISABLED" />
- <set-property name="jre.checks.bounds" value="ENABLED">
- <any>
- <when-property-is name="jre.checks.checkLevel" value="FULL" />
- <when-property-is name="jre.checks.checkLevel" value="NORMAL" />
- </any>
- </set-property>
-
- <set-property name="jre.checks.api" value="DISABLED" />
- <set-property name="jre.checks.api" value="ENABLED">
- <any>
- <when-property-is name="jre.checks.checkLevel" value="FULL" />
- <when-property-is name="jre.checks.checkLevel" value="NORMAL" />
- </any>
- </set-property>
-
-
- <set-property name="jre.checks.type" value="DISABLED" />
- <set-property name="jre.checks.type" value="ENABLED">
- <any>
- <when-property-is name="jre.checks.checkLevel" value="FULL" />
- <when-property-is name="jre.checks.checkLevel" value="NORMAL" />
- <when-property-is name="jre.checks.checkLevel" value="OPTIMIZED" />
- </any>
- </set-property>
-
- <!-- CRITICAL checking cannot be disabled for now.
- <set-property name="jre.checks.critical" value="DISABLED" />
- <set-property name="jre.checks.critical" value="ENABLED">
- <any>
- <when-property-is name="jre.checks.checkLevel" value="FULL" />
- <when-property-is name="jre.checks.checkLevel" value="NORMAL" />
- <when-property-is name="jre.checks.checkLevel" value="OPTIMIZED" />
- <when-property-is name="jre.checks.checkLevel" value="MINIMAL" />
- </any>
- </set-property>
- -->
-
- <!-- End of associations -->
-
-
- <!-- Default checkLevel is NORMAL -->
+ <define-property name="jre.checks.checkLevel" values="NORMAL,OPTIMIZED,MINIMAL" />
<set-property name="jre.checks.checkLevel" value="NORMAL" />
<define-property name="jre.checkedMode" values="ENABLED,DISABLED" />
-
<set-property name="jre.checkedMode" value="DISABLED" />
<set-property name="jre.checkedMode" value="ENABLED">
<when-property-is name="jre.debugMode" value="ENABLED" />
</set-property>
+
</module>
diff --git a/user/super/com/google/gwt/emul/java/util/ConcurrentModificationDetector.java b/user/super/com/google/gwt/emul/java/util/ConcurrentModificationDetector.java
index 0f6300b..8adf867 100644
--- a/user/super/com/google/gwt/emul/java/util/ConcurrentModificationDetector.java
+++ b/user/super/com/google/gwt/emul/java/util/ConcurrentModificationDetector.java
@@ -15,6 +15,7 @@
*/
package java.util;
+import javaemul.internal.InternalPreconditions;
import javaemul.internal.JsUtils;
/**
@@ -23,8 +24,7 @@
*/
class ConcurrentModificationDetector {
- private static final boolean API_CHECK =
- System.getProperty("jre.checks.api", "ENABLED").equals("ENABLED");
+ private static final boolean API_CHECK = InternalPreconditions.isApiChecked();
private static final String MOD_COUNT_PROPERTY = "_gwt_modCount";
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java b/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
index 56812ce..f6868fa 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/InternalPreconditions.java
@@ -15,21 +15,88 @@
*/
package javaemul.internal;
+import static java.lang.System.getProperty;
+
import java.util.NoSuchElementException;
/**
* A utility class that provides utility functions to do precondition checks inside GWT-SDK.
+ * <p>Following table summarizes the grouping of the checks:
+ * <pre>
+ * ┌────────┬─────────────────────────────────────────────────────┬───────────────────────────────┐
+ * │Group │Description │Common Exception Types │
+ * ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
+ * │BOUNDS │Checks related to the bound checking in collections. │IndexOutBoundsException │
+ * │ │ │ArrayIndexOutOfBoundsException │
+ * ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
+ * │API │Checks related to the correct usage of APIs. │IllegalStateException │
+ * │ │ │NoSuchElementException │
+ * │ │ │NullPointerException │
+ * │ │ │IllegalArgumentException │
+ * │ │ │ConcurrentModificationException│
+ * ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
+ * │TYPE │Checks related to java type system. │ClassCastException │
+ * │ │ │ArrayStoreException │
+ * ├────────┼─────────────────────────────────────────────────────┼───────────────────────────────┤
+ * │CRITICAL│Checks for cases where not failing-fast will keep │IllegalArgumentException │
+ * │ │the object in an inconsistent state and/or degrade │ │
+ * │ │debugging significantly. Currently disabling these │ │
+ * │ │checks is not supported. │ │
+ * └────────┴─────────────────────────────────────────────────────┴───────────────────────────────┘
+ * </pre>
+ *
+ * <p> Following table summarizes predefined check levels:
+ * <pre>
+ * ┌────────────────┬──────────┬─────────┬─────────┬─────────┐
+ * │Check level │ BOUNDS │ API │ TYPE │CRITICAL │
+ * ├────────────────┼──────────┼─────────┼─────────┼─────────┤
+ * │Normal (default)│ X │ X │ X │ X │
+ * ├────────────────┼──────────┼─────────┼─────────┼─────────┤
+ * │Optimized │ │ │ X │ X │
+ * ├────────────────┼──────────┼─────────┼─────────┼─────────┤
+ * │Minimal │ │ │ │ X │
+ * ├────────────────┼──────────┼─────────┼─────────┼─────────┤
+ * │None (N/A yet) │ │ │ │ │
+ * └────────────────┴──────────┴─────────┴─────────┴─────────┘
+ * </pre>
+ *
+ * <p>Please note that, in development mode (jre.checkedMode=ENABLED), these checks will always be
+ * performed regardless of configuration but will be converted to AssertionError if check is
+ * disabled. This so that any reliance on related exceptions could be detected early on.
+ * For this detection to work properly; it is important for apps to share the same config in
+ * all environments.
*/
// Some parts adapted from Guava
public final class InternalPreconditions {
- private static final boolean CHECKED_MODE =
- System.getProperty("jre.checkedMode", "ENABLED").equals("ENABLED");
- private static final boolean TYPE_CHECK =
- System.getProperty("jre.checks.type", "ENABLED").equals("ENABLED");
- private static final boolean API_CHECK =
- System.getProperty("jre.checks.api", "ENABLED").equals("ENABLED");
- private static final boolean BOUND_CHECK =
- System.getProperty("jre.checks.bounds", "ENABLED").equals("ENABLED");
+
+ private static final String CHECK_TYPE = getProperty("jre.checks.type");
+ private static final String CHECK_BOUNDS = getProperty("jre.checks.bounds");
+ private static final String CHECK_API = getProperty("jre.checks.api");
+
+ // NORMAL
+ private static final boolean LEVEL_NORMAL_OR_HIGHER =
+ getProperty("jre.checks.checkLevel").equals("NORMAL");
+ // NORMAL or OPTIMIZED
+ private static final boolean LEVEL_OPT_OR_HIGHER =
+ getProperty("jre.checks.checkLevel").equals("OPTIMIZED") || LEVEL_NORMAL_OR_HIGHER;
+ // NORMAL or OPTIMIZED or MINIMAL
+ private static final boolean LEVEL_MINIMAL_OR_HIGHER =
+ getProperty("jre.checks.checkLevel").equals("MINIMAL") || LEVEL_OPT_OR_HIGHER;
+
+ static {
+ if (!LEVEL_MINIMAL_OR_HIGHER) {
+ throw new IllegalStateException("Incorrect level: " + getProperty("jre.checks.checkLevel"));
+ }
+ }
+
+ private static final boolean IS_TYPE_CHECKED =
+ (CHECK_TYPE.equals("AUTO") && LEVEL_OPT_OR_HIGHER) || CHECK_TYPE.equals("ENABLED");
+ private static final boolean IS_BOUNDS_CHECKED =
+ (CHECK_BOUNDS.equals("AUTO") && LEVEL_NORMAL_OR_HIGHER) || CHECK_BOUNDS.equals("ENABLED");
+ private static final boolean IS_API_CHECKED =
+ (CHECK_API.equals("AUTO") && LEVEL_NORMAL_OR_HIGHER) || CHECK_API.equals("ENABLED");
+
+ private static final boolean IS_ASSERTED = getProperty("jre.checkedMode").equals("ENABLED");
/**
* This method reports if the code is compiled with type checks.
@@ -39,13 +106,23 @@
* Please note that {@link #checkType(boolean)} should be preferred where feasible.
*/
public static boolean isTypeChecked() {
- return TYPE_CHECK || CHECKED_MODE;
+ return IS_TYPE_CHECKED || IS_ASSERTED;
+ }
+
+ /**
+ * This method reports if the code is compiled with api checks.
+ * It must be used in places where code can be replaced with a simpler one
+ * when we know that no checks will occur.
+ * Please note that {@code #checkXXX(boolean)} should be preferred where feasible.
+ */
+ public static boolean isApiChecked() {
+ return IS_API_CHECKED || IS_ASSERTED;
}
public static void checkType(boolean expression) {
- if (TYPE_CHECK) {
+ if (IS_TYPE_CHECKED) {
checkCriticalType(expression);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalType(expression);
} catch (Exception e) {
@@ -64,9 +141,9 @@
* Ensures the truth of an expression that verifies array type.
*/
public static void checkArrayType(boolean expression) {
- if (TYPE_CHECK) {
+ if (IS_TYPE_CHECKED) {
checkCriticalArrayType(expression);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArrayType(expression);
} catch (Exception e) {
@@ -85,9 +162,9 @@
* Ensures the truth of an expression that verifies array type.
*/
public static void checkArrayType(boolean expression, Object errorMessage) {
- if (TYPE_CHECK) {
+ if (IS_TYPE_CHECKED) {
checkCriticalArrayType(expression, errorMessage);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArrayType(expression, errorMessage);
} catch (Exception e) {
@@ -106,9 +183,9 @@
* Ensures the truth of an expression involving existence of an element.
*/
public static void checkElement(boolean expression) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalElement(expression);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalElement(expression);
} catch (Exception e) {
@@ -133,9 +210,9 @@
* Ensures the truth of an expression involving existence of an element.
*/
public static void checkElement(boolean expression, Object errorMessage) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalElement(expression, errorMessage);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalElement(expression, errorMessage);
} catch (Exception e) {
@@ -160,9 +237,9 @@
* Ensures the truth of an expression involving one or more parameters to the calling method.
*/
public static void checkArgument(boolean expression) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalArgument(expression);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArgument(expression);
} catch (Exception e) {
@@ -187,9 +264,9 @@
* Ensures the truth of an expression involving one or more parameters to the calling method.
*/
public static void checkArgument(boolean expression, Object errorMessage) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalArgument(expression, errorMessage);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArgument(expression, errorMessage);
} catch (Exception e) {
@@ -215,9 +292,9 @@
*/
public static void checkArgument(boolean expression, String errorMessageTemplate,
Object... errorMessageArgs) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalArgument(expression, errorMessageTemplate, errorMessageArgs);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArgument(expression, errorMessageTemplate, errorMessageArgs);
} catch (Exception e) {
@@ -247,9 +324,9 @@
* @throws IllegalStateException if {@code expression} is false
*/
public static void checkState(boolean expression) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalState(expression);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalState(expression);
} catch (Exception e) {
@@ -276,9 +353,9 @@
* involving any parameters to the calling method.
*/
public static void checkState(boolean expression, Object errorMessage) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalState(expression, errorMessage);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalState(expression, errorMessage);
} catch (Exception e) {
@@ -301,9 +378,9 @@
* Ensures that an object reference passed as a parameter to the calling method is not null.
*/
public static <T> T checkNotNull(T reference) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalNotNull(reference);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalNotNull(reference);
} catch (Exception e) {
@@ -325,9 +402,9 @@
* Ensures that an object reference passed as a parameter to the calling method is not null.
*/
public static void checkNotNull(Object reference, Object errorMessage) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalNotNull(reference, errorMessage);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalNotNull(reference, errorMessage);
} catch (Exception e) {
@@ -346,9 +423,9 @@
* Ensures that {@code size} specifies a valid array size (i.e. non-negative).
*/
public static void checkArraySize(int size) {
- if (API_CHECK) {
+ if (IS_API_CHECKED) {
checkCriticalArraySize(size);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalArraySize(size);
} catch (Exception e) {
@@ -368,9 +445,9 @@
* {@code size}. An element index may range from zero, inclusive, to {@code size}, exclusive.
*/
public static void checkElementIndex(int index, int size) {
- if (BOUND_CHECK) {
+ if (IS_BOUNDS_CHECKED) {
checkCriticalElementIndex(index, size);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalElementIndex(index, size);
} catch (Exception e) {
@@ -390,9 +467,9 @@
* size {@code size}. A position index may range from zero to {@code size}, inclusive.
*/
public static void checkPositionIndex(int index, int size) {
- if (BOUND_CHECK) {
+ if (IS_BOUNDS_CHECKED) {
checkCriticalPositionIndex(index, size);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalPositionIndex(index, size);
} catch (Exception e) {
@@ -413,9 +490,9 @@
* {@code size}, inclusive.
*/
public static void checkPositionIndexes(int start, int end, int size) {
- if (BOUND_CHECK) {
+ if (IS_BOUNDS_CHECKED) {
checkCriticalPositionIndexes(start, end, size);
- } else if (CHECKED_MODE) {
+ } else if (IS_ASSERTED) {
try {
checkCriticalPositionIndexes(start, end, size);
} catch (Exception e) {