Version 2.16.0-0.0.dev
Merge commit '4ff053b8b74668357dddcb0b7114571d348cea40' into 'dev'
diff --git a/build/mac/find_sdk.py b/build/mac/find_sdk.py
index d2bf424..e28244a 100755
--- a/build/mac/find_sdk.py
+++ b/build/mac/find_sdk.py
@@ -96,19 +96,16 @@
if job.returncode != 0:
print(out, file=sys.stderr)
print(err, file=sys.stderr)
- raise Exception((
- 'Error %d running xcode-select, you might have to run '
- '|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| '
- 'if you are using Xcode 4.') % job.returncode)
- # The Developer folder moved in Xcode 4.3.
- xcode43_sdk_path = os.path.join(out.rstrip(),
- 'Platforms/MacOSX.platform/Developer/SDKs')
- if os.path.isdir(xcode43_sdk_path):
- sdk_dir = xcode43_sdk_path
- else:
- sdk_dir = os.path.join(out.rstrip(), 'SDKs')
+ raise Exception('Error %d running xcode-select' % job.returncode)
+ sdk_dir = os.path.join(out.rstrip(),
+ 'Platforms/MacOSX.platform/Developer/SDKs')
+ if not os.path.isdir(sdk_dir):
+ raise Exception(
+ 'Install Xcode, launch it, accept the license ' +
+ 'agreement, and run `sudo xcode-select -s /path/to/Xcode.app` ' +
+ 'to continue.')
sdks = [
- re.findall('^MacOSX(1[01]\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)
+ re.findall('^MacOSX(\d+\.\d+)\.sdk$', s) for s in os.listdir(sdk_dir)
]
sdks = [s[0] for s in sdks if s] # [['10.5'], ['10.6']] => ['10.5', '10.6']
sdks = [
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index ce99ad0..9d06f65 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -8,7 +8,7 @@
/// The current version of the Dart language (or, for non-stable releases, the
/// version of the language currently in the process of being developed).
-const _currentVersion = '2.15.0';
+const _currentVersion = '2.16.0';
/// A map containing information about all known experimental flags.
final _knownFeatures = <String, ExperimentalFeature>{
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 4102f5a..582b2c36 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -32,25 +32,25 @@
}
const Version enableAlternativeInvalidationStrategyVersion =
- const Version(2, 15);
-const Version enableConstFunctionsVersion = const Version(2, 15);
+ const Version(2, 16);
+const Version enableConstFunctionsVersion = const Version(2, 16);
const Version enableConstantUpdate2018Version = const Version(2, 0);
const Version enableConstructorTearoffsVersion = const Version(2, 15);
const Version enableControlFlowCollectionsVersion = const Version(2, 0);
-const Version enableEnhancedEnumsVersion = const Version(2, 15);
+const Version enableEnhancedEnumsVersion = const Version(2, 16);
const Version enableExtensionMethodsVersion = const Version(2, 6);
-const Version enableExtensionTypesVersion = const Version(2, 15);
+const Version enableExtensionTypesVersion = const Version(2, 16);
const Version enableGenericMetadataVersion = const Version(2, 14);
-const Version enableNamedArgumentsAnywhereVersion = const Version(2, 15);
+const Version enableNamedArgumentsAnywhereVersion = const Version(2, 16);
const Version enableNonNullableVersion = const Version(2, 12);
const Version enableNonfunctionTypeAliasesVersion = const Version(2, 13);
const Version enableSetLiteralsVersion = const Version(2, 0);
const Version enableSpreadCollectionsVersion = const Version(2, 0);
-const Version enableSuperParametersVersion = const Version(2, 15);
-const Version enableTestExperimentVersion = const Version(2, 15);
+const Version enableSuperParametersVersion = const Version(2, 16);
+const Version enableTestExperimentVersion = const Version(2, 16);
const Version enableTripleShiftVersion = const Version(2, 14);
-const Version enableValueClassVersion = const Version(2, 15);
-const Version enableVarianceVersion = const Version(2, 15);
+const Version enableValueClassVersion = const Version(2, 16);
+const Version enableVarianceVersion = const Version(2, 16);
ExperimentalFlag? parseExperimentalFlag(String flag) {
switch (flag) {
@@ -141,47 +141,47 @@
};
const Map<ExperimentalFlag, Version> experimentEnabledVersion = {
- ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 15),
- ExperimentalFlag.constFunctions: const Version(2, 15),
+ ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 16),
+ ExperimentalFlag.constFunctions: const Version(2, 16),
ExperimentalFlag.constantUpdate2018: const Version(2, 0),
ExperimentalFlag.constructorTearoffs: const Version(2, 15),
ExperimentalFlag.controlFlowCollections: const Version(2, 0),
- ExperimentalFlag.enhancedEnums: const Version(2, 15),
+ ExperimentalFlag.enhancedEnums: const Version(2, 16),
ExperimentalFlag.extensionMethods: const Version(2, 6),
- ExperimentalFlag.extensionTypes: const Version(2, 15),
+ ExperimentalFlag.extensionTypes: const Version(2, 16),
ExperimentalFlag.genericMetadata: const Version(2, 14),
- ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 15),
+ ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 16),
ExperimentalFlag.nonNullable: const Version(2, 12),
ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
ExperimentalFlag.setLiterals: const Version(2, 0),
ExperimentalFlag.spreadCollections: const Version(2, 0),
- ExperimentalFlag.superParameters: const Version(2, 15),
- ExperimentalFlag.testExperiment: const Version(2, 15),
+ ExperimentalFlag.superParameters: const Version(2, 16),
+ ExperimentalFlag.testExperiment: const Version(2, 16),
ExperimentalFlag.tripleShift: const Version(2, 14),
- ExperimentalFlag.valueClass: const Version(2, 15),
- ExperimentalFlag.variance: const Version(2, 15),
+ ExperimentalFlag.valueClass: const Version(2, 16),
+ ExperimentalFlag.variance: const Version(2, 16),
};
const Map<ExperimentalFlag, Version> experimentReleasedVersion = {
- ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 15),
- ExperimentalFlag.constFunctions: const Version(2, 15),
+ ExperimentalFlag.alternativeInvalidationStrategy: const Version(2, 16),
+ ExperimentalFlag.constFunctions: const Version(2, 16),
ExperimentalFlag.constantUpdate2018: const Version(2, 0),
ExperimentalFlag.constructorTearoffs: const Version(2, 15),
ExperimentalFlag.controlFlowCollections: const Version(2, 0),
- ExperimentalFlag.enhancedEnums: const Version(2, 15),
+ ExperimentalFlag.enhancedEnums: const Version(2, 16),
ExperimentalFlag.extensionMethods: const Version(2, 6),
- ExperimentalFlag.extensionTypes: const Version(2, 15),
+ ExperimentalFlag.extensionTypes: const Version(2, 16),
ExperimentalFlag.genericMetadata: const Version(2, 14),
- ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 15),
+ ExperimentalFlag.namedArgumentsAnywhere: const Version(2, 16),
ExperimentalFlag.nonNullable: const Version(2, 10),
ExperimentalFlag.nonfunctionTypeAliases: const Version(2, 13),
ExperimentalFlag.setLiterals: const Version(2, 0),
ExperimentalFlag.spreadCollections: const Version(2, 0),
- ExperimentalFlag.superParameters: const Version(2, 15),
- ExperimentalFlag.testExperiment: const Version(2, 15),
+ ExperimentalFlag.superParameters: const Version(2, 16),
+ ExperimentalFlag.testExperiment: const Version(2, 16),
ExperimentalFlag.tripleShift: const Version(2, 14),
- ExperimentalFlag.valueClass: const Version(2, 15),
- ExperimentalFlag.variance: const Version(2, 15),
+ ExperimentalFlag.valueClass: const Version(2, 16),
+ ExperimentalFlag.variance: const Version(2, 16),
};
const AllowedExperimentalFlags defaultAllowedExperimentalFlags =
diff --git a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.expect b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.expect
index bc4eb86..dfe0844 100644
--- a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.expect
+++ b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart:11:6: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// test(E e) {} // Error.
// ^
//
diff --git a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.outline.expect b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.outline.expect
index 1a1b4af..7be45bb 100644
--- a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.outline.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart:11:6: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// test(E e) {} // Error.
// ^
//
diff --git a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.transformed.expect b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.transformed.expect
index bc4eb86..dfe0844 100644
--- a/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_type_when_experiment_not_enabled.dart:11:6: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// test(E e) {} // Error.
// ^
//
diff --git a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.expect b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.expect
index e55b3b5..0c596cb 100644
--- a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.expect
+++ b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart:9:11: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// extension type E on A {} // Error because of 'type'.
// ^^^^
//
diff --git a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.outline.expect b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.outline.expect
index a219bab..8b21c25 100644
--- a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.outline.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart:9:11: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// extension type E on A {} // Error because of 'type'.
// ^^^^
//
diff --git a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.transformed.expect b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.transformed.expect
index e55b3b5..0c596cb 100644
--- a/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
// Problems in library:
//
// pkg/front_end/testcases/general/extension_types_feature_not_enabled.dart:9:11: Error: This requires the 'extension-types' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.15 or higher, and running 'pub get'.
+// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.16 or higher, and running 'pub get'.
// extension type E on A {} // Error because of 'type'.
// ^^^^
//
diff --git a/pkg/kernel/lib/default_language_version.dart b/pkg/kernel/lib/default_language_version.dart
index 96327d4..d4c3163 100644
--- a/pkg/kernel/lib/default_language_version.dart
+++ b/pkg/kernel/lib/default_language_version.dart
@@ -9,4 +9,4 @@
import "ast.dart";
-Version defaultLanguageVersion = const Version(2, 15);
+Version defaultLanguageVersion = const Version(2, 16);
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index 5ebf334..f1b4d7f 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -6,7 +6,7 @@
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart tools/generate_experimental_flags.dart' to update.
//
-// Current version: 2.15.0
+// Current version: 2.16.0
#include "vm/experimental_features.h"
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index c1db176..020ba59 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -6,7 +6,7 @@
// Instead modify 'tools/experimental_features.yaml' and run
// 'dart tools/generate_experimental_flags.dart' to update.
//
-// Current version: 2.15.0
+// Current version: 2.16.0
#ifndef RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
#define RUNTIME_VM_EXPERIMENTAL_FEATURES_H_
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index c4420c6..23fa301 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -223,6 +223,14 @@
/// Encodes lists of bytes using base64 or base64url encoding.
///
/// The results are ASCII strings using a restricted alphabet.
+///
+/// Example:
+/// ```dart
+/// final base64Encoder = base64.encoder;
+/// const sample = 'Dart is open source';
+/// final encodedSample = base64Encoder.convert(sample.codeUnits);
+/// print(encodedSample); // RGFydCBpcyBvcGVuIHNvdXJjZQ==
+/// ```
class Base64Encoder extends Converter<List<int>, String> {
final bool _urlSafe;
@@ -295,7 +303,7 @@
/// Returns a [Uint8List] of the ASCII codes of the encoded data.
///
/// If the input, including left over [_state] from earlier encodings,
- /// are not a multiple of three bytes, then the partial state is stored
+ /// is not a multiple of three bytes, then the partial state is stored
/// back into [_state].
/// If [isLast] is true, partial state is encoded in the output instead,
/// with the necessary padding.
@@ -469,6 +477,20 @@
/// This decoder accepts both base64 and base64url ("url-safe") encodings.
///
/// The encoding is required to be properly padded.
+///
+/// Throws a [FormatException] if the input is not valid base64 data.
+///
+/// Example:
+/// ```dart
+/// final base64Decoder = base64.decoder;
+/// const base64Bytes = 'RGFydCBpcyBvcGVuIHNvdXJjZQ==';
+/// final decodedBytes = base64Decoder.convert(base64Bytes);
+/// // decodedBytes: [68, 97, 114, 116, 32, 105, 115, 32, 111, 112, 101, 110,
+/// // 32, 115, 111, 117, 114, 99, 101]
+///
+/// // Print as string using UTF-8 decoder
+/// print(utf8.decode(decodedBytes)); // Dart is open source
+/// ```
class Base64Decoder extends Converter<String, List<int>> {
const Base64Decoder();
@@ -726,7 +748,7 @@
/// it needs when input is valid, and at least enough bytes to reach the error
/// when input is invalid.
///
- /// Never count more than two padding sequences since any more than that
+ /// Never count more than two padding sequences as any more than that
/// will raise an error anyway, and we only care about being precise for
/// successful conversions.
static int _trimPaddingChars(String input, int start, int end) {
@@ -777,7 +799,7 @@
/// only call this function after having seen at least one `=` or `%`
/// character.
/// If the number of missing characters is not 3 or 0, we have seen (at least)
- /// a `%` character and expects the rest of the `%3D` sequence, and a `=` is
+ /// a `%` character and expect the rest of the `%3D` sequence, and a `=` is
/// not allowed. When missing 3 characters, either `=` or `%` is allowed.
///
/// When the value is 0, no more padding (or any other character) is allowed.
diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart
index 69b63a0..ced0a4a7 100644
--- a/sdk/lib/convert/html_escape.dart
+++ b/sdk/lib/convert/html_escape.dart
@@ -26,7 +26,7 @@
/// HTML escape modes.
///
-/// Allows specifying a mode for HTML escaping that depend on the context
+/// Allows specifying a mode for HTML escaping that depends on the context
/// where the escaped result is going to be used.
/// The relevant contexts are:
///
@@ -38,6 +38,38 @@
///
/// Custom escape modes can be created using the [HtmlEscapeMode.HtmlEscapeMode]
/// constructor.
+///
+/// Example:
+/// ```dart
+/// const htmlEscapeMode = HtmlEscapeMode(
+/// name: 'custom',
+/// escapeLtGt: true,
+/// escapeQuot: false,
+/// escapeApos: false,
+/// escapeSlash: false,
+/// );
+///
+/// const HtmlEscape htmlEscape = HtmlEscape(htmlEscapeMode);
+/// String unescaped = 'Text & subject';
+/// String escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Text & subject
+///
+/// unescaped = '10 > 1 and 1 < 10';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // 10 > 1 and 1 < 10
+///
+/// unescaped = "Single-quoted: 'text'";
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Single-quoted: 'text'
+///
+/// unescaped = 'Double-quoted: "text"';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Double-quoted: "text"
+///
+/// unescaped = 'Path: /system/';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Path: /system/
+/// ```
class HtmlEscapeMode {
final String _name;
@@ -56,13 +88,13 @@
/// [the Open Web Application Security Project](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content)
final bool escapeSlash;
- /// Default escaping mode which escape all characters.
+ /// Default escaping mode, which escapes all characters.
///
/// The result of such an escaping is usable both in element content and
/// in any attribute value.
///
/// The escaping only works for elements with normal HTML content,
- /// and not for, for example, script or style element content,
+ /// and not, for example, for script or style element content,
/// which require escapes matching their particular content syntax.
static const HtmlEscapeMode unknown =
HtmlEscapeMode._('unknown', true, true, true, true);
@@ -85,14 +117,14 @@
///
/// Escapes single quotes (`'`) but not double quotes (`"`),
/// and escapes `<` and `>` characters because they are not allowed
- /// in strict XHTML attributes
+ /// in strict XHTML attributes.
static const HtmlEscapeMode sqAttribute =
HtmlEscapeMode._('attribute', true, false, true, false);
/// Escaping mode for text going into HTML element content.
///
/// The escaping only works for elements with normal HTML content,
- /// and not for, for example, script or style element content,
+ /// and not, for example, for script or style element content,
/// which require escapes matching their particular content syntax.
///
/// Escapes `<` and `>` characters.
@@ -120,13 +152,13 @@
/// Converter which escapes characters with special meaning in HTML.
///
-/// The converter finds characters that are significant in HTML source and
+/// The converter finds characters that are significant in the HTML source and
/// replaces them with corresponding HTML entities.
///
/// The characters that need escaping in HTML are:
///
-/// * `&` (ampersand) always need to be escaped.
-/// * `<` (less than) and '>' (greater than) when inside an element.
+/// * `&` (ampersand) always needs to be escaped.
+/// * `<` (less than) and `>` (greater than) when inside an element.
/// * `"` (quote) when inside a double-quoted attribute value.
/// * `'` (apostrophe) when inside a single-quoted attribute value.
/// Apostrophe is escaped as `'` instead of `'` since
@@ -137,6 +169,30 @@
/// Escaping `>` (greater than) isn't necessary, but the result is often
/// found to be easier to read if greater-than is also escaped whenever
/// less-than is.
+///
+/// Example:
+/// ```dart
+/// const HtmlEscape htmlEscape = HtmlEscape();
+/// String unescaped = 'Text & subject';
+/// String escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Text & subject
+///
+/// unescaped = '10 > 1 and 1 < 10';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // 10 > 1 and 1 < 10
+///
+/// unescaped = "Single-quoted: 'text'";
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Single-quoted: 'text'
+///
+/// unescaped = 'Double-quoted: "text"';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Double-quoted: "text"
+///
+/// unescaped = 'Path: /system/';
+/// escaped = htmlEscape.convert(unescaped);
+/// print(escaped); // Path: /system/
+/// ```
class HtmlEscape extends Converter<String, String> {
/// The [HtmlEscapeMode] used by the converter.
final HtmlEscapeMode mode;
@@ -145,7 +201,7 @@
///
/// If [mode] is provided as either [HtmlEscapeMode.attribute] or
/// [HtmlEscapeMode.element], only the corresponding subset of HTML
- /// characters are escaped.
+ /// characters is escaped.
/// The default is to escape all HTML characters.
const HtmlEscape([this.mode = HtmlEscapeMode.unknown]);
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index a4aeb6a..cc9afdc 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -76,6 +76,39 @@
///
/// Shorthand for `json.encode`. Useful if a local variable shadows the global
/// [json] constant.
+///
+/// Example:
+/// ```dart
+/// const data = {'text': 'foo', 'value': 2, 'status': false, 'extra': null};
+/// final String jsonString = jsonEncode(data);
+/// print(jsonString); // {"text":"foo","value":2,"status":false,"extra":null}
+/// ```
+///
+/// Example of converting an otherwise unsupported object to a
+/// custom JSON format:
+///
+/// ```dart
+/// class CustomClass {
+/// final String text;
+/// final int value;
+/// CustomClass({required this.text, required this.value});
+/// CustomClass.fromJson(Map<String, dynamic> json)
+/// : text = json['text'],
+/// value = json['value'];
+///
+/// static Map<String, dynamic> toJson(CustomClass value) =>
+/// {'text': value.text, 'value': value.value};
+/// }
+///
+/// void main() {
+/// final CustomClass cc = CustomClass(text: 'Dart', value: 123);
+/// final jsonText = jsonEncode({'cc': cc},
+/// toEncodable: (Object? value) => value is CustomClass
+/// ? CustomClass.toJson(value)
+/// : throw UnsupportedError('Cannot convert to JSON: $value'));
+/// print(jsonText); // {"cc":{"text":"Dart","value":123}}
+/// }
+/// ```
String jsonEncode(Object? object,
{Object? toEncodable(Object? nonEncodable)?}) =>
json.encode(object, toEncodable: toEncodable);
@@ -91,6 +124,32 @@
///
/// Shorthand for `json.decode`. Useful if a local variable shadows the global
/// [json] constant.
+///
+/// Example:
+/// ```dart
+/// const jsonString =
+/// '{"text": "foo", "value": 1, "status": false, "extra": null}';
+///
+/// final data = jsonDecode(jsonString);
+/// print(data['text']); // foo
+/// print(data['value']); // 1
+/// print(data['status']); // false
+/// print(data['extra']); // null
+///
+/// const jsonArray = '''
+/// [{"text": "foo", "value": 1, "status": true},
+/// {"text": "bar", "value": 2, "status": false}]
+/// ''';
+///
+/// final List<dynamic> dataList = jsonDecode(jsonArray);
+/// print(dataList[0]); // {text: foo, value: 1, status: true}
+/// print(dataList[1]); // {text: bar, value: 2, status: false}
+///
+/// final item = dataList[0];
+/// print(item['text']); // foo
+/// print(item['value']); // 1
+/// print(item['status']); // false
+/// ```
dynamic jsonDecode(String source,
{Object? reviver(Object? key, Object? value)?}) =>
json.decode(source, reviver: reviver);
@@ -185,6 +244,30 @@
}
/// This class converts JSON objects to strings.
+///
+/// Example:
+///
+/// ```dart
+/// const JsonEncoder encoder = JsonEncoder();
+/// const data = {'text': 'foo', 'value': '2'};
+///
+/// final String jsonString = encoder.convert(data);
+/// print(jsonString); // {"text":"foo","value":"2"}
+/// ```
+///
+/// Example of pretty-printed output:
+///
+/// ```dart
+/// const JsonEncoder encoder = JsonEncoder.withIndent(' ');
+///
+/// const data = {'text': 'foo', 'value': '2'};
+/// final String jsonString = encoder.convert(data);
+/// print(jsonString);
+/// // {
+/// // "text": "foo",
+/// // "value": "2"
+/// // }
+/// ```
class JsonEncoder extends Converter<Object?, String> {
/// The string used for indention.
///
@@ -478,6 +561,29 @@
/// A JSON input must be the JSON encoding of a single JSON value,
/// which can be a list or map containing other values.
///
+/// Throws [FormatException] if the input is not valid JSON text.
+///
+/// Example:
+/// ```dart
+/// const JsonDecoder decoder = JsonDecoder();
+///
+/// const String jsonString = '''
+/// {
+/// "data": [{"text": "foo", "value": 1 },
+/// {"text": "bar", "value": 2 }],
+/// "text": "Dart"
+/// }
+/// ''';
+///
+/// final Map<String, dynamic> object = decoder.convert(jsonString);
+///
+/// final item = object['data'][0];
+/// print(item['text']); // foo
+/// print(item['value']); // 1
+///
+/// print(object['text']); // Dart
+/// ```
+///
/// When used as a [StreamTransformer], the input stream may emit
/// multiple strings. The concatenation of all of these strings must
/// be a valid JSON encoding of a single JSON value.
diff --git a/tools/VERSION b/tools/VERSION
index f27070e..859524f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
#
CHANNEL dev
MAJOR 2
-MINOR 15
+MINOR 16
PATCH 0
-PRERELEASE 301
+PRERELEASE 0
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 3c3b0a7..45d745b 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -103,7 +103,7 @@
# default 'language' "category" with code generated for both CFE and Analyzer,
# while other categories can be tailored more specifically.
-current-version: '2.15.0'
+current-version: '2.16.0'
features:
variance: