Add version information to SDK changes that have happened after 2.0.

Change-Id: I4f49731c446d49e8b49e5c1c29ebcab85e085864
Reviewed-on: https://dart-review.googlesource.com/c/84430
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index b69a600..1021892 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -16,6 +16,7 @@
         UnmodifiableMapView;
 import 'dart:convert';
 import 'dart:developer' hide log;
+import 'dart:_internal' show Since;
 import 'dart:math';
 import 'dart:io';
 import 'dart:typed_data';
@@ -36,6 +37,7 @@
 abstract class HttpStatus {
   static const int continue_ = 100;
   static const int switchingProtocols = 101;
+  @Since("2.1")
   static const int processing = 102;
   static const int ok = 200;
   static const int created = 201;
@@ -44,8 +46,11 @@
   static const int noContent = 204;
   static const int resetContent = 205;
   static const int partialContent = 206;
+  @Since("2.1")
   static const int multiStatus = 207;
+  @Since("2.1")
   static const int alreadyReported = 208;
+  @Since("2.1")
   static const int imUsed = 226;
   static const int multipleChoices = 300;
   static const int movedPermanently = 301;
@@ -55,6 +60,7 @@
   static const int notModified = 304;
   static const int useProxy = 305;
   static const int temporaryRedirect = 307;
+  @Since("2.1")
   static const int permanentRedirect = 308;
   static const int badRequest = 400;
   static const int unauthorized = 401;
@@ -74,16 +80,26 @@
   static const int unsupportedMediaType = 415;
   static const int requestedRangeNotSatisfiable = 416;
   static const int expectationFailed = 417;
+  @Since("2.1")
   static const int misdirectedRequest = 421;
+  @Since("2.1")
   static const int unprocessableEntity = 422;
+  @Since("2.1")
   static const int locked = 423;
+  @Since("2.1")
   static const int failedDependency = 424;
   static const int upgradeRequired = 426;
+  @Since("2.1")
   static const int preconditionRequired = 428;
+  @Since("2.1")
   static const int tooManyRequests = 429;
+  @Since("2.1")
   static const int requestHeaderFieldsTooLarge = 431;
+  @Since("2.1")
   static const int connectionClosedWithoutResponse = 444;
+  @Since("2.1")
   static const int unavailableForLegalReasons = 451;
+  @Since("2.1")
   static const int clientClosedRequest = 499;
   static const int internalServerError = 500;
   static const int notImplemented = 501;
@@ -91,10 +107,15 @@
   static const int serviceUnavailable = 503;
   static const int gatewayTimeout = 504;
   static const int httpVersionNotSupported = 505;
+  @Since("2.1")
   static const int variantAlsoNegotiates = 506;
+  @Since("2.1")
   static const int insufficientStorage = 507;
+  @Since("2.1")
   static const int loopDetected = 508;
+  @Since("2.1")
   static const int notExtended = 510;
+  @Since("2.1")
   static const int networkAuthenticationRequired = 511;
   // Client generated status code.
   static const int networkConnectTimeoutError = 599;
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index b5354bb..b3a5dbd 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -99,9 +99,10 @@
         CastStream,
         CastStreamTransformer,
         EmptyIterator,
+        IterableElementError,
         printToZone,
         printToConsole,
-        IterableElementError;
+        Since;
 
 part 'async_error.dart';
 part 'broadcast_stream_controller.dart';
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index f77ca2c..cb021aa 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -2016,6 +2016,7 @@
    *     (stream) => stream.transform(utf8.decoder).transform(LineSplitter()));
    * ```
    */
+  @Since("2.1")
   factory StreamTransformer.fromBind(Stream<T> Function(Stream<S>) bind) =
       _StreamBindTransformer<S, T>;
 
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index dcdb4ee..728ff9e6 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -163,6 +163,7 @@
    * If multiple [entries] have the same key,
    * later occurrences overwrite the earlier ones.
    */
+  @Since("2.1")
   factory HashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
       HashMap<K, V>()..addEntries(entries);
 }
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 770c6e1..91f95ad 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -151,6 +151,7 @@
    * If multiple [entries] have the same key,
    * later occurrences overwrite the earlier ones.
    */
+  @Since("2.1")
   factory LinkedHashMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
       <K, V>{}..addEntries(entries);
 }
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index ddec7cc..e3014bb 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.dart
@@ -55,16 +55,19 @@
   ///
   /// Returns `true` if both this and [other] are `true`, and `false` otherwise.
   //TODO(lrn): Remove "as bool" in Dart 2.
+  @Since("2.1")
   bool operator &(bool other) => (other as bool) && this;
 
   /// The logical disjunction ("inclusive or") of this and [other].
   ///
   /// Returns `true` if either this or [other] is `true`, and `false` otherwise.
+  @Since("2.1")
   bool operator |(bool other) => (other as bool) || this;
 
   /// The logical exclusive disjunction ("exclusive or") of this and [other].
   ///
   /// Returns whether this and [other] are neither both `true` nor both `false`.
+  @Since("2.1")
   bool operator ^(bool other) => !(other as bool) == this;
 
   /**
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index f58a6a3..9ab8ed4 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -169,6 +169,7 @@
 import "dart:math" show Random; // Used by List.shuffle.
 import "dart:typed_data" show Uint8List, Uint16List, Endian;
 
+@Since("2.1")
 export "dart:async" show Future, Stream;
 
 part "annotations.dart";
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index b772646..1bd829d 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -176,6 +176,7 @@
   /**
    * Throws if [argument] is `null`.
    */
+  @Since("2.1")
   static void checkNotNull(Object argument, [String name]) {
     if (argument == null) throw ArgumentError.notNull(name);
   }
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index 7ffc482..f5ae6a1 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -164,3 +164,41 @@
 /// See this issue for more context:
 /// https://github.com/dart-lang/sdk/issues/31371
 external Object extractTypeArguments<T>(T instance, Function extract);
+
+/// Annotation class marking the version where SDK API was added.
+///
+/// A `Since` annotation can be applied to a library declaration,
+/// any public declaration in a library, or in a class, or to
+/// an optional parameter.
+///
+/// It signifies that the export, member or parameter was *added* in
+/// that version.
+///
+/// When applied to a library declaration, it also a applies to
+/// all members declared or exported by that library.
+/// If applied to a class, it also applies to all members and constructors
+/// of that class.
+/// If applied to a class method, or parameter of such,
+/// any method implementing that interface method is also annotated.
+/// I multiple `Since` annotations apply to the same declaration or
+/// parameter, the latest version takes precendence.
+///
+/// Any use of a marked API may trigger a warning if the using code
+/// does not require an SDK version guaranteeing that the API is available,
+/// unless the API feature is also provided by something else.
+/// It is only a problem if an annotated feature is used, and the annotated
+/// API is the *only* thing providing the functionality.
+/// For example, using `Future` exported by `dart:core` is not a problem
+/// if the same library also imports `dart:async`, and using an optional
+/// parameter on an interface is not a problem if the same type also
+/// implements another interface providing the same parameter.
+///
+/// The version must be a semantic version (like `1.4.2` or `0.9.4-rec.4`),
+/// or the first two numbers of a semantic version (like `1.0` or `2.2`),
+/// representing a stable release, and equivalent to the semantic version
+/// you get by appending a `.0`.
+@Since("2.2")
+class Since {
+  final String version;
+  const Since(this.version);
+}