diff --git a/CHANGELOG.md b/CHANGELOG.md index 4767ad8bc8c..f8d9aadded2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.17.0 + +### Core library changes +* `dart:core` + * `Uri.replace` supports iterables as values for the query parameters. + * `Uri.parseIPv6Address` returns a `Uint8List`. + ## 1.16.0 ### Core library changes diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart index dd195023655..d553a33d2f8 100644 --- a/sdk/lib/core/iterable.dart +++ b/sdk/lib/core/iterable.dart @@ -451,7 +451,7 @@ abstract class Iterable { * equivalent to `(iterator..moveNext())..current`. */ E get first { - Iterator it = iterator; + Iterator it = iterator; if (!it.moveNext()) { throw IterableElementError.noElement(); } @@ -469,7 +469,7 @@ abstract class Iterable { * without iterating through the previous ones). */ E get last { - Iterator it = iterator; + Iterator it = iterator; if (!it.moveNext()) { throw IterableElementError.noElement(); } @@ -486,7 +486,7 @@ abstract class Iterable { * Throws a [StateError] if `this` is empty or has more than one element. */ E get single { - Iterator it = iterator; + Iterator it = iterator; if (!it.moveNext()) throw IterableElementError.noElement(); E result = it.current; if (it.moveNext()) throw IterableElementError.tooMany(); @@ -610,9 +610,19 @@ class _GeneratorIterable extends Iterable final int _start; final int _end; final _Generator _generator; + + /// Creates an iterable that builds the elements from a generator function. + /// + /// The [generator] may be null, in which case the default generator + /// enumerating the integer positions is used. This means that [int] must + /// be assignable to [E] when no generator is provided. In practice this means + /// that the generator can only be emitted when [E] is equal to `dynamic`, + /// `int`, or `num`. The constructor will check that the types match. _GeneratorIterable(this._end, E generator(int n)) : _start = 0, - _generator = (generator != null) ? generator : _id; + // The `as` below is used as check to make sure that `int` is assignable + // to [E]. + _generator = (generator != null) ? generator : _id as _Generator; _GeneratorIterable.slice(this._start, this._end, this._generator); diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart index 38587b107ab..21f23eef183 100644 --- a/sdk/lib/core/num.dart +++ b/sdk/lib/core/num.dart @@ -439,14 +439,15 @@ abstract class num implements Comparable { static num parse(String input, [num onError(String input)]) { String source = input.trim(); // TODO(lrn): Optimize to detect format and result type in one check. - num result = int.parse(source, onError: _returnNull); + num result = int.parse(source, onError: _returnIntNull); if (result != null) return result; - result = double.parse(source, _returnNull); + result = double.parse(source, _returnDoubleNull); if (result != null) return result; if (onError == null) throw new FormatException(input); return onError(input); } - /** Helper function for [parse]. */ - static _returnNull(_) => null; + /** Helper functions for [parse]. */ + static int _returnIntNull(String _) => null; + static double _returnDoubleNull(String _) => null; } diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart index a1a5b5d3296..0cfecebe472 100644 --- a/sdk/lib/core/uri.dart +++ b/sdk/lib/core/uri.dart @@ -148,7 +148,7 @@ class Uri { * except for the unreserved characters, and replaces spaces with `+`. * If `query` is the empty string, it is equivalent to omitting it. * To have an actual empty query part, - * use an empty list for `queryParameters`. + * use an empty map for `queryParameters`. * * If both `query` and `queryParameters` are omitted or `null`, * the URI has no query part. @@ -165,7 +165,7 @@ class Uri { String path, Iterable pathSegments, String query, - Map queryParameters, + Map*/> queryParameters, String fragment}) { scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme)); userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo)); @@ -1010,7 +1010,7 @@ class Uri { String path, Iterable pathSegments, String query, - Map queryParameters, + Map*/> queryParameters, String fragment}) { // Set to true if the scheme has (potentially) changed. // In that case, the default port may also have changed and we need @@ -1373,8 +1373,9 @@ class Uri { return _removeDotSegments(path); } - static String _makeQuery(String query, int start, int end, - Map queryParameters) { + static String _makeQuery( + String query, int start, int end, + Map*/> queryParameters) { if (query == null && queryParameters == null) return null; if (query != null && queryParameters != null) { throw new ArgumentError('Both query and queryParameters specified'); @@ -1469,7 +1470,7 @@ class Uri { static String _escapeChar(int char) { assert(char <= 0x10ffff); // It's a valid unicode code point. - List codeUnits; + List codeUnits; if (char < 0x80) { // ASCII, a single percent encoded sequence. codeUnits = new List(3); @@ -2365,8 +2366,7 @@ class Uri { } else if (parts.length != 8) { error('an address without a wildcard must contain exactly 8 parts'); } - // TODO(ajohnsen): Consider using Uint8List. - List bytes = new List(16); + List bytes = new Uint8List(16); for (int i = 0, index = 0; i < parts.length; i++) { int value = parts[i]; if (value == -1) { @@ -2830,7 +2830,7 @@ class UriData { Map parameters, bool base64: false}) { StringBuffer buffer = new StringBuffer(); - List indices = [_noScheme]; + List indices = [_noScheme]; String charsetName; String encodingName; if (parameters != null) charsetName = parameters["charset"]; @@ -2867,7 +2867,7 @@ class UriData { Map parameters, percentEncoded: false}) { StringBuffer buffer = new StringBuffer(); - List indices = [_noScheme]; + List indices = [_noScheme]; _writeUri(mimeType, null, parameters, buffer, indices); indices.add(buffer.length); if (percentEncoded) { @@ -3231,7 +3231,7 @@ class UriData { const int slash = 0x2f; const int semicolon = 0x3b; const int equals = 0x3d; - List indices = [start - 1]; + List indices = [start - 1]; int slashIndex = -1; var char; int i = start; diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart index fd281c50574..f1dce7a9195 100644 --- a/tests/corelib/uri_test.dart +++ b/tests/corelib/uri_test.dart @@ -407,7 +407,8 @@ void testReplace() { var fragment = uri1.hasFragment ? uri1.fragment : null; var tmp1 = uri1; - test() { + + void test() { var tmp2 = new Uri(scheme: scheme, userInfo: userInfo, host: host, port: port, path: path, query: query == "" ? null : query, @@ -452,6 +453,14 @@ void testReplace() { var uri = Uri.parse("/no-authorty/"); uri = uri.replace(fragment: "fragment"); Expect.isFalse(uri.hasAuthority); + + uri = new Uri(scheme: "foo", path: "bar"); + uri = uri.replace( + queryParameters: {"x": ["42", "37"], "y": ["43", "38"]}); + var params = uri.queryParametersAll; + Expect.equals(2, params.length); + Expect.listEquals(["42", "37"], params["x"]); + Expect.listEquals(["43", "38"], params["y"]); } main() {