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) {