Add jsinterop.annotations.JsNonNull and JsNullable.

Change-Id: I9c3102440c7f02b06835d1c92567d5b176b30c66
diff --git a/eclipse/settings/code-style/gwt-checkstyle-suppressions.xml b/eclipse/settings/code-style/gwt-checkstyle-suppressions.xml
index 28cce46..c5181f9 100644
--- a/eclipse/settings/code-style/gwt-checkstyle-suppressions.xml
+++ b/eclipse/settings/code-style/gwt-checkstyle-suppressions.xml
@@ -3,6 +3,18 @@
     "-//Puppy Crawl//DTD Suppressions 1.0//EN"
     "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
 <suppressions>
+    <!-- Suppress errors on files with Java 9 syntax.
+         Can be removed when checkstyle is upgraded
+     -->
     <suppress checks="TreeWalker"
         files="user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java8Test.java"/>
+    <!-- Suppress errors on files that use type annotations.
+         Can be removed when checkstyle is upgraded
+      -->
+    <suppress checks="ModifierOrder"
+        files="user/super/com/google/gwt/emul/java/lang/Enum.java"/>
+    <suppress checks="ModifierOrder"
+        files="user/super/com/google/gwt/emul/java/lang/String.java"/>
+    <suppress checks="ModifierOrder"
+        files="user/super/com/google/gwt/emul/java/lang/Throwable.java"/>
 </suppressions>
\ No newline at end of file
diff --git a/eclipse/settings/code-style/gwt-checkstyle.xml b/eclipse/settings/code-style/gwt-checkstyle.xml
index d146bb0..41fdcea 100644
--- a/eclipse/settings/code-style/gwt-checkstyle.xml
+++ b/eclipse/settings/code-style/gwt-checkstyle.xml
@@ -229,4 +229,7 @@
       <property name="onCommentFormat" value="CHECKSTYLE_NAMING_ON"/>
       <property name="checkFormat" value="ParameterName"/>
     </module>
+  <module name="SuppressionFilter">
+    <property name="file" value="eclipse/settings/code-style/gwt-checkstyle-suppressions.xml"/>
+  </module>
 </module>
diff --git a/user/BUILD b/user/BUILD
index cdf4dd7..b8c95b8 100644
--- a/user/BUILD
+++ b/user/BUILD
@@ -27,12 +27,19 @@
 
 load("//third_party/java_src/gwt:build-macros.bzl", "AugmentedJar")
 
+JSINTEROP_SRCS_JAVA7 = glob(
+    ["src/jsinterop/**/*.java"],
+    exclude = [
+        "src/jsinterop/annotations/JsNonNull.java",
+        "src/jsinterop/annotations/JsNullable.java",
+    ],
+)
+
 JSINTEROP_SRCS = glob(["src/jsinterop/**/*.java"])
 
 # GWT JsInterop annotations in a separate library used by hybrid app projects
 java_library(
     name = "gwt-jsinterop-annotations",
-    srcs = JSINTEROP_SRCS,
     compatible_with = [
         "//buildenv/target:android",
         "//buildenv/target:appengine",
@@ -40,6 +47,35 @@
     constraints = [
         "android",
     ],
+    exports = select({
+        "//tools/java_toolchain:java7": [":gwt-jsinterop-annotations_java7"],
+        "//conditions:default": [":gwt-jsinterop-annotations_java8"],
+    }),
+)
+
+java_library(
+    name = "gwt-jsinterop-annotations_java7",
+    srcs = JSINTEROP_SRCS_JAVA7,
+    compatible_with = [
+        "//buildenv/target:android",
+        "//buildenv/target:appengine",
+    ],
+    constraints = [
+        "android",
+    ],
+    visibility = ["//visibility:private"],
+)
+
+java_library(
+    name = "gwt-jsinterop-annotations_java8",
+    srcs = JSINTEROP_SRCS,
+    compatible_with = [
+        "//buildenv/target:android",
+    ],
+    constraints = [
+        "android",
+    ],
+    visibility = ["//visibility:private"],
 )
 
 java_library(
diff --git a/user/src/jsinterop/annotations/JsNonNull.java b/user/src/jsinterop/annotations/JsNonNull.java
new file mode 100644
index 0000000..3872b0c
--- /dev/null
+++ b/user/src/jsinterop/annotations/JsNonNull.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package jsinterop.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * JsNonNull marks a type as non-nullable indicating that program elements of such a type can not
+ * hold a {@code null} value.
+ *
+ * <p>Note that JsNonNull can only be used in a JsConstructor, a JsMethod, a JsProperty or a
+ * JsFunction method.
+ *
+ * <p>This annotation is informational in the GWT compiler but other compilers or tools might use it
+ * for example to annotate types in the output JavaScript program.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE_USE)
+@Documented
+public @interface JsNonNull { }
+
diff --git a/user/src/jsinterop/annotations/JsNullable.java b/user/src/jsinterop/annotations/JsNullable.java
new file mode 100644
index 0000000..b19a1d4
--- /dev/null
+++ b/user/src/jsinterop/annotations/JsNullable.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package jsinterop.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * JsNullable marks a type variable as nullable indicating that program elements of such a type can
+ * hold a {@code null} value.
+ *
+ * <p>Note that JsNullable can only be used on type variables in the context of a JsConstructor,
+ * a JsMethod, a JsProperty or a JsFunction method.
+ *
+ * <p>This annotation is informational in the GWT compiler but other compilers or tools might use it
+ * for example to annotate types in the output JavaScript program.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE_USE)
+@Documented
+public @interface JsNullable { }
diff --git a/user/super/com/google/gwt/emul/java/lang/Enum.java b/user/super/com/google/gwt/emul/java/lang/Enum.java
index 0d9fef0..43a00b9 100644
--- a/user/super/com/google/gwt/emul/java/lang/Enum.java
+++ b/user/super/com/google/gwt/emul/java/lang/Enum.java
@@ -22,9 +22,8 @@
 
 import java.io.Serializable;
 
-import javax.annotation.Nonnull;
-
 import jsinterop.annotations.JsIgnore;
+import jsinterop.annotations.JsNonNull;
 import jsinterop.annotations.JsType;
 
 /**
@@ -117,8 +116,7 @@
     return super.hashCode();
   }
 
-  @Nonnull
-  public final String name() {
+  public final @JsNonNull String name() {
     return name != null ? name : "" + ordinal;
   }
 
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index 33a3fe3..959f9e5 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -28,8 +28,6 @@
 import java.util.Locale;
 import java.util.StringJoiner;
 
-import javax.annotation.Nonnull;
-
 import javaemul.internal.ArrayHelper;
 import javaemul.internal.EmulatedCharset;
 import javaemul.internal.HashCodes;
@@ -38,6 +36,7 @@
 import javaemul.internal.annotations.DoNotInline;
 
 import jsinterop.annotations.JsMethod;
+import jsinterop.annotations.JsNonNull;
 import jsinterop.annotations.JsPackage;
 import jsinterop.annotations.JsProperty;
 import jsinterop.annotations.JsType;
@@ -190,8 +189,7 @@
 
   // valueOf needs to be treated special:
   // J2cl uses it for String concat and thus it can not use string concatenation itself.
-  @Nonnull
-  public static String valueOf(Object x) {
+  public static @JsNonNull String valueOf(Object x) {
     return x == null ? "null" : x.toString();
   }
 
diff --git a/user/super/com/google/gwt/emul/java/lang/Throwable.java b/user/super/com/google/gwt/emul/java/lang/Throwable.java
index 856776e..09558a8 100644
--- a/user/super/com/google/gwt/emul/java/lang/Throwable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Throwable.java
@@ -22,12 +22,11 @@
 import java.io.PrintStream;
 import java.io.Serializable;
 
-import javax.annotation.Nonnull;
-
 import javaemul.internal.JsUtils;
 import javaemul.internal.annotations.DoNotInline;
 
 import jsinterop.annotations.JsMethod;
+import jsinterop.annotations.JsNonNull;
 import jsinterop.annotations.JsProperty;
 import jsinterop.annotations.JsType;
 
@@ -289,8 +288,7 @@
   }
 
   @JsMethod
-  @Nonnull
-  public static Throwable of(Object e) {
+  public static @JsNonNull Throwable of(Object e) {
     // If the JS error is already mapped to a Java Exception, use it.
     if (e != null) {
       Throwable throwable = JsUtils.getProperty(e, "__java$exception");
diff --git a/user/super/com/google/gwt/emul/java/util/List.java b/user/super/com/google/gwt/emul/java/util/List.java
index 8cb824f..f8c3ac7 100644
--- a/user/super/com/google/gwt/emul/java/util/List.java
+++ b/user/super/com/google/gwt/emul/java/util/List.java
@@ -19,10 +19,9 @@
 
 import java.util.function.UnaryOperator;
 
-import javax.annotation.Nonnull;
-
 import jsinterop.annotations.JsIgnore;
 import jsinterop.annotations.JsMethod;
+import jsinterop.annotations.JsNonNull;
 import jsinterop.annotations.JsType;
 
 /**
@@ -84,6 +83,5 @@
     return Spliterators.spliterator(this, Spliterator.ORDERED);
   }
 
-  @Nonnull
-  List<E> subList(int fromIndex, int toIndex);
+  @JsNonNull List<E> subList(int fromIndex, int toIndex);
 }
diff --git a/user/super/com/google/gwt/emul/java/util/Map.java b/user/super/com/google/gwt/emul/java/util/Map.java
index 06106eb..9c134bc 100644
--- a/user/super/com/google/gwt/emul/java/util/Map.java
+++ b/user/super/com/google/gwt/emul/java/util/Map.java
@@ -22,9 +22,8 @@
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
-import javax.annotation.Nonnull;
-
 import jsinterop.annotations.JsIgnore;
+import jsinterop.annotations.JsNonNull;
 import jsinterop.annotations.JsType;
 
 /**
@@ -143,7 +142,7 @@
 
   boolean isEmpty();
 
-  @Nonnull
+  @JsNonNull
   Set<K> keySet();
 
   @JsIgnore
@@ -206,6 +205,5 @@
 
   int size();
 
-  @Nonnull
-  Collection<V> values();
+  @JsNonNull Collection<V> values();
 }
diff --git a/user/test/com/google/gwt/core/client/impl/StackTraceEmulTest.java b/user/test/com/google/gwt/core/client/impl/StackTraceEmulTest.java
index 97e8978..b15ce75 100644
--- a/user/test/com/google/gwt/core/client/impl/StackTraceEmulTest.java
+++ b/user/test/com/google/gwt/core/client/impl/StackTraceEmulTest.java
@@ -67,7 +67,7 @@
     String[] methodNames = getTraceJava();
 
     StackTraceElement[] expectedTrace = new StackTraceElement[] {
-        createSTE(methodNames[0], "Throwable.java", 69),
+        createSTE(methodNames[0], "Throwable.java", 68),
         createSTE(methodNames[1], "Exception.java", 29),
         createSTE(methodNames[2], "StackTraceExamples.java", 57),
         createSTE(methodNames[3], "StackTraceExamples.java", 52),