Version 0.4.7.0 .
svn merge -r 21386:21520 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@21522 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/README.dart-sdk b/README.dart-sdk
index 9a967c0..8a5c750 100644
--- a/README.dart-sdk
+++ b/README.dart-sdk
@@ -7,14 +7,15 @@
bin/ Binaries/scripts to compile, run, and manage Dart applications.
dart Dart virtual machine
dart2js Dart-to-JavaScript compiler
- dart_analyzer Dart static analyzer
+ dartanalyzer Dart static analyzer
+ dart_analyzer The older, deprecated Dart static analyzer
dartdoc Dart documentation generator
pub Pub, the Dart package manager
lib/ Libraries that are shipped with the Dart runtime. More
information is available at api.dartlang.org.
-pkg/ Additional packages that are shipped outside of the Dart
+packages/ Additional packages that are shipped outside of the Dart
runtime. More information is available at api.dartlang.org.
version The version number of the SDK (ex. 0.1.2.0_r1234).
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index 2d614f39..f016f2a 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -672,7 +672,7 @@
analyzeLibrary(
"class A {",
" void foo();",
- " noSuchMethod(InvocationMirror m) {}",
+ " noSuchMethod(Invocation m) {}",
"}",
"main() {",
" new A();",
@@ -693,7 +693,7 @@
analyzeLibrary(
"class A {",
" void foo();",
- " noSuchMethod(InvocationMirror m) {}",
+ " noSuchMethod(Invocation m) {}",
"}",
"main() {",
" new A();",
@@ -5354,7 +5354,7 @@
String[] lines = {
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
- " noSuchMethod(InvocationMirror invocation) {}",
+ " noSuchMethod(Invocation invocation) {}",
"}",
"class B extends A {}",
"class C {}",
@@ -5396,7 +5396,7 @@
String[] lines = {
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
- " noSuchMethod(InvocationMirror invocation) {}",
+ " noSuchMethod(Invocation invocation) {}",
"}",
"class B extends A {}",
"class C {}",
@@ -5436,7 +5436,7 @@
String[] lines = {
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
- " noSuchMethod(InvocationMirror invocation) {}",
+ " noSuchMethod(Invocation invocation) {}",
"}",
"class B extends A {}",
"class C {}",
diff --git a/dart.gyp b/dart.gyp
index b4f7aa4..6eea60b 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -50,6 +50,7 @@
'dependencies': [
'runtime/dart-runtime.gyp:dart',
'utils/compiler/compiler.gyp:dart2js',
+ 'analyzer',
'compiler',
],
'actions': [
@@ -62,6 +63,7 @@
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
'<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
+ '<(PRODUCT_DIR)/dartanalyzer/dartanalyzer.jar',
],
'outputs': [
'<(PRODUCT_DIR)/dart-sdk/README',
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
index cb730cd..f4806ac 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -38,7 +38,7 @@
var options = new CommandLineOptions.parse(args);
if (options == null) {
- return new Future.immediate(new AnalysisResult.forFailure());
+ return new Future.value(new AnalysisResult.forFailure());
}
//TODO(pquitslund): call out to analyzer...
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index 3d7e2a4..e3e9d02 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -2133,7 +2133,7 @@
List<String> components = new List<String>();
Element ancestor = element;
while (ancestor != null) {
- components.insertRange(0, 1, ((ancestor as ElementImpl)).identifier);
+ components.insert(0, ((ancestor as ElementImpl)).identifier);
ancestor = ancestor.enclosingElement;
}
this._components = new List.from(components);
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 995fa42..d90e510 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -311,7 +311,7 @@
elements.clear();
}
- void remove(Object element) {
+ bool remove(Object element) {
return elements.remove(element);
}
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index 25b0022..26b8d0f 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -164,7 +164,7 @@
}
/// Returns a [Future] that asynchronously completes to `null`.
-Future get async => new Future.immediate(null);
+Future get async => new Future.value();
/// Returns a closed [Stream] with no elements.
Stream get emptyStream => streamFromIterable([]);
@@ -218,8 +218,8 @@
/// Configures [future] so that its result (success or exception) is passed on
/// to [completer].
void chainToCompleter(Future future, Completer completer) {
- future.then((v) => completer.complete(v)).catchError((e) {
- completer.completeError(e.error, e.stackTrace);
+ future.then((v) => completer.complete(v)).catchError((error) {
+ completer.completeError(error);
});
}
@@ -234,7 +234,7 @@
Future forEachFuture(Iterable input, Future fn(element)) {
var iterator = input.iterator;
Future nextElement(_) {
- if (!iterator.moveNext()) return new Future.immediate(null);
+ if (!iterator.moveNext()) return new Future.value();
return fn(iterator.current).then(nextElement);
}
return nextElement(null);
diff --git a/pkg/http/test/mock_client_test.dart b/pkg/http/test/mock_client_test.dart
index f1f75bf..a77d965 100644
--- a/pkg/http/test/mock_client_test.dart
+++ b/pkg/http/test/mock_client_test.dart
@@ -19,7 +19,7 @@
void main() {
test('handles a request', () {
var client = new MockClient((request) {
- return new Future.immediate(new http.Response(
+ return new Future.value(new http.Response(
json.stringify(request.bodyFields), 200,
request: request, headers: {'content-type': 'application/json'}));
});
@@ -57,7 +57,7 @@
test('handles a request with no body', () {
var client = new MockClient((request) {
- return new Future.immediate(new http.Response('you did it', 200));
+ return new Future.value(new http.Response('you did it', 200));
});
expect(client.read("http://example.com/foo"),
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index e7ea1e5..288a445 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -213,7 +213,7 @@
tearDown(() => tempDir.deleteSync(recursive: true));
test('with a file from disk', () {
- expect(new Future.of(() {
+ expect(new Future.sync(() {
var filePath = path.join(tempDir.path, 'test-file');
new File(filePath).writeAsStringSync('hello');
return http.MultipartFile.fromPath('file', filePath);
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index e17589c..2e4c570 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -215,10 +215,10 @@
var request = new http.Request('POST', serverUrl.resolve('/loop?1'))
..maxRedirects = 2;
- var future = request.send().catchError((e) {
+ var future = request.send().catchError((error) {
print("#maxRedirects test exception received");
- expect(e.error, isRedirectLimitExceededException);
- expect(e.error.redirects.length, equals(2));
+ expect(error, isRedirectLimitExceededException);
+ expect(error.redirects.length, equals(2));
});
expect(future.catchError((_) {}).then((_) {
print("#maxRedirects test stopping server...");
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
index 2b388dd..7019df1 100644
--- a/pkg/http/test/safe_http_server.dart
+++ b/pkg/http/test/safe_http_server.dart
@@ -42,23 +42,22 @@
HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
- {void onError(AsyncError error), void onDone(),
- bool unsubscribeOnError: false}) {
+ {void onError(error), void onDone(),
+ bool cancelOnError: false}) {
var subscription;
subscription = super.listen((request) {
onData(new _HttpRequestWrapper(request));
- }, onError: (e) {
- var error = e.error;
+ }, onError: (error) {
// Ignore socket error 104, which is caused by a request being cancelled
// before it writes any headers. There's no reason to care about such
// requests.
if (error is SocketIOException && error.osError.errorCode == 104) return;
// Ignore any parsing errors, which come from malformed requests.
if (error is HttpParserException) return;
- // Manually handle unsubscribeOnError so the above (ignored) errors don't
+ // Manually handle cancelOnError so the above (ignored) errors don't
// cause unsubscription.
- if (unsubscribeOnError) subscription.cancel();
- if (onError != null) onError(e);
+ if (cancelOnError) subscription.cancel();
+ if (onError != null) onError(error);
}, onDone: onDone);
return subscription;
}
@@ -132,10 +131,8 @@
Future<Socket> detachSocket() => _inner.detachSocket();
HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
void add(List<int> data) => _inner.add(data);
- Future<HttpResponse> consume(Stream<List<int>> stream) =>
- _inner.consume(stream);
- Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
- _inner.writeStream(stream);
+ Future<HttpResponse> addStream(Stream<List<int>> stream) =>
+ _inner.addStream(stream);
Future close() => _inner.close();
void write(Object obj) => _inner.write(obj);
void writeAll(Iterable objects, [String separator = ""]) =>
diff --git a/pkg/intl/example/basic/messages_all.dart b/pkg/intl/example/basic/messages_all.dart
index e722f6c..78cb5f0 100644
--- a/pkg/intl/example/basic/messages_all.dart
+++ b/pkg/intl/example/basic/messages_all.dart
@@ -28,7 +28,7 @@
initializeMessages(localeName) {
initializeInternalMessageLookup(() => new CompositeMessageLookup());
messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
- return new Future.immediate(null);
+ return new Future.value();
}
MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
diff --git a/pkg/intl/lib/date_symbol_data_local.dart b/pkg/intl/lib/date_symbol_data_local.dart
index 939bb3d..a8ce2b8 100644
--- a/pkg/intl/lib/date_symbol_data_local.dart
+++ b/pkg/intl/lib/date_symbol_data_local.dart
@@ -31,7 +31,7 @@
Future initializeDateFormatting(String locale, String ignored) {
initializeDateSymbols(dateTimeSymbolMap);
initializeDatePatterns(dateTimePatternMap);
- return new Future.immediate(null);
+ return new Future.value();
}
/**
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 0961d38..26fb304 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -183,7 +183,7 @@
initializeMessages(localeName) {
initializeInternalMessageLookup(() => new CompositeMessageLookup());
messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
- return new Future.immediate(null);
+ return new Future.value();
}
MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
diff --git a/pkg/intl/lib/intl_browser.dart b/pkg/intl/lib/intl_browser.dart
index 76e8d50..995b2c1 100644
--- a/pkg/intl/lib/intl_browser.dart
+++ b/pkg/intl/lib/intl_browser.dart
@@ -27,5 +27,5 @@
*/
Future<String> findSystemLocale() {
Intl.systemLocale = Intl.canonicalizedLocale(window.navigator.language);
- return new Future.immediate(Intl.systemLocale);
+ return new Future.value(Intl.systemLocale);
}
diff --git a/pkg/intl/lib/intl_standalone.dart b/pkg/intl/lib/intl_standalone.dart
index e40126f..fe70ccf 100644
--- a/pkg/intl/lib/intl_standalone.dart
+++ b/pkg/intl/lib/intl_standalone.dart
@@ -43,7 +43,7 @@
return _getAppleDefaults();
}
// We can't find anything, don't set the system locale and return null.
- return new Future.immediate(null);
+ return new Future.value();
}
/**
@@ -83,12 +83,12 @@
* then don't set the variable and return a future that completes with null.
*/
Future<String> _checkResult(ProcessResult result, RegExp regex) {
- if (result.exitCode != 0) return new Future.immediate(null);
+ if (result.exitCode != 0) return new Future.value();
var match = regex.firstMatch(result.stdout);
- if (match == null) return new Future.immediate(null);
+ if (match == null) return new Future.value();
var locale = match.group(1);
_setLocale(locale);
- return new Future.immediate(locale);
+ return new Future.value(locale);
}
/**
@@ -96,5 +96,5 @@
*/
Future<String> _setLocale(aLocale) {
Intl.systemLocale = Intl.canonicalizedLocale(aLocale);
- return new Future.immediate(Intl.systemLocale);
+ return new Future.value(Intl.systemLocale);
}
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index d2610b1..222ff1e 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -48,6 +48,9 @@
/** Controller used to notify when log entries are added to this logger. */
StreamController<LogRecord> _controller;
+ /** The broadcast stream associated with the controller. */
+ Stream _stream;
+
/**
* Singleton constructor. Calling `new Logger(name)` will return the same
* actual instance whenever it is called with the same string name.
@@ -177,9 +180,10 @@
Stream<LogRecord> _getStream() {
if (hierarchicalLoggingEnabled || parent == null) {
if (_controller == null) {
- _controller = new StreamController<LogRecord>.broadcast();
+ _controller = new StreamController<LogRecord>();
+ _stream = _controller.stream.asBroadcastStream();
}
- return _controller.stream;
+ return _stream;
} else {
return root._getStream();
}
diff --git a/pkg/oauth2/lib/src/client.dart b/pkg/oauth2/lib/src/client.dart
index 0d422af..ec8dda5 100644
--- a/pkg/oauth2/lib/src/client.dart
+++ b/pkg/oauth2/lib/src/client.dart
@@ -83,7 +83,7 @@
/// the request if necessary.
Future<http.StreamedResponse> send(http.BaseRequest request) {
return async.then((_) {
- if (!credentials.isExpired) return new Future.immediate(null);
+ if (!credentials.isExpired) return new Future.value();
if (!credentials.canRefresh) throw new ExpirationException(credentials);
return refreshCredentials();
}).then((_) {
diff --git a/pkg/oauth2/test/authorization_code_grant_test.dart b/pkg/oauth2/test/authorization_code_grant_test.dart
index 85c055b..22be3cfa7 100644
--- a/pkg/oauth2/test/authorization_code_grant_test.dart
+++ b/pkg/oauth2/test/authorization_code_grant_test.dart
@@ -33,8 +33,8 @@
}
void expectFutureThrows(future, predicate) {
- future.catchError(expectAsync1((AsyncError e) {
- expect(predicate(e.error), isTrue);
+ future.catchError(expectAsync1((error) {
+ expect(predicate(error), isTrue);
}));
}
@@ -154,7 +154,7 @@
'client_secret': 'secret'
}));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'access token',
'token_type': 'bearer',
}), 200, headers: {'content-type': 'application/json'}));
@@ -198,7 +198,7 @@
'client_secret': 'secret'
}));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'access token',
'token_type': 'bearer',
}), 200, headers: {'content-type': 'application/json'}));
diff --git a/pkg/oauth2/test/client_test.dart b/pkg/oauth2/test/client_test.dart
index 7049122..bac0548 100644
--- a/pkg/oauth2/test/client_test.dart
+++ b/pkg/oauth2/test/client_test.dart
@@ -26,8 +26,8 @@
}
void expectFutureThrows(future, predicate) {
- future.catchError(expectAsync1((AsyncError e) {
- expect(predicate(e.error), isTrue);
+ future.catchError(expectAsync1((error) {
+ expect(predicate(error), isTrue);
}));
}
@@ -57,7 +57,7 @@
httpClient.expectRequest((request) {
expect(request.method, equals('POST'));
expect(request.url.toString(), equals(tokenEndpoint.toString()));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'new access token',
'token_type': 'bearer'
}), 200, headers: {'content-type': 'application/json'}));
@@ -69,7 +69,7 @@
expect(request.headers['authorization'],
equals('Bearer new access token'));
- return new Future.immediate(new http.Response('good job', 200));
+ return new Future.value(new http.Response('good job', 200));
});
expect(client.read(requestUri).then((_) {
@@ -92,7 +92,7 @@
expect(request.headers['authorization'],
equals('Bearer access token'));
- return new Future.immediate(new http.Response('good job', 200));
+ return new Future.value(new http.Response('good job', 200));
});
expect(client.read(requestUri), completion(equals('good job')));
@@ -107,7 +107,7 @@
httpClient.expectRequest((request) {
expect(request.method, equals('POST'));
expect(request.url.toString(), equals(tokenEndpoint.toString()));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'new access token',
'token_type': 'bearer'
}), 200, headers: {'content-type': 'application/json'}));
@@ -144,7 +144,7 @@
var authenticate = 'Bearer error="invalid_token", error_description='
'"Something is terribly wrong."';
- return new Future.immediate(new http.Response('bad job', 401,
+ return new Future.value(new http.Response('bad job', 401,
headers: {'www-authenticate': authenticate}));
});
@@ -163,7 +163,7 @@
expect(request.headers['authorization'],
equals('Bearer access token'));
- return new Future.immediate(new http.Response('bad job', 401));
+ return new Future.value(new http.Response('bad job', 401));
});
expect(
@@ -184,7 +184,7 @@
var authenticate = 'Bearer error="invalid_token", error_description='
'"Something is terribly wrong.", ';
- return new Future.immediate(new http.Response('bad job', 401,
+ return new Future.value(new http.Response('bad job', 401,
headers: {'www-authenticate': authenticate}));
});
@@ -204,7 +204,7 @@
expect(request.headers['authorization'],
equals('Bearer access token'));
- return new Future.immediate(new http.Response('bad job', 401,
+ return new Future.value(new http.Response('bad job', 401,
headers: {'www-authenticate': 'Digest'}));
});
@@ -224,7 +224,7 @@
expect(request.headers['authorization'],
equals('Bearer access token'));
- return new Future.immediate(new http.Response('bad job', 401,
+ return new Future.value(new http.Response('bad job', 401,
headers: {'www-authenticate': 'Bearer'}));
});
diff --git a/pkg/oauth2/test/credentials_test.dart b/pkg/oauth2/test/credentials_test.dart
index 8e40a4a..652d394 100644
--- a/pkg/oauth2/test/credentials_test.dart
+++ b/pkg/oauth2/test/credentials_test.dart
@@ -46,8 +46,8 @@
'access token', null, tokenEndpoint);
expect(credentials.canRefresh, false);
credentials.refresh('identifier', 'secret', httpClient: httpClient)
- .catchError(expectAsync1((e) {
- expect(e.error is StateError, isTrue);
+ .catchError(expectAsync1((error) {
+ expect(error is StateError, isTrue);
}));
});
@@ -55,8 +55,8 @@
var credentials = new oauth2.Credentials('access token', 'refresh token');
expect(credentials.canRefresh, false);
credentials.refresh('identifier', 'secret', httpClient: httpClient)
- .catchError(expectAsync1((e) {
- expect(e.error is StateError, isTrue);
+ .catchError(expectAsync1((error) {
+ expect(error is StateError, isTrue);
}));
});
@@ -76,7 +76,7 @@
"client_secret": "secret"
}));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'new access token',
'token_type': 'bearer',
'refresh_token': 'new refresh token'
@@ -106,7 +106,7 @@
"client_secret": "secret"
}));
- return new Future.immediate(new http.Response(JSON.stringify({
+ return new Future.value(new http.Response(JSON.stringify({
'access_token': 'new access token',
'token_type': 'bearer'
}), 200, headers: {'content-type': 'application/json'}));
diff --git a/pkg/oauth2/test/utils.dart b/pkg/oauth2/test/utils.dart
index b874cc4..9198c80 100644
--- a/pkg/oauth2/test/utils.dart
+++ b/pkg/oauth2/test/utils.dart
@@ -38,7 +38,7 @@
Future<http.Response> _handleRequest(http.Request request) {
if (_handlers.isEmpty) {
- return new Future.immediate(new http.Response('not found', 404));
+ return new Future.value(new http.Response('not found', 404));
} else {
return _handlers.removeFirst()(request);
}
diff --git a/pkg/pathos/lib/path.dart b/pkg/pathos/lib/path.dart
index 0fe031d..5136871 100644
--- a/pkg/pathos/lib/path.dart
+++ b/pkg/pathos/lib/path.dart
@@ -11,6 +11,18 @@
/// functional interface and not require users to create one.
final _builder = new Builder();
+/**
+ * Inserts [length] elements in front of the [list] and fills them with the
+ * [fillValue].
+ */
+void _growListFront(List list, int length, fillValue) {
+ list.length += length;
+ list.setRange(length, list.length, list);
+ for (var i = 0; i < length; i++) {
+ list[i] = fillValue;
+ }
+}
+
/// Gets the path to the current working directory.
String get current => new io.Directory.current().path;
@@ -408,7 +420,7 @@
// Filter out empty parts that exist due to multiple separators in a row.
parsed.parts = parsed.parts.where((part) => !part.isEmpty)
.toList();
- if (parsed.root != null) parsed.parts.insertRange(0, 1, parsed.root);
+ if (parsed.root != null) parsed.parts.insert(0, parsed.root);
return parsed.parts;
}
@@ -503,9 +515,9 @@
// If there are any directories left in the root path, we need to walk up
// out of them.
- pathParsed.parts.insertRange(0, fromParsed.parts.length, '..');
- pathParsed.separators.insertRange(0, fromParsed.parts.length,
- style.separator);
+ _growListFront(pathParsed.parts, fromParsed.parts.length, '..');
+ _growListFront(
+ pathParsed.separators, fromParsed.parts.length, style.separator);
// Corner case: the paths completely collapsed.
if (pathParsed.parts.length == 0) return '.';
@@ -678,7 +690,7 @@
// A relative path can back out from the start directory.
if (!isAbsolute) {
- newParts.insertRange(0, leadingDoubles, '..');
+ _growListFront(newParts, leadingDoubles, '..');
}
// If we collapsed down to nothing, do ".".
@@ -688,7 +700,7 @@
// Canonicalize separators.
var newSeparators = [];
- newSeparators.insertRange(0, newParts.length, style.separator);
+ _growListFront(newSeparators, newParts.length, style.separator);
parts = newParts;
separators = newSeparators;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 959a310..195a42f 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -2,6 +2,9 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
+serialization/test/*: Skip # http://dartbug.com/9894
+
+
# Run this test manually to verify that the fixnum library produces
# the same results as native ints on a set of directed and random inputs.
# Skip it when running automated tests because it times out. This
@@ -120,7 +123,8 @@
[ $compiler == dart2js && $minified ]
# The unittest package relies on getting the original (non-minified) method
-# names in InvocationMirrors. You can't get that when minifying.
+# names in Invocation. You can't get that when minifying.
+# TODO(ahe/erikcorry): But soon you can, now that we use Symbol.
unittest/test/mock_test: Fail
unittest/test/mock_regexp_negative_test: Fail
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index cf37211..45e5061 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -134,9 +134,9 @@
_handleExit(exitCodeCompleter);
return Future.wait([
- new Future.of(() => executable),
+ new Future.sync(() => executable),
awaitObject(arguments),
- new Future.of(() => options)
+ new Future.sync(() => options)
]).then((results) {
executable = results[0];
arguments = results[1];
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
index 1ad8ac2..cb17268 100644
--- a/pkg/scheduled_test/lib/scheduled_server.dart
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -91,7 +91,7 @@
/// responsibility to check that the method/path are correct and that it's
/// being run at the correct time.
void _handleRequest(HttpRequest request) {
- wrapFuture(new Future.of(() {
+ wrapFuture(new Future.sync(() {
if (_handlers.isEmpty) {
throw "'$description' received ${request.method} ${request.uri.path} "
"when no more requests were expected.";
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index b46dc45..6e7b754 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -228,8 +228,6 @@
assert(e.schedule.errors.contains(e));
assert(e.schedule == currentSchedule);
unittest.registerException(e.schedule.errorString());
- } else if (e is AsyncError) {
- unittest.registerException(e.error, e.stackTrace);
} else {
unittest.registerException(e);
}
diff --git a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
index d07b5bc..97f8c92 100644
--- a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
@@ -46,9 +46,9 @@
}
return Future.wait(contents.map((entry) {
- return new Future.of(() => entry.validateNow(fullPath))
+ return new Future.sync(() => entry.validateNow(fullPath))
.then((_) => null)
- .catchError((e) => e.error);
+ .catchError((e) => e);
})).then((results) {
var errors = results.where((e) => e != null);
if (errors.isEmpty) return;
@@ -57,7 +57,7 @@
}
Stream<List<int>> load(String pathToLoad) {
- return futureStream(new Future.immediate(null).then((_) {
+ return futureStream(new Future.value().then((_) {
if (_path.isAbsolute(pathToLoad)) {
throw "Can't load absolute path '$pathToLoad'.";
}
diff --git a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
index 75327d1..f56f720 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
@@ -63,7 +63,7 @@
});
}
- Stream<List<int>> read() => new Future.immediate(contents).asStream();
+ Stream<List<int>> read() => new Future.value(contents).asStream();
String describe() => name;
diff --git a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
index e56db2a..1cc47f5 100644
--- a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
@@ -19,12 +19,12 @@
NothingDescriptor(String name)
: super(name);
- Future create([String parent]) => new Future.immediate(null);
+ Future create([String parent]) => new Future.value();
Future validate([String parent]) => schedule(() => validateNow(parent),
"validating '$name' doesn't exist");
- Future validateNow([String parent]) => new Future.of(() {
+ Future validateNow([String parent]) => new Future.sync(() {
if (parent == null) parent = defaultRoot;
var fullPath = path.join(parent, name);
if (new File(fullPath).existsSync()) {
diff --git a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
index 3735f82..7eb0c61 100644
--- a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
@@ -62,8 +62,8 @@
var descriptor = _fn(path.basename(entry));
return descriptor.validateNow(parent).then((_) {
return new Pair(null, descriptor.describe());
- }).catchError((e) {
- return new Pair(e.error.toString(), descriptor.describe());
+ }).catchError((error) {
+ return new Pair(error.toString(), descriptor.describe());
});
})).then((results) {
var matches = results.where((result) => result.first == null).toList();
@@ -110,7 +110,7 @@
return '/${regExp.pattern}/$flags';
}
- Future create([String parent]) => new Future.immediateError(
+ Future create([String parent]) => new Future.error(
new UnsupportedError("Pattern descriptors don't support create()."));
Stream<List<int>> load(String pathToLoad) => errorStream(
diff --git a/pkg/scheduled_test/lib/src/future_group.dart b/pkg/scheduled_test/lib/src/future_group.dart
index 213f0fc..f1f64db 100644
--- a/pkg/scheduled_test/lib/src/future_group.dart
+++ b/pkg/scheduled_test/lib/src/future_group.dart
@@ -34,11 +34,11 @@
completed = true;
_completer.complete(_values);
}
- }).catchError((e) {
+ }).catchError((error) {
if (completed) return;
completed = true;
- _completer.completeError(e.error, e.stackTrace);
+ _completer.completeError(error);
}));
return task;
diff --git a/pkg/scheduled_test/lib/src/mock_clock.dart b/pkg/scheduled_test/lib/src/mock_clock.dart
index a4bbdee..6abe81f 100644
--- a/pkg/scheduled_test/lib/src/mock_clock.dart
+++ b/pkg/scheduled_test/lib/src/mock_clock.dart
@@ -45,8 +45,15 @@
int _time = 0;
/// The stream of millisecond ticks of the clock.
- Stream<int> get onTick => _onTickController.stream;
- final _onTickController = new StreamController<int>.broadcast();
+ Stream<int> get onTick {
+ if (_onTickControllerStream == null) {
+ _onTickControllerStream = _onTickController.stream.asBroadcastStream();
+ }
+ return _onTickControllerStream;
+ }
+
+ final _onTickController = new StreamController<int>();
+ Stream<int> _onTickControllerStream;
Clock._();
@@ -57,7 +64,7 @@
void tick([int milliseconds=1]) {
for (var i = 0; i < milliseconds; i++) {
var tickTime = ++_time;
- new Future.immediate(null).then((_) => _onTickController.add(tickTime));
+ new Future.value().then((_) => _onTickController.add(tickTime));
}
}
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index 2569b4b..ecdf4dd 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -131,7 +131,7 @@
/// Sets up this schedule by running [setUp], then runs all the task queues in
/// order. Any errors in [setUp] will cause [onException] to run.
Future run(void setUp()) {
- return new Future.immediate(null).then((_) {
+ return new Future.value().then((_) {
try {
setUp();
} catch (e, stackTrace) {
@@ -188,7 +188,7 @@
/// Signals that an out-of-band error has occurred. Using [wrapAsync] along
/// with `throw` is usually preferable to calling this directly.
///
- /// The metadata in [AsyncError]s and [ScheduleError]s will be preserved.
+ /// The metadata in [ScheduleError]s will be preserved.
void signalError(error, [stackTrace]) {
heartbeat();
@@ -432,13 +432,13 @@
if (isRunning) {
var task = _schedule.currentTask;
var wrappedFn = () => _schedule.wrapFuture(
- new Future.immediate(null).then((_) => fn()));
+ new Future.value().then((_) => fn()));
if (task == null) return wrappedFn();
return task.runChild(wrappedFn, description);
}
var task = new Task(() {
- return new Future.of(fn).catchError((e) {
+ return new Future.sync(fn).catchError((e) {
throw new ScheduleError.from(_schedule, e);
});
}, description, this);
@@ -557,7 +557,7 @@
} else if (_taskFuture != null) {
// Catch errors coming off the old task future, in case it completes after
// timing out.
- _taskFuture.substitute(new Future.immediateError(error)).catchError((e) {
+ _taskFuture.substitute(new Future.error(error)).catchError((e) {
_schedule._signalPostTimeoutError(e);
});
} else {
diff --git a/pkg/scheduled_test/lib/src/schedule_error.dart b/pkg/scheduled_test/lib/src/schedule_error.dart
index 7b66391..09bb350 100644
--- a/pkg/scheduled_test/lib/src/schedule_error.dart
+++ b/pkg/scheduled_test/lib/src/schedule_error.dart
@@ -13,7 +13,13 @@
import 'utils.dart';
/// A wrapper for errors that occur during a scheduled test.
-class ScheduleError extends AsyncError {
+class ScheduleError {
+ /// The wrapped error.
+ final error;
+
+ /// The stack trace that was attached to the error. Can be `null`.
+ final stackTrace;
+
/// The schedule during which this error occurred.
final Schedule schedule;
@@ -33,33 +39,33 @@
final ScheduleState _stateWhenDetected;
int get hashCode => schedule.hashCode ^ task.hashCode ^ queue.hashCode ^
- _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode ^
- cause.hashCode;
+ _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode;
/// Creates a new [ScheduleError] wrapping [error]. The metadata in
- /// [AsyncError]s and [ScheduleError]s will be preserved.
- factory ScheduleError.from(Schedule schedule, error, {StackTrace stackTrace,
- AsyncError cause}) {
+ /// [ScheduleError]s will be preserved.
+ factory ScheduleError.from(Schedule schedule, error,
+ {StackTrace stackTrace}) {
if (error is ScheduleError) return error;
- if (error is AsyncError) {
+ var attachedTrace = getAttachedStackTrace(error);
+ if (attachedTrace != null) {
// Overwrite the explicit stack trace, because it probably came from a
// rethrow in the first place.
- stackTrace = error.stackTrace;
- if (cause == null) cause = error.cause;
- error = error.error;
+ stackTrace = attachedTrace;
}
if (schedule.captureStackTraces && stackTrace == null) {
stackTrace = new Trace.current();
}
- return new ScheduleError(schedule, error, stackTrace, cause);
+ return new ScheduleError(schedule, error, stackTrace);
}
- ScheduleError(Schedule schedule, error, StackTrace stackTrace,
- AsyncError cause)
- : super.withCause(error, stackTrace, cause),
+ // TODO(floitsch): restore StackTrace type when it has been integrated into
+ // the core libraries.
+ ScheduleError(Schedule schedule, error, var stackTrace)
+ : error = error,
+ stackTrace = stackTrace,
schedule = schedule,
task = schedule.currentTask,
queue = schedule.currentQueue,
@@ -69,8 +75,7 @@
bool operator ==(other) => other is ScheduleError && task == other.task &&
queue == other.queue && _stateWhenDetected == other._stateWhenDetected &&
- error == other.error && stackTrace == other.stackTrace &&
- cause == other.cause;
+ error == other.error && stackTrace == other.stackTrace;
String toString() {
var result = new StringBuffer();
diff --git a/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
index 83609f5..599613d 100644
--- a/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
@@ -66,11 +66,10 @@
currentSchedule.wrapFuture(item.then((value) {
if (_matcher == null) return;
- try {
- expect(value, _matcher);
- } catch (e, stackTrace) {
- throw new AsyncError(e, outerTrace);
- }
+ // TODO(floitsch): we cannot switch traces anymore.
+ // If expect throws we might want to be able to switch to the outer trace
+ // instead.
+ expect(value, _matcher);
}), description);
return true;
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
index 6be6b1c..4d6c6b8 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
@@ -54,7 +54,7 @@
// between a test failing while waiting for a handler and a test failing
// while executing a handler.
chainToCompleter(schedule(() {
- return new Future.of(() {
+ return new Future.sync(() {
if (request.method != method || request.uri.path != path) {
throw "'${server.description}' expected $method $path, "
"but got ${request.method} ${request.uri.path}.";
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
index 7e4e4cc..2e5b9cc 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
@@ -42,22 +42,21 @@
HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
- {void onError(AsyncError error), void onDone(),
- bool unsubscribeOnError: false}) {
+ {void onError(error), void onDone(),
+ bool cancelOnError: false}) {
var subscription;
subscription = super.listen((request) {
onData(new _HttpRequestWrapper(request));
- }, onError: (e) {
- var error = e.error;
+ }, onError: (error) {
// Ignore socket error 104, which is caused by a request being cancelled
// before it writes any headers. There's no reason to care about such
// requests.
if (error is SocketIOException && error.osError.errorCode == 104) return;
// Ignore any parsing errors, which come from malformed requests.
if (error is HttpParserException) return;
- // Manually handle unsubscribeOnError so the above (ignored) errors don't
+ // Manually handle cancelOnError so the above (ignored) errors don't
// cause unsubscription.
- if (unsubscribeOnError) subscription.cancel();
+ if (cancelOnError) subscription.cancel();
if (onError != null) onError(e);
}, onDone: onDone);
return subscription;
@@ -132,12 +131,8 @@
Future<Socket> detachSocket() => _inner.detachSocket();
HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
void add(List<int> data) => _inner.add(data);
- Future<HttpResponse> consume(Stream<List<int>> stream) =>
- _inner.consume(stream);
Future<HttpResponse> addStream(Stream<List<int>> stream) =>
- _inner.writeStream(stream);
- Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
- _inner.writeStream(stream);
+ _inner.addStream(stream);
Future close() => _inner.close();
void write(Object obj) => _inner.write(obj);
void writeAll(Iterable objects, [String separator = ""]) =>
diff --git a/pkg/scheduled_test/lib/src/substitute_future.dart b/pkg/scheduled_test/lib/src/substitute_future.dart
index 4122a3d..abbb5d4 100644
--- a/pkg/scheduled_test/lib/src/substitute_future.dart
+++ b/pkg/scheduled_test/lib/src/substitute_future.dart
@@ -24,9 +24,9 @@
}
Stream<T> asStream() => _completer.future.asStream();
- Future catchError(onError(AsyncError asyncError), {bool test(error)}) =>
+ Future catchError(onError(asyncError), {bool test(error)}) =>
_completer.future.catchError(onError, test: test);
- Future then(onValue(T value), {onError(AsyncError asyncError)}) =>
+ Future then(onValue(T value), {onError(error)}) =>
_completer.future.then(onValue, onError: onError);
Future<T> whenComplete(action()) => _completer.future.whenComplete(action);
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index aabdbba..e77f531 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -79,7 +79,7 @@
}
_state = TaskState.RUNNING;
- var future = new Future.immediate(null).then((_) => fn())
+ var future = new Future.value().then((_) => fn())
.whenComplete(() {
if (_childGroup == null || _childGroup.completed) return;
return _childGroup.future;
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index 419e47e..6e4c636 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -50,8 +50,8 @@
/// times. By default, this should pump the event queue enough times to allow
/// any code to run, as long as it's not waiting on some external event.
Future pumpEventQueue([int times=20]) {
- if (times == 0) return new Future.immediate(null);
- return new Future.immediate(null).then((_) => pumpEventQueue(times - 1));
+ if (times == 0) return new Future.value();
+ return new Future.value().then((_) => pumpEventQueue(times - 1));
}
/// Returns whether [iterable1] has the same elements in the same order as
@@ -71,7 +71,7 @@
// TODO(nweiz): remove this when issue 8731 is fixed.
/// Returns a [Stream] that will immediately emit [error] and then close.
-Stream errorStream(error) => new Future.immediateError(error).asStream();
+Stream errorStream(error) => new Future.error(error).asStream();
/// Returns a buffered stream that will emit the same values as the stream
/// returned by [future] once [future] completes. If [future] completes to an
@@ -107,10 +107,10 @@
subscription.cancel();
completer.complete(value);
}, onError: (e) {
- completer.completeError(e.error, e.stackTrace);
+ completer.completeError(e);
}, onDone: () {
completer.completeError(new StateError("No elements"), stackTrace);
- }, unsubscribeOnError: true);
+ }, cancelOnError: true);
return completer.future;
}
@@ -122,15 +122,16 @@
/// the wrapped stream. Unlike [StreamSubscription], this canceller will send a
/// "done" message to the wrapped stream.
Pair<Stream, StreamCanceller> streamWithCanceller(Stream stream) {
- var controller = stream.isBroadcast ?
- new StreamController.broadcast() :
- new StreamController();
+ var controller = new StreamController();
+ var controllerStream = stream.isBroadcast ?
+ controller.stream.asBroadcastStream() :
+ controller.stream;
var subscription = stream.listen((value) {
if (!controller.isClosed) controller.add(value);
}, onError: (error) {
if (!controller.isClosed) controller.signalError(error);
}, onDone: controller.close);
- return new Pair<Stream, StreamCanceller>(controller.stream, controller.close);
+ return new Pair<Stream, StreamCanceller>(controllerStream, controller.close);
}
// TODO(nweiz): remove this when issue 7787 is fixed.
@@ -162,7 +163,7 @@
if (object is Iterable) {
return Future.wait(object.map(awaitObject).toList());
}
- if (object is! Map) return new Future.immediate(object);
+ if (object is! Map) return new Future.value(object);
var pairs = <Future<Pair>>[];
object.forEach((key, value) {
diff --git a/pkg/scheduled_test/lib/src/value_future.dart b/pkg/scheduled_test/lib/src/value_future.dart
index 41ffcc0..8aa2c62 100644
--- a/pkg/scheduled_test/lib/src/value_future.dart
+++ b/pkg/scheduled_test/lib/src/value_future.dart
@@ -30,9 +30,9 @@
}
Stream<T> asStream() => _future.asStream();
- Future catchError(onError(AsyncError asyncError), {bool test(error)}) =>
+ Future catchError(onError(Object error), {bool test(error)}) =>
_future.catchError(onError, test: test);
- Future then(onValue(T value), {onError(AsyncError asyncError)}) =>
+ Future then(onValue(T value), {onError(Object error)}) =>
_future.then(onValue, onError: onError);
Future<T> whenComplete(action()) => _future.whenComplete(action);
}
diff --git a/pkg/scheduled_test/test/descriptor/async_test.dart b/pkg/scheduled_test/test/descriptor/async_test.dart
index b35718f..1726345 100644
--- a/pkg/scheduled_test/test/descriptor/async_test.dart
+++ b/pkg/scheduled_test/test/descriptor/async_test.dart
@@ -126,7 +126,7 @@
test('test', () {
scheduleSandbox();
- expect(d.async(new Future.immediate(d.file('name.txt')))
+ expect(d.async(new Future.value(d.file('name.txt')))
.load('path').toList(),
throwsA(equals("AsyncDescriptors don't support load().")));
});
@@ -136,7 +136,7 @@
test('test', () {
scheduleSandbox();
- expect(d.async(new Future.immediate(d.file('name.txt'))).read().toList(),
+ expect(d.async(new Future.value(d.file('name.txt'))).read().toList(),
throwsA(equals("AsyncDescriptors don't support read().")));
});
});
diff --git a/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart b/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
index 6ea9e59..25bba20 100644
--- a/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
@@ -32,6 +32,7 @@
}, passing: ['test 2']);
expectTestsPass('does not capture a stack trace if set to false', () {
+ var errorThrown = new Object();
var error;
test('test 1', () {
currentSchedule.captureStackTraces = false;
@@ -39,7 +40,7 @@
error = currentSchedule.errors.first;
});
- schedule(() => throw 'error');
+ schedule(() => throw errorThrown);
});
test('test 2', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
index 2e7a10b..047cd3b 100644
--- a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
@@ -89,6 +89,7 @@
expectTestsPass("nested scheduled blocks whose return values are passed to "
"wrapFuture should report exceptions once", () {
+ var error = new Object();
var errors;
test('test 1', () {
currentSchedule.onException.schedule(() {
@@ -97,7 +98,7 @@
schedule(() {
wrapFuture(schedule(() {
- throw 'error';
+ throw error;
}));
return pumpEventQueue();
@@ -106,7 +107,7 @@
test('test 2', () {
expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
- expect(errors.map((e) => e.error), equals(['error']));
+ expect(errors.map((e) => e.error), equals([error]));
});
}, passing: ['test 2']);
diff --git a/pkg/scheduled_test/test/scheduled_test/simple_test.dart b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
index ea51921..8c67bf3 100644
--- a/pkg/scheduled_test/test/scheduled_test/simple_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
@@ -30,14 +30,14 @@
expectTestsPass('a scheduled test with a correct asynchronous expectation '
'should pass', () {
test('test', () {
- expect(new Future.immediate('foo'), completion(equals('foo')));
+ expect(new Future.value('foo'), completion(equals('foo')));
});
});
expectTestsFail('a scheduled test with an incorrect asynchronous expectation '
'should fail', () {
test('test', () {
- expect(new Future.immediate('foo'), completion(equals('bar')));
+ expect(new Future.value('foo'), completion(equals('bar')));
});
});
@@ -57,7 +57,7 @@
'register', () {
test('test', () {
schedule(() =>
- expect(new Future.immediate('foo'), completion(equals('foo'))));
+ expect(new Future.value('foo'), completion(equals('foo'))));
});
});
@@ -65,7 +65,7 @@
'register', () {
test('test', () {
schedule(() =>
- expect(new Future.immediate('foo'), completion(equals('bar'))));
+ expect(new Future.value('foo'), completion(equals('bar'))));
});
});
@@ -88,7 +88,7 @@
});
test('asynchronous value', () {
- var future = schedule(() => new Future.immediate('value'));
+ var future = schedule(() => new Future.value('value'));
expect(future, completion(equals('value')));
});
});
@@ -107,7 +107,7 @@
expectTestsFail('a test failure in a chained future in a scheduled block '
'should be registered', () {
test('test', () {
- schedule(() => new Future.immediate('foo')
+ schedule(() => new Future.value('foo')
.then((v) => expect(v, equals('bar'))));
});
});
@@ -115,7 +115,7 @@
expectTestsFail('an error in a chained future in a scheduled block should be '
'registered', () {
test('test', () {
- schedule(() => new Future.immediate(null).then((_) {
+ schedule(() => new Future.value().then((_) {
throw 'error';
}));
});
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
index fd8e003..2a44cc5 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
@@ -53,7 +53,7 @@
wrapFuture(pumpEventQueue().then((_) {
throw 'error';
})).catchError(wrapAsync((e) {
- error = e.error;
+ error = e;
}));
});
});
diff --git a/pkg/scheduled_test/test/substitute_future_test.dart b/pkg/scheduled_test/test/substitute_future_test.dart
index f9c8b32..7202c86 100644
--- a/pkg/scheduled_test/test/substitute_future_test.dart
+++ b/pkg/scheduled_test/test/substitute_future_test.dart
@@ -31,28 +31,28 @@
test('.then and .catchError on success', () {
expect(future.then((v) => "transformed $v")
- .catchError((e) => "caught ${e.error}"),
+ .catchError((error) => "caught ${error}"),
completion(equals('transformed success')));
completer.complete('success');
});
test('.then and .catchError on error', () {
expect(future.then((v) => "transformed $v")
- .catchError((e) => "caught ${e.error}"),
+ .catchError((error) => "caught ${error}"),
completion(equals('caught error')));
completer.completeError('error');
});
test('.then with onError on success', () {
expect(future.then((v) => "transformed $v",
- onError: (e) => "caught ${e.error}"),
+ onError: (error) => "caught ${error}"),
completion(equals('transformed success')));
completer.complete('success');
});
test('.then with onError on error', () {
expect(future.then((v) => "transformed $v",
- onError: (e) => "caught ${e.error}"),
+ onError: (error) => "caught ${error}"),
completion(equals('caught error')));
completer.completeError('error');
});
@@ -148,7 +148,7 @@
var completer = new Completer();
var future = new SubstituteFuture(completer.future);
completer.complete('success');
- expect(() => future.substitute(new Future.immediate(null)),
+ expect(() => future.substitute(new Future.value()),
throwsStateError);
});
}
diff --git a/pkg/scheduled_test/test/utils.dart b/pkg/scheduled_test/test/utils.dart
index 4dd7ef9..a52b137 100644
--- a/pkg/scheduled_test/test/utils.dart
+++ b/pkg/scheduled_test/test/utils.dart
@@ -26,16 +26,16 @@
Future timeout(Future input, int milliseconds, onTimeout()) {
var completer = new Completer();
var timer = new Timer(new Duration(milliseconds: milliseconds), () {
- chainToCompleter(new Future.of(onTimeout), completer);
+ chainToCompleter(new Future.sync(onTimeout), completer);
});
input.then((value) {
if (completer.isCompleted) return;
timer.cancel();
completer.complete(value);
- }).catchError((e) {
+ }).catchError((error) {
if (completer.isCompleted) return;
timer.cancel();
- completer.completeError(e.error, e.stackTrace);
+ completer.completeError(error);
});
return completer.future;
}
diff --git a/pkg/scheduled_test/test/value_future_test.dart b/pkg/scheduled_test/test/value_future_test.dart
index a5777b3..61ab436 100644
--- a/pkg/scheduled_test/test/value_future_test.dart
+++ b/pkg/scheduled_test/test/value_future_test.dart
@@ -31,28 +31,28 @@
test('.then and .catchError on success', () {
expect(future.then((v) => "transformed $v")
- .catchError((e) => "caught ${e.error}"),
+ .catchError((error) => "caught ${error}"),
completion(equals('transformed success')));
completer.complete('success');
});
test('.then and .catchError on error', () {
expect(future.then((v) => "transformed $v")
- .catchError((e) => "caught ${e.error}"),
+ .catchError((error) => "caught ${error}"),
completion(equals('caught error')));
completer.completeError('error');
});
test('.then with onError on success', () {
expect(future.then((v) => "transformed $v",
- onError: (e) => "caught ${e.error}"),
+ onError: (error) => "caught ${error}"),
completion(equals('transformed success')));
completer.complete('success');
});
test('.then with onError on error', () {
expect(future.then((v) => "transformed $v",
- onError: (e) => "caught ${e.error}"),
+ onError: (error) => "caught ${error}"),
completion(equals('caught error')));
completer.completeError('error');
});
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index c640ba6..b3e3a95 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -419,7 +419,7 @@
* are kept in a separate object, which also has the ability to compute the
* default fields to use reflectively.
*/
-class _FieldList extends Iterable {
+class _FieldList extends IterableBase {
/**
* All of our fields, indexed by name. Note that the names are not
* necessarily strings.
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index e83e804..d63f07a 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -521,7 +521,7 @@
* looks like it's just a list of objects to a [CustomRule] without needing
* to inflate all the references in advance.
*/
-class _LazyList extends Iterable implements List {
+class _LazyList extends IterableBase implements List {
_LazyList(this._raw, this._reader);
final List _raw;
@@ -566,7 +566,6 @@
getRange(x, y) => _throw();
setRange(x, y, z, [a]) => _throw();
removeRange(x, y) => _throw();
- insertRange(x, y, [z]) => _throw();
get reversed => _throw();
void set length(x) => _throw();
}
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index bed1d5d..fa0c313 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -5,7 +5,7 @@
library trace;
import 'dart:uri';
-import 'dart:math';
+import 'dart:math' as math;
import 'frame.dart';
@@ -52,7 +52,7 @@
/// a [Trace], it will be returned as-is.
factory Trace.from(StackTrace trace) {
if (trace is Trace) return trace;
- return new Trace.parse(trace.fullStackTrace);
+ return new Trace.parse(trace.toString());
}
/// Parses a string representation of a stack trace.
@@ -117,7 +117,7 @@
if (frames.length == '') return '';
// Figure out the longest path so we know how much to pad.
- var longest = frames.map((frame) => frame.location.length).reduce(max);
+ var longest = frames.map((frame) => frame.location.length).reduce(math.max);
// Print out the stack trace nicely formatted.
return frames.map((frame) {
diff --git a/pkg/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index db243db..8bdb115 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -513,7 +513,8 @@
actionMatcher.matches(entry, matchState)) {
rtn.add(entry);
if (destructive) {
- logs.removeRange(i--, 1);
+ int startIndex = i--;
+ logs.removeRange(startIndex, startIndex + 1);
}
}
}
@@ -621,7 +622,7 @@
int pos = findLogEntry(logFilter, 0, defaultPosition);
if (inPlace) {
if (pos < logs.length) {
- logs.removeRange(pos, logs.length - pos);
+ logs.removeRange(pos, logs.length);
}
filter = description;
return this;
@@ -1291,7 +1292,7 @@
* return value. If we find no [Behavior] to apply an exception is
* thrown.
*/
- noSuchMethod(InvocationMirror invocation) {
+ noSuchMethod(Invocation invocation) {
var method = invocation.memberName;
var args = invocation.positionalArguments;
if (invocation.isGetter) {
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index 1a8143c..e8606aa 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -326,16 +326,17 @@
// completes.
item.then((value) {
done(() => fail("Expected future to fail, but succeeded with '$value'."));
- }, onError: (e) {
+ }, onError: (error) {
done(() {
if (_matcher == null) return;
var reason;
- if (e.stackTrace != null) {
- var stackTrace = e.stackTrace.toString();
+ var trace = getAttachedStackTrace(error);
+ if (trace != null) {
+ var stackTrace = trace.toString();
stackTrace = " ${stackTrace.replaceAll("\n", "\n ")}";
reason = "Actual exception trace:\n$stackTrace";
}
- expect(e.error, _matcher, reason: reason);
+ expect(error, _matcher, reason: reason);
});
});
// It hasn't failed yet.
diff --git a/pkg/unittest/lib/src/future_matchers.dart b/pkg/unittest/lib/src/future_matchers.dart
index cfc0518..6067451 100644
--- a/pkg/unittest/lib/src/future_matchers.dart
+++ b/pkg/unittest/lib/src/future_matchers.dart
@@ -42,12 +42,13 @@
item.then((value) {
done(() { if (_matcher != null) expect(value, _matcher); });
- }, onError: (e) {
+ }, onError: (error) {
var id = _id == '' ? '' : '${_id} ';
var reason = 'Expected future ${id}to complete successfully, '
- 'but it failed with ${e.error}';
- if (e.stackTrace != null) {
- var stackTrace = e.stackTrace.toString();
+ 'but it failed with ${error}';
+ var trace = getAttachedStackTrace(error);
+ if (trace != null) {
+ var stackTrace = trace.toString();
stackTrace = ' ${stackTrace.replaceAll('\n', '\n ')}';
reason = '$reason\nStack trace:\n$stackTrace';
}
diff --git a/pkg/unittest/lib/src/test_case.dart b/pkg/unittest/lib/src/test_case.dart
index 23d04de..13d59f5 100644
--- a/pkg/unittest/lib/src/test_case.dart
+++ b/pkg/unittest/lib/src/test_case.dart
@@ -83,7 +83,7 @@
--_callbackFunctionsOutstanding;
if (f is Future) {
return f.then((_) => _finishTest())
- .catchError((e) => fail("${e.error}"));
+ .catchError((error) => fail("${error}"));
} else {
_finishTest();
return null;
@@ -118,7 +118,7 @@
// a failed setUp. There is no right answer, but doing it
// seems to be the more conservative approach, because
// unittest will not stop at a test failure.
- error("$description: Test setup failed: ${e.error}");
+ error("$description: Test setup failed: $e");
});
} else {
var f = _runTest();
@@ -175,11 +175,12 @@
rtn.then((_) {
_notifyComplete();
})
- .catchError((e) {
+ .catchError((error) {
+ var trace = getAttachedStackTrace(error);
// We don't call fail() as that will potentially result in
// spurious messages like 'test failed more than once'.
- _setResult(ERROR, "$description: Test teardown failed: ${e.error}",
- e.stackTrace.toString());
+ _setResult(ERROR, "$description: Test teardown failed: ${error}",
+ trace == null ? "" : trace.toString());
_notifyComplete();
});
return;
diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
index efe6f8d..ec79288 100644
--- a/pkg/unittest/lib/unittest.dart
+++ b/pkg/unittest/lib/unittest.dart
@@ -668,7 +668,7 @@
* (as we do in unitttest_test.dart).
*/
_defer(void callback()) {
- (new Future.immediate(null)).then((_) => callback());
+ (new Future.value()).then((_) => callback());
}
void rerunTests() {
diff --git a/pkg/unittest/test/matchers_test.dart b/pkg/unittest/test/matchers_test.dart
index 7e97b38..be286ea 100644
--- a/pkg/unittest/test/matchers_test.dart
+++ b/pkg/unittest/test/matchers_test.dart
@@ -35,19 +35,19 @@
featureValueOf(actual) => actual.price;
}
-class SimpleIterable extends Iterable {
+class SimpleIterable extends IterableBase {
int count;
SimpleIterable(this.count);
-
+
bool contains(int val) => count < val ? false : true;
-
+
bool any(bool f(element)) {
for(var i = 0; i <= count; i++) {
if(f(i)) return true;
}
return false;
}
-
+
String toString() => "<[$count]>";
Iterator get iterator {
@@ -197,7 +197,7 @@
"but: exception <Exception> does not match "
"UnsupportedError.");
});
-
+
test('throwsStateError', () {
shouldPass(() { throw new StateError(''); },
throwsStateError);
@@ -453,14 +453,14 @@
shouldPass(d, isEmpty);
shouldFail(e, isEmpty, "Expected: empty but: was <[1]>.");
});
-
+
test('contains', () {
var d = new SimpleIterable(3);
shouldPass(d, contains(2));
shouldFail(d, contains(5), "Expected: contains <5> but: was <[3]>.");
});
});
-
+
group('Iterable Matchers', () {
test('isEmpty', () {
diff --git a/pkg/unittest/test/unittest_test.dart b/pkg/unittest/test/unittest_test.dart
index 8a641a4..f6a2f5d 100644
--- a/pkg/unittest/test/unittest_test.dart
+++ b/pkg/unittest/test/unittest_test.dart
@@ -15,7 +15,7 @@
import 'package:unittest/unittest.dart';
Future _defer(void fn()) {
- return new Future.of(fn);
+ return new Future.sync(fn);
}
String buildStatusString(int passed, int failed, int errors,
@@ -154,37 +154,37 @@
} else if (testName == 'async setup/teardown test') {
group('good setup/good teardown', () {
setUp(() {
- return new Future.immediate(0);
+ return new Future.value(0);
});
tearDown(() {
- return new Future.immediate(0);
+ return new Future.value(0);
});
test('foo1', (){});
});
group('good setup/bad teardown', () {
setUp(() {
- return new Future.immediate(0);
+ return new Future.value(0);
});
tearDown(() {
- return new Future.immediateError("Failed to complete tearDown");
+ return new Future.error("Failed to complete tearDown");
});
test('foo2', (){});
});
group('bad setup/good teardown', () {
setUp(() {
- return new Future.immediateError("Failed to complete setUp");
+ return new Future.error("Failed to complete setUp");
});
tearDown(() {
- return new Future.immediate(0);
+ return new Future.value(0);
});
test('foo3', (){});
});
group('bad setup/bad teardown', () {
setUp(() {
- return new Future.immediateError("Failed to complete setUp");
+ return new Future.error("Failed to complete setUp");
});
tearDown(() {
- return new Future.immediateError("Failed to complete tearDown");
+ return new Future.error("Failed to complete tearDown");
});
test('foo4', (){});
});
diff --git a/pkg/webdriver/lib/webdriver.dart b/pkg/webdriver/lib/webdriver.dart
index 9fed8d7..cc6b7d3 100644
--- a/pkg/webdriver/lib/webdriver.dart
+++ b/pkg/webdriver/lib/webdriver.dart
@@ -215,9 +215,10 @@
_url = 'http://$_host:$_port$_path';
}
- void _failRequest(Completer completer, error, StackTrace stackTrace) {
+ void _failRequest(Completer completer, error, [stackTrace]) {
if (completer != null) {
- completer.completeError(new WebDriverError(-1, error), stackTrace);
+ var trace = stackTrace != null ? stackTrace, getAttachedStackTrace(error);
+ completer.completeError(new WebDriverError(-1, error), trace);
}
}
@@ -273,7 +274,7 @@
results = new String.fromCharCodes(body).trim();
if (!successCodes.contains(rsp.statusCode)) {
_failRequest(completer,
- 'Unexpected response ${rsp.statusCode}; $results', null);
+ 'Unexpected response ${rsp.statusCode}; $results');
completer = null;
return;
}
@@ -297,18 +298,18 @@
completer.complete(value);
}
}
- }, onError: (e) {
- _failRequest(completer, e.error, e.stackTrace);
+ }, onError: (error) {
+ _failRequest(completer, error);
completer = null;
});
})
- .catchError((e) {
- _failRequest(completer, e.error, e.stackTrace);
+ .catchError((error) {
+ _failRequest(completer, error);
completer = null;
});
})
- .catchError((e) {
- _failRequest(completer, e.error, e.stackTrace);
+ .catchError((error) {
+ _failRequest(completer, error);
completer = null;
});
} catch (e, s) {
diff --git a/pkg/webdriver/test/webdriver_test.dart b/pkg/webdriver/test/webdriver_test.dart
index 213917f..3c4d500 100644
--- a/pkg/webdriver/test/webdriver_test.dart
+++ b/pkg/webdriver/test/webdriver_test.dart
@@ -1,4 +1,5 @@
library webdriver_test;
+import 'dart:async' show getAttachedStackTrace;
import 'package:webdriver/webdriver.dart';
import 'package:unittest/unittest.dart';
import 'package:unittest/vm_config.dart';
@@ -15,12 +16,13 @@
var web_driver = new WebDriver('localhost', 4444, '/wd/hub');
var session = null;
- var exceptionHandler = (e) {
- if (e.error is TestFailure) {
- currentTestCase.fail(e.error.message, e.stackTrace.toString());
+ var exceptionHandler = (error) {
+ var trace = getAttachedStackTrace(error);
+ String traceString = trace == null ? "" : trace.toString();
+ if (error is TestFailure) {
+ currentTestCase.fail(error.message, traceString);
} else {
- currentTestCase.error("Unexpected error: ${e.error}",
- e.stackTrace.toString());
+ currentTestCase.error("Unexpected error: ${error}", traceString);
}
if (session != null) {
var s = session;
diff --git a/pkg/yaml/lib/model.dart b/pkg/yaml/lib/model.dart
index 5c09aa5..ac237a0 100644
--- a/pkg/yaml/lib/model.dart
+++ b/pkg/yaml/lib/model.dart
@@ -190,8 +190,7 @@
/// long.
String zeroPad(String str, int length) {
assert(length >= str.length);
- var prefix = [];
- prefix.insertRange(0, length - str.length, '0');
+ var prefix = new List.filled(length - str.length, '0');
return '${prefix.join()}$str';
}
diff --git a/pkg/yaml/lib/parser.dart b/pkg/yaml/lib/parser.dart
index 9621b13..b923fe3 100644
--- a/pkg/yaml/lib/parser.dart
+++ b/pkg/yaml/lib/parser.dart
@@ -1637,7 +1637,7 @@
if (!truth(s_indent(indent))) return null;
return c_l_blockSeqEntry(indent);
}));
- content.insertRange(0, 1, first);
+ content.insert(0, first);
return new _SequenceNode("?", content);
});
@@ -1720,7 +1720,7 @@
if (!truth(s_indent(indent))) return null;
return ns_l_blockMapEntry(indent);
}));
- pairs.insertRange(0, 1, first);
+ pairs.insert(0, first);
return map(pairs);
});
diff --git a/pkg/yaml/test/yaml_test.dart b/pkg/yaml/test/yaml_test.dart
index 6013dc9..047c273 100644
--- a/pkg/yaml/test/yaml_test.dart
+++ b/pkg/yaml/test/yaml_test.dart
@@ -1350,8 +1350,7 @@
bar: invalid ]""")));
// TODO(nweiz): enable this when we throw an error for long keys
- // var dotList = [];
- // dotList.insertRange(0, 1024, ' ');
+ // var dotList = new List.filled(1024, ' ');
// var dots = dotList.join();
// Expect.throws(() => loadYaml('[ "foo...$dots...bar": invalid ]'));
});
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index b4b44d0..555dfe5 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -31,8 +31,8 @@
V(File_ReadByte, 1) \
V(File_WriteByte, 2) \
V(File_Read, 2) \
- V(File_ReadList, 4) \
- V(File_WriteList, 4) \
+ V(File_ReadInto, 4) \
+ V(File_WriteFrom, 4) \
V(File_Position, 1) \
V(File_SetPosition, 2) \
V(File_Truncate, 2) \
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 7dd8534..37cf816 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -678,9 +678,10 @@
Dart_CObject* CObject::NewUint8Array(int length) {
- Dart_CObject* cobject = New(Dart_CObject::kUint8Array, length);
- cobject->value.as_byte_array.length = length;
- cobject->value.as_byte_array.values = reinterpret_cast<uint8_t*>(cobject + 1);
+ Dart_CObject* cobject = New(Dart_CObject::kTypedData, length);
+ cobject->value.as_typed_data.type = Dart_CObject::kUint8Array;
+ cobject->value.as_typed_data.length = length;
+ cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
return cobject;
}
@@ -688,11 +689,12 @@
Dart_CObject* CObject::NewExternalUint8Array(
int64_t length, uint8_t* data, void* peer,
Dart_WeakPersistentHandleFinalizer callback) {
- Dart_CObject* cobject = New(Dart_CObject::kExternalUint8Array);
- cobject->value.as_external_byte_array.length = length;
- cobject->value.as_external_byte_array.data = data;
- cobject->value.as_external_byte_array.peer = peer;
- cobject->value.as_external_byte_array.callback = callback;
+ Dart_CObject* cobject = New(Dart_CObject::kExternalTypedData);
+ cobject->value.as_external_typed_data.type = Dart_CObject::kUint8Array;
+ cobject->value.as_external_typed_data.length = length;
+ cobject->value.as_external_typed_data.data = data;
+ cobject->value.as_external_typed_data.peer = peer;
+ cobject->value.as_external_typed_data.callback = callback;
return cobject;
}
@@ -704,10 +706,10 @@
void CObject::FreeIOBufferData(Dart_CObject* cobject) {
- ASSERT(cobject->type == Dart_CObject::kExternalUint8Array);
- cobject->value.as_external_byte_array.callback(
- NULL, cobject->value.as_external_byte_array.peer);
- cobject->value.as_external_byte_array.data = NULL;
+ ASSERT(cobject->type == Dart_CObject::kExternalTypedData);
+ cobject->value.as_external_typed_data.callback(
+ NULL, cobject->value.as_external_typed_data.peer);
+ cobject->value.as_external_typed_data.data = NULL;
}
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index da7653e..83457dc 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -205,6 +205,11 @@
public:
explicit CObject(Dart_CObject *cobject) : cobject_(cobject) {}
Dart_CObject::Type type() { return cobject_->type; }
+ Dart_CObject::TypedDataType byte_array_type() {
+ ASSERT(type() == Dart_CObject::kTypedData ||
+ type() == Dart_CObject::kExternalTypedData);
+ return cobject_->value.as_typed_data.type;
+ }
bool IsNull() { return type() == Dart_CObject::kNull; }
bool IsBool() { return type() == Dart_CObject::kBool; }
@@ -216,7 +221,11 @@
bool IsDouble() { return type() == Dart_CObject::kDouble; }
bool IsString() { return type() == Dart_CObject::kString; }
bool IsArray() { return type() == Dart_CObject::kArray; }
- bool IsUint8Array() { return type() == Dart_CObject::kUint8Array; }
+ bool IsTypedData() { return type() == Dart_CObject::kTypedData; }
+ bool IsUint8Array() {
+ return type() == Dart_CObject::kTypedData &&
+ byte_array_type() == Dart_CObject::kUint8Array;
+ }
bool IsTrue() {
return type() == Dart_CObject::kBool && cobject_->value.as_bool;
@@ -288,7 +297,35 @@
ASSERT(cobject != NULL); \
ASSERT(cobject->type() == Dart_CObject::k##t); \
cobject_ = cobject->AsApiCObject(); \
- }
+ } \
+
+
+#define DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(t) \
+ explicit CObject##t(Dart_CObject *cobject) : CObject(cobject) { \
+ ASSERT(type() == Dart_CObject::kTypedData); \
+ ASSERT(byte_array_type() == Dart_CObject::k##t); \
+ cobject_ = cobject; \
+ } \
+ explicit CObject##t(CObject* cobject) : CObject() { \
+ ASSERT(cobject != NULL); \
+ ASSERT(cobject->type() == Dart_CObject::kTypedData); \
+ ASSERT(cobject->byte_array_type() == Dart_CObject::k##t); \
+ cobject_ = cobject->AsApiCObject(); \
+ } \
+
+
+#define DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(t) \
+ explicit CObjectExternal##t(Dart_CObject *cobject) : CObject(cobject) { \
+ ASSERT(type() == Dart_CObject::kExternalTypedData); \
+ ASSERT(byte_array_type() == Dart_CObject::k##t); \
+ cobject_ = cobject; \
+ } \
+ explicit CObjectExternal##t(CObject* cobject) : CObject() { \
+ ASSERT(cobject != NULL); \
+ ASSERT(cobject->type() == Dart_CObject::kExternalTypedData); \
+ ASSERT(cobject->byte_array_type() == Dart_CObject::k##t); \
+ cobject_ = cobject->AsApiCObject(); \
+ } \
class CObjectBool : public CObject {
@@ -404,12 +441,35 @@
};
+class CObjectTypedData : public CObject {
+ public:
+ explicit CObjectTypedData(Dart_CObject *cobject) : CObject(cobject) {
+ ASSERT(type() == Dart_CObject::kTypedData);
+ cobject_ = cobject;
+ }
+ explicit CObjectTypedData(CObject* cobject) : CObject() {
+ ASSERT(cobject != NULL);
+ ASSERT(cobject->type() == Dart_CObject::kTypedData);
+ cobject_ = cobject->AsApiCObject();
+ }
+
+ Dart_CObject::TypedDataType Type() const {
+ return cobject_->value.as_typed_data.type;
+ }
+ int Length() const { return cobject_->value.as_typed_data.length; }
+ uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CObjectTypedData);
+};
+
+
class CObjectUint8Array : public CObject {
public:
- DECLARE_COBJECT_CONSTRUCTORS(Uint8Array)
+ DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(Uint8Array)
- int Length() const { return cobject_->value.as_byte_array.length; }
- uint8_t* Buffer() const { return cobject_->value.as_byte_array.values; }
+ int Length() const { return cobject_->value.as_typed_data.length; }
+ uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
private:
DISALLOW_COPY_AND_ASSIGN(CObjectUint8Array);
@@ -418,16 +478,16 @@
class CObjectExternalUint8Array : public CObject {
public:
- DECLARE_COBJECT_CONSTRUCTORS(ExternalUint8Array)
+ DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(Uint8Array)
- int Length() const { return cobject_->value.as_external_byte_array.length; }
+ int Length() const { return cobject_->value.as_external_typed_data.length; }
void SetLength(uint64_t length) {
- cobject_->value.as_external_byte_array.length = length;
+ cobject_->value.as_external_typed_data.length = length;
}
- uint8_t* Data() const { return cobject_->value.as_external_byte_array.data; }
- void* Peer() const { return cobject_->value.as_external_byte_array.peer; }
+ uint8_t* Data() const { return cobject_->value.as_external_typed_data.data; }
+ void* Peer() const { return cobject_->value.as_external_typed_data.peer; }
Dart_WeakPersistentHandleFinalizer Callback() const {
- return cobject_->value.as_external_byte_array.callback;
+ return cobject_->value.as_external_typed_data.callback;
}
private:
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 931d2bc..a1ac5e5 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -398,24 +398,15 @@
Dart_ActivationFrame frame;
res = Dart_GetActivationFrame(trace, 0, &frame);
ASSERT_NOT_ERROR(res);
- Dart_Handle script_url;
- intptr_t token_number = 0;
- intptr_t line_number = 0;
- intptr_t library_id = 0;
- // TODO(hausner): Remove this call and line_number once Editor no
- // longer depends on line number info.
- res = Dart_ActivationFrameInfo(frame, NULL, NULL, &line_number, NULL);
+ Dart_CodeLocation location;
+ res = Dart_ActivationFrameGetLocation(frame, NULL, &location);
ASSERT_NOT_ERROR(res);
- res = Dart_ActivationFrameGetLocation(
- frame, &script_url, &library_id, &token_number);
- ASSERT_NOT_ERROR(res);
- if (!Dart_IsNull(script_url)) {
- ASSERT(Dart_IsString(script_url));
+ if (!Dart_IsNull(location.script_url)) {
+ ASSERT(Dart_IsString(location.script_url));
msg->Printf("%s\"location\": { \"url\":", prefix);
- FormatEncodedString(msg, script_url);
- msg->Printf(",\"libraryId\":%"Pd",", library_id);
- msg->Printf("\"tokenOffset\":%"Pd",", token_number);
- msg->Printf("\"lineNumber\":%"Pd"}", line_number);
+ FormatEncodedString(msg, location.script_url);
+ msg->Printf(",\"libraryId\":%d,", location.library_id);
+ msg->Printf("\"tokenOffset\":%d}", location.token_pos);
}
}
@@ -430,36 +421,22 @@
res = Dart_GetActivationFrame(trace, i, &frame);
ASSERT_NOT_ERROR(res);
Dart_Handle func_name;
- Dart_Handle script_url;
- intptr_t line_number = 0;
- intptr_t token_number = 0;
- intptr_t library_id = 0;
- res = Dart_ActivationFrameInfo(
- frame, &func_name, NULL, &line_number, &library_id);
+ Dart_CodeLocation location;
+ res = Dart_ActivationFrameGetLocation(frame, &func_name, &location);
ASSERT_NOT_ERROR(res);
-
ASSERT(Dart_IsString(func_name));
msg->Printf("%s{\"functionName\":", (i > 0) ? "," : "");
FormatEncodedString(msg, func_name);
- // TODO(hausner): Remove this libraryId field when Editor
- // no longer depends on it.
- msg->Printf(",\"libraryId\": %"Pd",", library_id);
-
- res = Dart_ActivationFrameGetLocation(
- frame, &script_url, NULL, &token_number);
- ASSERT_NOT_ERROR(res);
- if (!Dart_IsNull(script_url)) {
- ASSERT(Dart_IsString(script_url));
- msg->Printf("\"location\": { \"url\":");
- FormatEncodedString(msg, script_url);
- msg->Printf(",\"libraryId\": %"Pd",", library_id);
- msg->Printf("\"tokenOffset\":%"Pd",", token_number);
- msg->Printf("\"lineNumber\":%"Pd"},", line_number);
+ if (!Dart_IsNull(location.script_url)) {
+ ASSERT(Dart_IsString(location.script_url));
+ msg->Printf(",\"location\": { \"url\":");
+ FormatEncodedString(msg, location.script_url);
+ msg->Printf(",\"libraryId\":%d,", location.library_id);
+ msg->Printf("\"tokenOffset\":%d}", location.token_pos);
}
-
Dart_Handle locals = Dart_GetLocalVariables(frame);
ASSERT_NOT_ERROR(locals);
- msg->Printf("\"locals\":");
+ msg->Printf(",\"locals\":");
FormatNamedValueList(msg, locals);
msg->Printf("}");
}
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index f04a367..c9fc1b2 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -210,28 +210,29 @@
}
-void FUNCTION_NAME(File_ReadList)(Dart_NativeArguments args) {
+void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) {
Dart_EnterScope();
File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
ASSERT(file != NULL);
Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
ASSERT(Dart_IsList(buffer_obj));
- // Offset and length arguments are checked in Dart code to be
- // integers and have the property that (offset + length) <=
+ // start and end arguments are checked in Dart code to be
+ // integers and have the property that end <=
// list.length. Therefore, it is safe to extract their value as
// intptr_t.
- intptr_t offset =
+ intptr_t start =
DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
- intptr_t length =
+ intptr_t end =
DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+ intptr_t length = end - start;
intptr_t array_len = 0;
Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
if (Dart_IsError(result)) Dart_PropagateError(result);
- ASSERT((offset + length) <= array_len);
+ ASSERT(end <= array_len);
uint8_t* buffer = new uint8_t[length];
int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
if (bytes_read >= 0) {
- result = Dart_ListSetAsBytes(buffer_obj, offset, buffer, bytes_read);
+ result = Dart_ListSetAsBytes(buffer_obj, start, buffer, bytes_read);
if (Dart_IsError(result)) {
delete[] buffer;
Dart_PropagateError(result);
@@ -247,7 +248,7 @@
}
-void FUNCTION_NAME(File_WriteList)(Dart_NativeArguments args) {
+void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) {
Dart_EnterScope();
File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
ASSERT(file != NULL);
@@ -257,24 +258,23 @@
// integers and have the property that (offset + length) <=
// list.length. Therefore, it is safe to extract their value as
// intptr_t.
- intptr_t offset =
+ intptr_t start =
DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
- intptr_t length =
+ intptr_t end =
DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+ intptr_t length = end - start;
intptr_t buffer_len = 0;
Dart_Handle result = Dart_ListLength(buffer_obj, &buffer_len);
if (Dart_IsError(result)) Dart_PropagateError(result);
- ASSERT((offset + length) <= buffer_len);
+ ASSERT(end <= buffer_len);
uint8_t* buffer = new uint8_t[length];
- result = Dart_ListGetAsBytes(buffer_obj, offset, buffer, length);
+ result = Dart_ListGetAsBytes(buffer_obj, start, buffer, length);
if (Dart_IsError(result)) {
delete[] buffer;
Dart_PropagateError(result);
}
int64_t bytes_written = file->Write(reinterpret_cast<void*>(buffer), length);
- if (bytes_written >= 0) {
- Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
- } else {
+ if (bytes_written != length) {
Dart_Handle err = DartUtils::NewDartOSError();
if (Dart_IsError(err)) Dart_PropagateError(err);
Dart_SetReturnValue(args, err);
@@ -911,7 +911,7 @@
if (!file->IsClosed()) {
int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
- uint8_t* data = io_buffer->value.as_external_byte_array.data;
+ uint8_t* data = io_buffer->value.as_external_typed_data.data;
int64_t bytes_read = file->Read(data, length);
if (bytes_read >= 0) {
CObjectExternalUint8Array* external_array =
@@ -933,7 +933,7 @@
}
-static CObject* FileReadListRequest(const CObjectArray& request) {
+static CObject* FileReadIntoRequest(const CObjectArray& request) {
if (request.Length() == 3 &&
request[1]->IsIntptr() &&
request[2]->IsInt32OrInt64()) {
@@ -942,7 +942,7 @@
if (!file->IsClosed()) {
int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
- uint8_t* data = io_buffer->value.as_external_byte_array.data;
+ uint8_t* data = io_buffer->value.as_external_typed_data.data;
int64_t bytes_read = file->Read(data, length);
if (bytes_read >= 0) {
CObjectExternalUint8Array* external_array =
@@ -965,27 +965,55 @@
}
-static CObject* FileWriteListRequest(const CObjectArray& request) {
+static int SizeInBytes(Dart_CObject::TypedDataType type) {
+ switch (type) {
+ case Dart_CObject::kInt8Array:
+ case Dart_CObject::kUint8Array:
+ case Dart_CObject::kUint8ClampedArray:
+ return 1;
+ case Dart_CObject::kInt16Array:
+ case Dart_CObject::kUint16Array:
+ return 2;
+ case Dart_CObject::kInt32Array:
+ case Dart_CObject::kUint32Array:
+ case Dart_CObject::kFloat32Array:
+ return 4;
+ case Dart_CObject::kInt64Array:
+ case Dart_CObject::kUint64Array:
+ case Dart_CObject::kFloat64Array:
+ return 8;
+ default:
+ break;
+ }
+ UNREACHABLE();
+ return -1;
+}
+
+
+static CObject* FileWriteFromRequest(const CObjectArray& request) {
if (request.Length() == 5 &&
request[1]->IsIntptr() &&
- (request[2]->IsUint8Array() || request[2]->IsArray()) &&
+ (request[2]->IsTypedData() || request[2]->IsArray()) &&
request[3]->IsInt32OrInt64() &&
request[4]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[1]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
- int64_t offset = CObjectInt32OrInt64ToInt64(request[3]);
- int64_t length = CObjectInt32OrInt64ToInt64(request[4]);
+ int64_t start = CObjectInt32OrInt64ToInt64(request[3]);
+ int64_t end = CObjectInt32OrInt64ToInt64(request[4]);
+ int64_t length = end - start;
uint8_t* buffer_start;
- if (request[2]->IsUint8Array()) {
- CObjectUint8Array byte_array(request[2]);
- buffer_start = byte_array.Buffer() + offset;
+ if (request[2]->IsTypedData()) {
+ CObjectTypedData typed_data(request[2]);
+ start = start * SizeInBytes(typed_data.Type());
+ length = length * SizeInBytes(typed_data.Type());
+ buffer_start = typed_data.Buffer() + start;
} else {
CObjectArray array(request[2]);
buffer_start = new uint8_t[length];
for (int i = 0; i < length; i++) {
- if (array[i + offset]->IsInt32OrInt64()) {
- int64_t value = CObjectInt32OrInt64ToInt64(array[i + offset]);
+ if (array[i + start]->IsInt32OrInt64()) {
+ int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
buffer_start[i] = static_cast<uint8_t>(value & 0xFF);
} else {
// Unsupported type.
@@ -993,11 +1021,11 @@
return CObject::IllegalArgumentError();
}
}
- offset = 0;
+ start = 0;
}
int64_t bytes_written =
file->Write(reinterpret_cast<void*>(buffer_start), length);
- if (!request[2]->IsUint8Array()) {
+ if (!request[2]->IsTypedData()) {
delete[] buffer_start;
}
if (bytes_written >= 0) {
@@ -1103,11 +1131,11 @@
case File::kReadRequest:
response = FileReadRequest(request);
break;
- case File::kReadListRequest:
- response = FileReadListRequest(request);
+ case File::kReadIntoRequest:
+ response = FileReadIntoRequest(request);
break;
- case File::kWriteListRequest:
- response = FileWriteListRequest(request);
+ case File::kWriteFromRequest:
+ response = FileWriteFromRequest(request);
break;
case File::kDeleteLinkRequest:
response = FileDeleteLinkRequest(request);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index b4c5c50..944fd6a 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -75,8 +75,8 @@
kReadByteRequest = 14,
kWriteByteRequest = 15,
kReadRequest = 16,
- kReadListRequest = 17,
- kWriteListRequest = 18,
+ kReadIntoRequest = 17,
+ kWriteFromRequest = 18,
kCreateLinkRequest = 19,
kDeleteLinkRequest = 20
};
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index c246002..65ac0a4 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -26,11 +26,11 @@
/* patch */ static int _close(int id) native "File_Close";
/* patch */ static _readByte(int id) native "File_ReadByte";
/* patch */ static _read(int id, int bytes) native "File_Read";
- /* patch */ static _readList(int id, List<int> buffer, int offset, int bytes)
- native "File_ReadList";
+ /* patch */ static _readInto(int id, List<int> buffer, int start, int end)
+ native "File_ReadInto";
/* patch */ static _writeByte(int id, int value) native "File_WriteByte";
- /* patch */ static _writeList(int id, List<int> buffer, int offset, int bytes)
- native "File_WriteList";
+ /* patch */ static _writeFrom(int id, List<int> buffer, int start, int end)
+ native "File_WriteFrom";
/* patch */ static _position(int id) native "File_Position";
/* patch */ static _setPosition(int id, int position)
native "File_SetPosition";
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 64828f5..ae87f4e 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -199,7 +199,7 @@
_stdin._sink.destroy();
}
- exitDataBuffer.setRange(exitDataRead, data.length, data);
+ exitDataBuffer.setRange(exitDataRead, exitDataRead + data.length, data);
exitDataRead += data.length;
if (exitDataRead == EXIT_DATA_SIZE) {
handleExit();
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 81e8ab3..bb71cc2 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -115,11 +115,11 @@
var socket = new _NativeSocket.listen();
var result = socket.nativeCreateBindListen(address, port, backlog);
if (result is OSError) {
- return new Future.immediateError(
+ return new Future.error(
new SocketIOException("Failed to create server socket", result));
}
if (port != 0) socket.localPort = port;
- return new Future.immediate(socket);
+ return new Future.value(socket);
}
_NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET {
@@ -175,10 +175,10 @@
}
if (isClosed) return 0;
if (bytes == 0) return 0;
- _BufferAndOffset bufferAndOffset =
- _ensureFastAndSerializableBuffer(buffer, offset, bytes);
+ _BufferAndStart bufferAndStart =
+ _ensureFastAndSerializableBuffer(buffer, offset, offset + bytes);
var result =
- nativeWrite(bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
+ nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
if (result is OSError) {
reportError(result, "Write failed");
result = 0;
@@ -432,8 +432,10 @@
_RawServerSocket(this._socket) {
_controller = new StreamController(
- onSubscriptionStateChange: _onSubscriptionStateChange,
- onPauseStateChange: _onPauseStateChange);
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
_socket.closeFuture.then((_) => _controller.close());
_socket.setHandlers(
read: () {
@@ -441,21 +443,21 @@
if (socket != null) _controller.add(new _RawSocket(socket));
},
error: (e) {
- _controller.addError(new AsyncError(e));
+ _controller.addError(e);
_controller.close();
}
);
}
StreamSubscription<RawSocket> listen(void onData(RawSocket event),
- {void onError(AsyncError error),
+ {void onError(Object error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
int get port => _socket.port;
@@ -501,8 +503,10 @@
_RawSocket(this._socket) {
_controller = new StreamController(
- onSubscriptionStateChange: _onSubscriptionStateChange,
- onPauseStateChange: _onPauseStateChange);
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
_socket.closeFuture.then((_) => _controller.close());
_socket.setHandlers(
read: () => _controller.add(RawSocketEvent.READ),
@@ -514,7 +518,7 @@
},
closed: () => _controller.add(RawSocketEvent.READ_CLOSED),
error: (e) {
- _controller.addError(new AsyncError(e));
+ _controller.addError(e);
close();
}
);
@@ -535,14 +539,14 @@
}
StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
- {void onError(AsyncError error),
+ {void onError(Object error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
int available() => _socket.available();
@@ -629,14 +633,14 @@
_ServerSocket(this._socket);
StreamSubscription<Socket> listen(void onData(Socket event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _socket.map((rawSocket) => new _Socket(rawSocket)).listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
int get port => _socket.port;
@@ -665,32 +669,13 @@
int offset;
List<int> buffer;
bool paused = false;
+ Completer streamCompleter;
_SocketStreamConsumer(this.socket);
- Future<Socket> consume(Stream<List<int>> stream) {
- if (socket._raw != null) {
- subscription = stream.listen(
- (data) {
- assert(!paused);
- assert(buffer == null);
- buffer = data;
- offset = 0;
- write();
- },
- onError: (error) {
- socket._consumerDone(error);
- },
- onDone: () {
- socket._consumerDone();
- },
- unsubscribeOnError: true);
- }
- return socket._doneFuture;
- }
-
Future<Socket> addStream(Stream<List<int>> stream) {
- Completer completer = new Completer<Socket>();
+ socket._ensureRawSocketSubscription();
+ streamCompleter = new Completer<Socket>();
if (socket._raw != null) {
subscription = stream.listen(
(data) {
@@ -701,20 +686,20 @@
write();
},
onError: (error) {
- socket._consumerDone(error);
- completer.completeError(error.error, error.stackTrace);
+ socket._consumerDone();
+ done(error);
},
onDone: () {
- completer.complete(socket);
+ done();
},
- unsubscribeOnError: true);
+ cancelOnError: true);
}
- return completer.future;
+ return streamCompleter.future;
}
Future<Socket> close() {
socket._consumerDone();
- return completer.future;
+ return new Future.value(socket);
}
void write() {
@@ -743,7 +728,20 @@
}
} catch (e) {
stop();
- socket._consumerDone(e);
+ socket._consumerDone();
+ done(e);
+ }
+ }
+
+ void done([error]) {
+ if (streamCompleter != null) {
+ var tmp = streamCompleter;
+ streamCompleter = null;
+ if (error != null) {
+ tmp.completeError(error);
+ } else {
+ tmp.complete(socket);
+ }
}
}
@@ -762,14 +760,15 @@
StreamController _controller;
bool _controllerClosed = false;
_SocketStreamConsumer _consumer;
- IOSink<Socket> _sink;
- Completer _doneCompleter;
+ IOSink _sink;
var _subscription;
_Socket(RawSocket this._raw) {
_controller = new StreamController<List<int>>(
- onSubscriptionStateChange: _onSubscriptionStateChange,
- onPauseStateChange: _onPauseStateChange);
+ onListen: _onSubscriptionStateChange,
+ onCancel: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange);
_consumer = new _SocketStreamConsumer(this);
_sink = new IOSink(_consumer);
@@ -791,14 +790,14 @@
_NativeSocket get _nativeSocket => _raw._socket;
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
Encoding get encoding => _sink.encoding;
@@ -817,15 +816,11 @@
void add(List<int> bytes) => _sink.add(bytes);
- Future<Socket> consume(Stream<List<int>> stream) {
- return _sink.consume(stream);
+ Future<Socket> addStream(Stream<List<int>> stream) {
+ return _sink.addStream(stream);
}
- Future<Socket> writeStream(Stream<List<int>> stream) {
- return _sink.writeStream(stream);
- }
-
- close() => _sink.close();
+ Future<Socket> close() => _sink.close();
Future<Socket> get done => _sink.done;
@@ -851,11 +846,11 @@
// consumer needs a subscription as they share the error and done
// events from the raw socket.
void _ensureRawSocketSubscription() {
- if (_subscription == null) {
+ if (_subscription == null && _raw != null) {
_subscription = _raw.listen(_onData,
onError: _onError,
onDone: _onDone,
- unsubscribeOnError: true);
+ cancelOnError: true);
}
}
@@ -908,7 +903,7 @@
_controllerClosed = true;
_controller.close();
}
- _done();
+ _consumer.done();
}
void _onError(error) {
@@ -917,27 +912,7 @@
_controller.addError(error);
_controller.close();
}
- _done(error);
- }
-
- get _doneFuture {
- if (_doneCompleter == null) {
- _ensureRawSocketSubscription();
- _doneCompleter = new Completer();
- }
- return _doneCompleter.future;
- }
-
- void _done([error]) {
- if (_doneCompleter != null) {
- var tmp = _doneCompleter;
- _doneCompleter = null;
- if (error != null) {
- tmp.completeError(error);
- } else {
- tmp.complete(this);
- }
- }
+ _consumer.done(error);
}
int _write(List<int> data, int offset, int length) =>
@@ -953,8 +928,7 @@
}
}
- void _consumerDone([error]) {
- _done(error);
+ void _consumerDone() {
if (_raw != null) {
_raw.shutdown(SocketDirection.SEND);
_disableWriteEvent();
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
index f709000..c37c80b 100644
--- a/runtime/embedders/openglui/common/gl.dart
+++ b/runtime/embedders/openglui/common/gl.dart
@@ -214,7 +214,7 @@
}
/// Has no effect.
- void onError(void handleError(AsyncError error)) {}
+ void onError(void handleError(Object error)) {}
/// Has no effect.
void onDone(void handleDone()) {}
@@ -255,6 +255,12 @@
_target.removeListener(_eventType, _onData);
}
}
+
+ Future asFuture([var futureValue]) {
+ // We just need a future that will never succeed or fail.
+ Completer completer = new Completer();
+ return completer.future;
+ }
}
class _EventStream<T extends Event> extends Stream<T> {
@@ -268,9 +274,9 @@
bool get isBroadcast => true;
StreamSubscription<T> listen(void onData(T event),
- { void onError(AsyncError error),
+ { void onError(Object error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return new _EventStreamSubscription<T>(
this._target, this._eventType, onData);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 2ac024a..121e49d 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -942,6 +942,11 @@
* representation as a Dart_CObject.
*
* The string encoding in the 'value.as_string' is UTF-8.
+ *
+ * All the different types from dart:typeddata are exposed as type
+ * kTypedData. The specific type from dart:typeddata is in the type
+ * field of the as_typed_data structure. The length in the
+ * as_typed_data structure is always in bytes.
*/
typedef struct _Dart_CObject {
enum Type {
@@ -953,11 +958,27 @@
kDouble,
kString,
kArray,
- kUint8Array,
- kExternalUint8Array,
+ kTypedData,
+ kExternalTypedData,
kUnsupported,
kNumberOfTypes
} type;
+
+ enum TypedDataType {
+ kInt8Array = 0,
+ kUint8Array,
+ kUint8ClampedArray,
+ kInt16Array,
+ kUint16Array,
+ kInt32Array,
+ kUint32Array,
+ kInt64Array,
+ kUint64Array,
+ kFloat32Array,
+ kFloat64Array,
+ kNumberOfTypedDataTypes
+ };
+
union {
bool as_bool;
int32_t as_int32;
@@ -970,15 +991,17 @@
struct _Dart_CObject** values;
} as_array;
struct {
+ TypedDataType type;
int length;
uint8_t* values;
- } as_byte_array;
+ } as_typed_data;
struct {
+ TypedDataType type;
int length;
uint8_t* data;
void* peer;
Dart_WeakPersistentHandleFinalizer callback;
- } as_external_byte_array;
+ } as_external_typed_data;
} value;
} Dart_CObject;
@@ -1665,6 +1688,7 @@
kUint64,
kFloat32,
kFloat64,
+ kFloat32x4,
kInvalid
} Dart_TypedData_Type;
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index 1fa5f2d..5694f8e 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -44,6 +44,17 @@
kShutdown,
} Dart_IsolateEvent;
+
+/**
+ * Represents a location in Dart code.
+ */
+typedef struct {
+ Dart_Handle script_url; // Url (string) of the script.
+ int32_t library_id; // Library in which the script is loaded.
+ int32_t token_pos; // Code address.
+} Dart_CodeLocation;
+
+
typedef void Dart_IsolateEventHandler(Dart_IsolateId isolate_id,
Dart_IsolateEvent kind);
@@ -362,6 +373,8 @@
/**
+ * DEPRECATED -- Use Dart_ActivationframeGetLocation instead.
+ *
* Returns information about the given activation frame.
* \function_name receives a string handle with the qualified
* function name.
@@ -386,15 +399,20 @@
/**
- * Returns text location of the given activation frame.
- * \script_url receives a string handle with the url of the
- * source script that contains the frame's function.
+ * Returns code location of the given activation frame.
+ *
+ * \function_name receives a string handle with the qualified
+ * function name.
+ * \location.script_url receives a string handle with the url of
+ * the source script that contains the frame's function.
* Receives a null handle if there is no textual location
* that corresponds to the frame, e.g. for implicitly
* generated constructors.
- * \token_number receives the line number in the script.
+ * \location.library_id receives the id of the library in which the
+ * function in this frame is defined.
+ * \location.token_pos receives the token position in the script.
*
- * Any or all of the out parameters above may be NULL.
+ * Any of the out parameters above may be NULL.
*
* Requires there to be a current isolate.
*
@@ -404,9 +422,8 @@
*/
DART_EXPORT Dart_Handle Dart_ActivationFrameGetLocation(
Dart_ActivationFrame activation_frame,
- Dart_Handle* script_url,
- intptr_t* library_id,
- intptr_t* token_number);
+ Dart_Handle* function_name,
+ Dart_CodeLocation* location);
/**
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 0ee4d08..1ebc5b7 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -29,6 +29,15 @@
"Cannot add to a non-extendable array");
}
+ void insertAll(int index, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot add to a non-extendable array");
+ }
+
+ void setAll(int index, Iterable<E> iterable) {
+ IterableMixinWorkaround.setAllList(this, index, iterable);
+ }
+
E removeAt(int index) {
throw new UnsupportedError(
"Cannot remove element of a non-extendable array");
@@ -54,27 +63,46 @@
}
// List interface.
- void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
- if (length < 0) {
- throw new ArgumentError("negative length $length");
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ if (start < 0 || start > this.length) {
+ throw new RangeError.range(start, 0, this.length);
}
- if (from is _ObjectArray) {
- _copyFromObjectArray(from, startFrom, start, length);
+ if (end < 0 || end > this.length) {
+ throw new RangeError.range(end, start, this.length);
+ }
+ int length = end - start;
+ if (length == 0) return;
+
+ if (iterable is _ObjectArray) {
+ _copyFromObjectArray(iterable, skipCount, start, length);
} else {
- Arrays.copy(from, startFrom, this, start, length);
+ List otherList;
+ int otherStart;
+ if (iterable is List) {
+ otherList = iterable;
+ otherStart = skipCount;
+ } else {
+ otherList =
+ iterable.skip(skipCount).take(length).toList(growable: false);
+ otherStart = 0;
+ }
+ Arrays.copy(otherList, otherStart, this, start, length);
}
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot remove range of a non-extendable array");
}
- void insertRange(int start, int length, [E initialValue = null]) {
+ void replaceRange(int start, int end, Iterable<E> iterable) {
throw new UnsupportedError(
- "Cannot insert range in a non-extendable array");
+ "Cannot remove range of a non-extendable array");
}
+ void fillRange(int start, int end, [E fillValue]) {
+ IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+ }
List<E> sublist(int start, [int end]) {
Arrays.indicesCheck(this, start, end);
@@ -267,6 +295,16 @@
"Cannot add to an immutable array");
}
+ void insertAll(int index, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot add to an immutable array");
+ }
+
+ void setAll(int index, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot modify an immutable array");
+ }
+
E removeAt(int index) {
throw new UnsupportedError(
"Cannot modify an immutable array");
@@ -292,19 +330,24 @@
"Cannot modify an immutable array");
}
- void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
throw new UnsupportedError(
"Cannot modify an immutable array");
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot remove range of an immutable array");
}
- void insertRange(int start, int length, [E initialValue = null]) {
+ void fillRange(int start, int end, [E fillValue]) {
throw new UnsupportedError(
- "Cannot insert range in an immutable array");
+ "Cannot modify an immutable array");
+ }
+
+ void replaceRange(int start, int end, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot modify an immutable array");
}
List<E> sublist(int start, [int end]) {
diff --git a/runtime/lib/collection_dev_patch.dart b/runtime/lib/collection_dev_patch.dart
new file mode 100644
index 0000000..c4618bc
--- /dev/null
+++ b/runtime/lib/collection_dev_patch.dart
@@ -0,0 +1,3 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
diff --git a/runtime/lib/collection_dev_sources.gypi b/runtime/lib/collection_dev_sources.gypi
new file mode 100644
index 0000000..76121f5
--- /dev/null
+++ b/runtime/lib/collection_dev_sources.gypi
@@ -0,0 +1,13 @@
+# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Sources that patch the library "dart:_collection-dev".
+
+{
+ 'sources': [
+ 'collection_dev_patch.dart',
+ # The above file needs to be first as it imports required libraries.
+ 'symbol_patch.dart',
+ ],
+}
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 8ed2abc..1ddd5d9 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -700,7 +700,7 @@
/**
* Generic iterable based on a [_HashTable].
*/
-abstract class _HashTableIterable<E> extends Iterable<E> {
+abstract class _HashTableIterable<E> extends IterableBase<E> {
final _HashTable _hashTable;
_HashTableIterable(this._hashTable);
@@ -924,7 +924,7 @@
}
}
-class _LinkedHashTableKeyIterable<K> extends Iterable<K> {
+class _LinkedHashTableKeyIterable<K> extends IterableBase<K> {
final _LinkedHashTable<K> _table;
_LinkedHashTableKeyIterable(this._table);
Iterator<K> get iterator => new _LinkedHashTableKeyIterator<K>(_table);
@@ -940,7 +940,7 @@
K _getCurrent(int offset) => _hashTable._key(offset);
}
-class _LinkedHashTableValueIterable<V> extends Iterable<V> {
+class _LinkedHashTableValueIterable<V> extends IterableBase<V> {
final _LinkedHashTable _hashTable;
final int _valueIndex;
_LinkedHashTableValueIterable(this._hashTable, this._valueIndex);
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 8e6d905..0a27429 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -4,3 +4,5 @@
import "dart:math";
import "dart:typeddata";
+
+import "dart:_collection-dev" as _symbol_dev;
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index c1336c4..b1f2f8d 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -76,7 +76,7 @@
_flooredDivision(_localDateInUtcMs, Duration.MILLISECONDS_PER_DAY);
// 1970-1-1 was a Thursday.
return ((daysSince1970 + DateTime.THURSDAY - DateTime.MONDAY)
- % DateTime.DAYS_IN_WEEK) +
+ % DateTime.DAYS_PER_WEEK) +
DateTime.MONDAY;
}
diff --git a/runtime/lib/deferred_load_patch.dart b/runtime/lib/deferred_load_patch.dart
index 8d0a9ff..2bd0027 100644
--- a/runtime/lib/deferred_load_patch.dart
+++ b/runtime/lib/deferred_load_patch.dart
@@ -9,7 +9,7 @@
// Dummy implementation that should eventually be replaced by real
// implementation.
Future future =
- new Future<bool>.immediate(!_loadedLibraries.contains(libraryName));
+ new Future<bool>.value(!_loadedLibraries.contains(libraryName));
_loadedLibraries.add(libraryName);
return future;
}
diff --git a/runtime/lib/function_patch.dart b/runtime/lib/function_patch.dart
index 56b817d..f0f016c 100644
--- a/runtime/lib/function_patch.dart
+++ b/runtime/lib/function_patch.dart
@@ -8,21 +8,21 @@
/* patch */ static apply(Function function,
List positionalArguments,
- [Map<String,dynamic> namedArguments]) {
+ [Map<Symbol, dynamic> namedArguments]) {
int numPositionalArguments = 1 + // Function is first implicit argument.
(positionalArguments != null ? positionalArguments.length : 0);
int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
int numArguments = numPositionalArguments + numNamedArguments;
List arguments = new List(numArguments);
arguments[0] = function;
- arguments.setRange(1, numPositionalArguments - 1, positionalArguments);
+ arguments.setRange(1, numPositionalArguments, positionalArguments);
List names = new List(numNamedArguments);
int argumentIndex = numPositionalArguments;
int nameIndex = 0;
if (numNamedArguments > 0) {
namedArguments.forEach((name, value) {
arguments[argumentIndex++] = value;
- names[nameIndex++] = name;
+ names[nameIndex++] = _symbol_dev.Symbol.getName(name);
});
}
return _apply(arguments, names);
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 76cacb4..f24da18 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -52,6 +52,33 @@
}
}
+ void insertAll(int index, Iterable<T> iterable) {
+ if (index < 0 || index > length) {
+ throw new RangeError.range(index, 0, length);
+ }
+ // TODO(floitsch): we can probably detect more cases.
+ if (iterable is! List && iterable is! Set && iterable is! SubListIterable) {
+ iterable = iterable.toList();
+ }
+ int insertionLength = iterable.length;
+ // There might be errors after the length change, in which case the list
+ // will end up being modified but the operation not complete. Unless we
+ // always go through a "toList" we can't really avoid that.
+ this.length += insertionLength;
+ setRange(index + insertionLength, this.length, this, index);
+ setAll(index, iterable);
+ }
+
+ void setAll(int index, Iterable<T> iterable) {
+ if (iterable is List) {
+ setRange(index, index + iterable.length, iterable);
+ } else {
+ for (T element in iterable) {
+ this[index++] = element;
+ }
+ }
+ }
+
void removeWhere(bool test(T element)) {
IterableMixinWorkaround.removeWhereList(this, test);
}
@@ -65,43 +92,26 @@
return IterableMixinWorkaround.getRangeList(this, start, end);
}
- void setRange(int start, int length, List<T> from, [int startFrom = 0]) {
- IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
+ void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
+ IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
}
- void removeRange(int start, int length) {
- if (length == 0) {
- return;
- }
- Arrays.rangeCheck(this, start, length);
+ void removeRange(int start, int end) {
+ Arrays.indicesCheck(this, start, end);
Arrays.copy(this,
- start + length,
+ end,
this,
start,
- this.length - length - start);
- this.length = this.length - length;
+ this.length - end);
+ this.length = this.length - (end - start);
}
- void insertRange(int start, int length, [T initialValue = null]) {
- if (length == 0) {
- return;
- }
- if ((length < 0) || (length is! int)) {
- throw new ArgumentError("invalid length specified $length");
- }
- if (start < 0 || start > this.length) {
- throw new RangeError.value(start);
- }
- var old_length = this.length;
- this.length = old_length + length; // Will expand if needed.
- Arrays.copy(this,
- start,
- this,
- start + length,
- old_length - start);
- for (int i = start; i < start + length; i++) {
- this[i] = initialValue;
- }
+ void replaceRange(int start, int end, Iterable<T> iterable) {
+ IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
+ }
+
+ void fillRange(int start, int end, [T fillValue]) {
+ IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
}
List<T> sublist(int start, [int end]) {
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 82f5458..3ca9ed5 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -82,7 +82,7 @@
}
}
-class _ImmutableMapKeyIterable<E> extends Iterable<E> {
+class _ImmutableMapKeyIterable<E> extends IterableBase<E> {
final ImmutableMap _map;
_ImmutableMapKeyIterable(this._map);
@@ -91,7 +91,7 @@
}
}
-class _ImmutableMapValueIterable<E> extends Iterable<E> {
+class _ImmutableMapValueIterable<E> extends IterableBase<E> {
final ImmutableMap _map;
_ImmutableMapValueIterable(this._map);
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index c498eac..0b438c7 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-class _InvocationMirror implements InvocationMirror {
+class _InvocationMirror implements Invocation {
// Constants describing the invocation type.
// _FIELD cannot be generated by regular invocation mirrors.
static const int _METHOD = 0;
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 144e9c9..a4daac2 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -34,8 +34,8 @@
_port.send(message);
}
- void addError(AsyncError errorEvent) {
- throw new UnimplementedError("signalError on isolate streams");
+ void addError(Object errorEvent) {
+ throw new UnimplementedError("addError on isolate streams");
}
void close() {
diff --git a/runtime/lib/lib_sources.gypi b/runtime/lib/lib_sources.gypi
index 7f1c37a..d3efd48 100644
--- a/runtime/lib/lib_sources.gypi
+++ b/runtime/lib/lib_sources.gypi
@@ -50,7 +50,6 @@
'string.cc',
'string_patch.dart',
'string_buffer_patch.dart',
- 'symbol_patch.dart',
'type_patch.dart',
'weak_property.dart',
'weak_property.cc',
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 6588649..8aa5abd 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -9,20 +9,39 @@
return (value == null || value is num || value is String || value is bool);
}
-Map _filterMap(Map old_map, bool filter(key, value)) {
- Map new_map = new Map();
+Map _filterMap(Map<Symbol, dynamic> old_map, bool filter(Symbol key, value)) {
+ Map new_map = new Map<Symbol, dynamic>();
old_map.forEach((key, value) {
- if (filter(key, value)) {
- new_map[key] = value;
- }
- });
+ if (filter(key, value)) {
+ new_map[key] = value;
+ }
+ });
return new_map;
}
+String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
+
+Symbol _s(String name) {
+ if (name == null) return null;
+ return new _symbol_dev.Symbol.unvalidated(name);
+}
+
+Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
+ if (owner == null) return simpleName;
+ return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}');
+}
+
+Map<Symbol, dynamic> _convertStringToSymbolMap(Map<String, dynamic> map) {
+ if (map == null) return null;
+ Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
+ map.forEach((name, value) => result[_s(name)] = value);
+ return result;
+}
+
String _makeSignatureString(TypeMirror returnType,
List<ParameterMirror> parameters) {
StringBuffer buf = new StringBuffer();
- buf.write(returnType.qualifiedName);
+ buf.write(_n(returnType.qualifiedName));
buf.write(' (');
bool found_optional_param = false;
for (int i = 0; i < parameters.length; i++) {
@@ -31,7 +50,7 @@
buf.write('[');
found_optional_param = true;
}
- buf.write(param.type.qualifiedName);
+ buf.write(_n(param.type.qualifiedName));
if (i < (parameters.length - 1)) {
buf.write(', ');
}
@@ -44,10 +63,13 @@
}
class _LocalMirrorSystemImpl implements MirrorSystem {
- _LocalMirrorSystemImpl(this.libraries, this.isolate)
- : _functionTypes = new Map<String, FunctionTypeMirror>() {}
+ // TODO(ahe): [libraries] should be Map<Uri, LibraryMirror>.
+ // Change parameter back to "this.libraries" when native code is changed.
+ _LocalMirrorSystemImpl(Map<String, LibraryMirror> libraries, this.isolate)
+ : _functionTypes = new Map<String, FunctionTypeMirror>(),
+ this.libraries = _convertStringToSymbolMap(libraries);
- final Map<String, LibraryMirror> libraries;
+ final Map<Symbol, LibraryMirror> libraries;
final IsolateMirror isolate;
TypeMirror _dynamicType = null;
@@ -139,10 +161,10 @@
abstract class _LocalObjectMirrorImpl extends _LocalVMObjectMirrorImpl
implements ObjectMirror {
_LocalObjectMirrorImpl(ref) : super(ref) {}
-
-Future<InstanceMirror> invokeAsync(String memberName,
- List positionalArguments,
- [Map<String,dynamic> namedArguments]) {
+
+ Future<InstanceMirror> invokeAsync(Symbol memberName,
+ List positionalArguments,
+ [Map<Symbol, dynamic> namedArguments]) {
if (namedArguments != null) {
throw new UnimplementedError(
'named argument support is not implemented');
@@ -155,29 +177,29 @@
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
try {
completer.complete(
- _invoke(this, memberName, positionalArguments));
+ _invoke(this, _n(memberName), positionalArguments));
} catch (exception, s) {
completer.completeError(exception, s);
}
return completer.future;
}
- Future<InstanceMirror> getFieldAsync(String fieldName) {
+ Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
try {
- completer.complete(_getField(this, fieldName));
+ completer.complete(_getField(this, _n(fieldName)));
} catch (exception, s) {
completer.completeError(exception, s);
}
return completer.future;
}
- Future<InstanceMirror> setFieldAsync(String fieldName, Object arg) {
+ Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object arg) {
_validateArgument(0, arg);
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
try {
- completer.complete(_setField(this, fieldName, arg));
+ completer.complete(_setField(this, _n(fieldName), arg));
} catch (exception, s) {
completer.completeError(exception, s);
}
@@ -304,7 +326,7 @@
}
Future<InstanceMirror> applyAsync(List<Object> positionalArguments,
- [Map<String,Object> namedArguments]) {
+ [Map<Symbol, Object> namedArguments]) {
if (namedArguments != null) {
throw new UnimplementedError(
'named argument support is not implemented');
@@ -324,7 +346,7 @@
return completer.future;
}
- Future<InstanceMirror> findInContext(String name) {
+ Future<InstanceMirror> findInContext(Symbol name) {
throw new UnimplementedError(
'ClosureMirror.findInContext() is not implemented');
}
@@ -334,13 +356,15 @@
}
class _LazyTypeMirror {
- _LazyTypeMirror(this.libraryName, this.typeName) {}
+ _LazyTypeMirror(String libraryName, String typeName)
+ : this.libraryName = _s(libraryName),
+ this.typeName = _s(typeName);
TypeMirror resolve(MirrorSystem mirrors) {
if (libraryName == null) {
- if (typeName == 'dynamic') {
+ if (typeName == const Symbol('dynamic')) {
return mirrors.dynamicType;
- } else if (typeName == 'void') {
+ } else if (typeName == const Symbol('void')) {
return mirrors.voidType;
} else {
throw new UnimplementedError(
@@ -355,35 +379,34 @@
return resolved;
}
- final String libraryName;
- final String typeName;
+ final Symbol libraryName;
+ final Symbol typeName;
}
class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
implements ClassMirror {
_LocalClassMirrorImpl(ref,
- this.simpleName,
+ String simpleName,
this.isClass,
this._owner,
this._superclass,
this._superinterfaces,
this._defaultFactory,
- this.members,
- this.constructors,
- this.typeVariables) : super(ref) {}
+ Map<String, Mirror> members,
+ Map<String, Mirror> constructors,
+ Map<String, Mirror> typeVariables)
+ : this.simpleName = _s(simpleName),
+ this.members = _convertStringToSymbolMap(members),
+ this.constructors = _convertStringToSymbolMap(constructors),
+ this.typeVariables = _convertStringToSymbolMap(typeVariables),
+ super(ref);
- final String simpleName;
+ final Symbol simpleName;
- String _qualifiedName = null;
- String get qualifiedName {
- if (_owner != null) {
- if (_qualifiedName == null) {
- _qualifiedName = '${owner.qualifiedName}.${simpleName}';
- }
- } else {
- // The owner of a ClassMirror is null in certain odd cases, like
- // 'void', 'dynamic' and function type mirrors.
- _qualifiedName = simpleName;
+ Symbol _qualifiedName = null;
+ Symbol get qualifiedName {
+ if (_qualifiedName == null) {
+ _qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
@@ -396,7 +419,7 @@
return _owner;
}
- bool get isPrivate => simpleName.startsWith('_');
+ bool get isPrivate => _n(simpleName).startsWith('_');
final bool isTopLevel = true;
@@ -436,14 +459,14 @@
return _defaultFactory;
}
- final Map<String, Mirror> members;
+ final Map<Symbol, Mirror> members;
- Map<String, MethodMirror> _methods = null;
- Map<String, MethodMirror> _getters = null;
- Map<String, MethodMirror> _setters = null;
- Map<String, VariableMirror> _variables = null;
+ Map<Symbol, MethodMirror> _methods = null;
+ Map<Symbol, MethodMirror> _getters = null;
+ Map<Symbol, MethodMirror> _setters = null;
+ Map<Symbol, VariableMirror> _variables = null;
- Map<String, MethodMirror> get methods {
+ Map<Symbol, MethodMirror> get methods {
if (_methods == null) {
_methods = _filterMap(
members,
@@ -452,7 +475,7 @@
return _methods;
}
- Map<String, MethodMirror> get getters {
+ Map<Symbol, MethodMirror> get getters {
if (_getters == null) {
_getters = _filterMap(
members,
@@ -461,7 +484,7 @@
return _getters;
}
- Map<String, MethodMirror> get setters {
+ Map<Symbol, MethodMirror> get setters {
if (_setters == null) {
_setters = _filterMap(
members,
@@ -470,7 +493,7 @@
return _setters;
}
- Map<String, VariableMirror> get variables {
+ Map<Symbol, VariableMirror> get variables {
if (_variables == null) {
_variables = _filterMap(
members,
@@ -479,10 +502,10 @@
return _variables;
}
- Map<String, MethodMirror> constructors;
- Map<String, TypeVariableMirror> typeVariables;
+ Map<Symbol, MethodMirror> constructors;
+ Map<Symbol, TypeVariableMirror> typeVariables;
- Map<String, TypeMirror> get typeArguments {
+ Map<Symbol, TypeMirror> get typeArguments {
throw new UnimplementedError(
'ClassMirror.typeArguments is not implemented');
}
@@ -499,9 +522,9 @@
String toString() => "ClassMirror on '$simpleName'";
- Future<InstanceMirror> newInstanceAsync(String constructorName,
+ Future<InstanceMirror> newInstanceAsync(Symbol constructorName,
List positionalArguments,
- [Map<String,dynamic> namedArguments]) {
+ [Map<Symbol, dynamic> namedArguments]) {
if (namedArguments != null) {
throw new UnimplementedError(
'named argument support is not implemented');
@@ -514,7 +537,7 @@
Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
try {
completer.complete(
- _invokeConstructor(this, constructorName, positionalArguments));
+ _invokeConstructor(this, _n(constructorName), positionalArguments));
} catch (exception) {
completer.completeError(exception);
}
@@ -569,28 +592,31 @@
class _LazyTypeVariableMirror {
- _LazyTypeVariableMirror(this._variableName, this._owner) {}
+ _LazyTypeVariableMirror(String variableName, this._owner)
+ : this._variableName = _s(variableName);
TypeVariableMirror resolve(MirrorSystem mirrors) {
ClassMirror owner = _owner.resolve(mirrors);
return owner.typeVariables[_variableName];
}
- final String _variableName;
+ final Symbol _variableName;
final _LazyTypeMirror _owner;
}
class _LocalTypeVariableMirrorImpl extends _LocalMirrorImpl
implements TypeVariableMirror {
- _LocalTypeVariableMirrorImpl(this.simpleName,
+ _LocalTypeVariableMirrorImpl(String simpleName,
this._owner,
- this._upperBound) {}
- final String simpleName;
+ this._upperBound)
+ : this.simpleName = _s(simpleName);
- String _qualifiedName = null;
- String get qualifiedName {
+ final Symbol simpleName;
+
+ Symbol _qualifiedName = null;
+ Symbol get qualifiedName {
if (_qualifiedName == null) {
- _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+ _qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
@@ -626,15 +652,17 @@
class _LocalTypedefMirrorImpl extends _LocalMirrorImpl
implements TypedefMirror {
- _LocalTypedefMirrorImpl(this.simpleName,
+ _LocalTypedefMirrorImpl(String simpleName,
this._owner,
- this._referent) {}
- final String simpleName;
+ this._referent)
+ : this.simpleName = _s(simpleName);
- String _qualifiedName = null;
- String get qualifiedName {
+ final Symbol simpleName;
+
+ Symbol _qualifiedName = null;
+ Symbol get qualifiedName {
if (_qualifiedName == null) {
- _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+ _qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
@@ -669,26 +697,30 @@
class _LazyLibraryMirror {
- _LazyLibraryMirror(this.libraryName) {}
+ _LazyLibraryMirror(String libraryName)
+ : this.libraryName = _s(libraryName);
LibraryMirror resolve(MirrorSystem mirrors) {
return mirrors.libraries[libraryName];
}
- final String libraryName;
+ final Symbol libraryName;
}
class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
implements LibraryMirror {
_LocalLibraryMirrorImpl(ref,
- this.simpleName,
+ String simpleName,
this.url,
- this.members) : super(ref) {}
+ Map<String, Mirror> members)
+ : this.simpleName = _s(simpleName),
+ this.members = _convertStringToSymbolMap(members),
+ super(ref);
- final String simpleName;
+ final Symbol simpleName;
// The simple name and the qualified name are the same for a library.
- String get qualifiedName => simpleName;
+ Symbol get qualifiedName => simpleName;
// Always null for libraries.
final DeclarationMirror owner = null;
@@ -705,15 +737,15 @@
}
final String url;
- final Map<String, Mirror> members;
+ final Map<Symbol, Mirror> members;
- Map<String, ClassMirror> _classes = null;
- Map<String, MethodMirror> _functions = null;
- Map<String, MethodMirror> _getters = null;
- Map<String, MethodMirror> _setters = null;
- Map<String, VariableMirror> _variables = null;
+ Map<Symbol, ClassMirror> _classes = null;
+ Map<Symbol, MethodMirror> _functions = null;
+ Map<Symbol, MethodMirror> _getters = null;
+ Map<Symbol, MethodMirror> _setters = null;
+ Map<Symbol, VariableMirror> _variables = null;
- Map<String, ClassMirror> get classes {
+ Map<Symbol, ClassMirror> get classes {
if (_classes == null) {
_classes = _filterMap(members,
(key, value) => (value is ClassMirror));
@@ -721,7 +753,7 @@
return _classes;
}
- Map<String, MethodMirror> get functions {
+ Map<Symbol, MethodMirror> get functions {
if (_functions == null) {
_functions = _filterMap(members,
(key, value) => (value is MethodMirror));
@@ -729,7 +761,7 @@
return _functions;
}
- Map<String, MethodMirror> get getters {
+ Map<Symbol, MethodMirror> get getters {
if (_getters == null) {
_getters = _filterMap(functions,
(key, value) => (value.isGetter));
@@ -737,7 +769,7 @@
return _getters;
}
- Map<String, MethodMirror> get setters {
+ Map<Symbol, MethodMirror> get setters {
if (_setters == null) {
_setters = _filterMap(functions,
(key, value) => (value.isSetter));
@@ -745,7 +777,7 @@
return _setters;
}
- Map<String, VariableMirror> get variables {
+ Map<Symbol, VariableMirror> get variables {
if (_variables == null) {
_variables = _filterMap(members,
(key, value) => (value is VariableMirror));
@@ -758,7 +790,7 @@
class _LocalMethodMirrorImpl extends _LocalMirrorImpl
implements MethodMirror {
- _LocalMethodMirrorImpl(this.simpleName,
+ _LocalMethodMirrorImpl(String simpleName,
this._owner,
this.parameters,
this._returnType,
@@ -770,14 +802,15 @@
this.isConstConstructor,
this.isGenerativeConstructor,
this.isRedirectingConstructor,
- this.isFactoryConstructor) {}
+ this.isFactoryConstructor)
+ : this.simpleName = _s(simpleName);
- final String simpleName;
+ final Symbol simpleName;
- String _qualifiedName = null;
- String get qualifiedName {
+ Symbol _qualifiedName = null;
+ Symbol get qualifiedName {
if (_qualifiedName == null) {
- _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+ _qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
@@ -791,7 +824,8 @@
}
bool get isPrivate {
- return simpleName.startsWith('_') || constructorName.startsWith('_');
+ return _n(simpleName).startsWith('_') ||
+ _n(constructorName).startsWith('_');
}
bool get isTopLevel => owner is LibraryMirror;
@@ -825,21 +859,21 @@
final bool isSetter;
final bool isConstructor;
- var _constructorName = null;
- String get constructorName {
+ Symbol _constructorName = null;
+ Symbol get constructorName {
if (_constructorName == null) {
if (!isConstructor) {
- _constructorName = '';
+ _constructorName = _s('');
} else {
- var parts = simpleName.split('.');
+ var parts = _n(simpleName).split('.');
if (parts.length > 2) {
throw new MirrorException(
'Internal error in MethodMirror.constructorName: '
'malformed name <$simpleName>');
} else if (parts.length == 2) {
- _constructorName = parts[1];
+ _constructorName = _s(parts[1]);
} else {
- _constructorName = '';
+ _constructorName = _s('');
}
}
}
@@ -856,18 +890,19 @@
class _LocalVariableMirrorImpl extends _LocalMirrorImpl
implements VariableMirror {
- _LocalVariableMirrorImpl(this.simpleName,
+ _LocalVariableMirrorImpl(String simpleName,
this._owner,
this._type,
this.isStatic,
- this.isFinal) {}
+ this.isFinal)
+ : this.simpleName = _s(simpleName);
- final String simpleName;
+ final Symbol simpleName;
- String _qualifiedName = null;
- String get qualifiedName {
+ Symbol _qualifiedName = null;
+ Symbol get qualifiedName {
if (_qualifiedName == null) {
- _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+ _qualifiedName = _computeQualifiedName(owner, simpleName);
}
return _qualifiedName;
}
@@ -881,7 +916,7 @@
}
bool get isPrivate {
- return simpleName.startsWith('_');
+ return _n(simpleName).startsWith('_');
}
bool get isTopLevel {
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index 78bbbd6..1c2e015 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import "dart:nativewrappers";
+// TODO(ahe): Move _symbol_dev.Symbol to its own "private" library?
+import "dart:_collection-dev" as _symbol_dev;
/**
* Returns a [MirrorSystem] for the current isolate.
@@ -28,3 +30,9 @@
patch InstanceMirror reflect(Object reflectee) {
return _Mirrors.reflect(reflectee);
}
+
+patch class MirrorSystem {
+ /* patch */ static String getName(Symbol symbol) {
+ return _symbol_dev.Symbol.getName(symbol);
+ }
+}
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index f6c6439..6c14f3e 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -33,7 +33,7 @@
Map<String, dynamic> namedArguments)
native "Object_noSuchMethod";
- /* patch */ noSuchMethod(InvocationMirror invocation) {
+ /* patch */ noSuchMethod(Invocation invocation) {
return _noSuchMethod(invocation.isMethod,
invocation.memberName,
invocation._type,
diff --git a/runtime/lib/stacktrace_patch.dart b/runtime/lib/stacktrace_patch.dart
index 2d5fdc5..a545a9c 100644
--- a/runtime/lib/stacktrace_patch.dart
+++ b/runtime/lib/stacktrace_patch.dart
@@ -3,9 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
patch class StackTrace {
- /* patch */ String get fullStackTrace native "Stacktrace_getFullStacktrace";
+ /* patch */ String get _fullStackTrace native "Stacktrace_getFullStacktrace";
- /* patch */ String get stackTrace native "Stacktrace_getStacktrace";
+ /* patch */ String get _stackTrace native "Stacktrace_getStacktrace";
/* patch */ void _setupFullStackTrace()
native "Stacktrace_setupFullStacktrace";
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 43101b0..2d148ec 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -157,41 +157,6 @@
return _substringUnchecked(startIndex, endIndex);
}
- String slice([int startIndex, int endIndex]) {
- int start, end;
- if (startIndex == null) {
- start = 0;
- } else if (startIndex is! int) {
- throw new ArgumentError("startIndex is not int");
- } else if (startIndex >= 0) {
- start = startIndex;
- } else {
- start = this.length + startIndex;
- }
- if (start < 0 || start > this.length) {
- throw new RangeError(
- "startIndex out of range: $startIndex (length: $length)");
- }
- if (endIndex == null) {
- end = this.length;
- } else if (endIndex is! int) {
- throw new ArgumentError("endIndex is not int");
- } else if (endIndex >= 0) {
- end = endIndex;
- } else {
- end = this.length + endIndex;
- }
- if (end < 0 || end > this.length) {
- throw new RangeError(
- "endIndex out of range: $endIndex (length: $length)");
- }
- if (end < start) {
- throw new ArgumentError(
- "End before start: $endIndex < $startIndex (length: $length)");
- }
- return _substringUnchecked(start, end);
- }
-
String _substringUnchecked(int startIndex, int endIndex) {
assert(endIndex != null);
assert((startIndex >= 0) && (startIndex <= this.length));
diff --git a/runtime/lib/symbol_patch.dart b/runtime/lib/symbol_patch.dart
index 6771348..4359019 100644
--- a/runtime/lib/symbol_patch.dart
+++ b/runtime/lib/symbol_patch.dart
@@ -2,34 +2,44 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-patch class Symbol {
- final String _name;
+patch class Symbol {
/* patch */ const Symbol(String name)
- : this._name = _validate(name);
-
+ : this._name = _validate(name);
static final RegExp _validationPattern =
- new RegExp(r'^[a-zA-Z$][a-zA-Z$0-9_]*=?');
+ new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
+ r'-|'
+ r'unary-|'
+ r'\[\]=|'
+ r'~|'
+ r'==|'
+ r'\[\]|'
+ r'\*|'
+ r'/|'
+ r'%|'
+ r'~/|'
+ r'\+|'
+ r'<<|'
+ r'>>|'
+ r'>=|'
+ r'>|'
+ r'<=|'
+ r'<|'
+ r'&|'
+ r'\^|'
+ r'\|'
+ r')$');
static _validate(String name) {
if (name is! String) throw new ArgumentError('name must be a String');
- if (name.isEmpty) return;
+ if (name.isEmpty) return name;
if (name.startsWith('_')) {
throw new ArgumentError('"$name" is a private identifier');
}
if (!_validationPattern.hasMatch(name)) {
throw new ArgumentError(
- '"$name" is not an identifier or an empty String');
+ '"$name" is not an identifier or an empty String');
}
return name;
}
-
- /* patch */ bool operator ==(other) {
- return other is Symbol && _name == other._name;
- }
-
- /* patch */ int get hashCode {
- const arbitraryPrime = 664597;
- return 0x1fffffff & (arbitraryPrime * _name.hashCode);
- }
}
diff --git a/runtime/lib/typeddata.dart b/runtime/lib/typeddata.dart
index 75f81a7..2cf2873 100644
--- a/runtime/lib/typeddata.dart
+++ b/runtime/lib/typeddata.dart
@@ -15,7 +15,9 @@
/* patch */ factory Int8List.fromList(List<int> elements) {
var result = new _Int8Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -41,7 +43,9 @@
/* patch */ factory Uint8List.fromList(List<int> elements) {
var result = new _Uint8Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -67,7 +71,9 @@
/* patch */ factory Uint8ClampedList.fromList(List<int> elements) {
var result = new _Uint8ClampedArray(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -94,7 +100,9 @@
/* patch */ factory Int16List.fromList(List<int> elements) {
var result = new _Int16Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -120,7 +128,9 @@
/* patch */ factory Uint16List.fromList(List<int> elements) {
var result = new _Uint16Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -146,7 +156,9 @@
/* patch */ factory Int32List.fromList(List<int> elements) {
var result = new _Int32Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -172,7 +184,9 @@
/* patch */ factory Uint32List.fromList(List<int> elements) {
var result = new _Uint32Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -198,7 +212,9 @@
/* patch */ factory Int64List.fromList(List<int> elements) {
var result = new _Int64Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -224,7 +240,9 @@
/* patch */ factory Uint64List.fromList(List<int> elements) {
var result = new _Uint64Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -250,7 +268,9 @@
/* patch */ factory Float32List.fromList(List<double> elements) {
var result = new _Float32Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -276,7 +296,9 @@
/* patch */ factory Float64List.fromList(List<double> elements) {
var result = new _Float64Array(elements.length);
- for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+ for (int i = 0; i < elements.length; i++) {
+ result[i] = elements[i];
+ }
return result;
}
@@ -515,14 +537,14 @@
throw new StateError("More than one element");
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot remove from a non-extendable array");
}
- void insertRange(int start, int length, [initialValue]) {
+ void replaceRange(int start, int end, Iterable iterable) {
throw new UnsupportedError(
- "Cannot add to a non-extendable array");
+ "Cannot remove from a non-extendable array");
}
List toList() {
@@ -546,13 +568,21 @@
return IterableMixinWorkaround.getRangeList(this, start, end);
}
- void setRange(int start, int length, List from, [int startFrom = 0]) {
- if (!_setRange(start, length, from, startFrom)) {
+ void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+ if (!_setRange(start, end - start, iterable, skipCount)) {
IterableMixinWorkaround.setRangeList(this, start,
- length, from, startFrom);
+ end, iterable, skipCount);
}
}
+ void setAll(int index, Iterable iterable) {
+ IterableMixinWorkaround.setAllList(this, index, iterable);
+ }
+
+ void fillRange(int start, int end, [fillValue]) {
+ IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+ }
+
// Method(s) implementing Object interface.
@@ -563,7 +593,7 @@
// Internal utility methods.
- bool _setRange(int start, int length, List from, startFrom)
+ bool _setRange(int start, int length, Iterable from, int startFrom)
native "TypedData_setRange";
}
diff --git a/runtime/tests/vm/dart/byte_array_optimized_test.dart b/runtime/tests/vm/dart/byte_array_optimized_test.dart
index ca3f9e5..45604fde3 100644
--- a/runtime/tests/vm/dart/byte_array_optimized_test.dart
+++ b/runtime/tests/vm/dart/byte_array_optimized_test.dart
@@ -33,8 +33,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -85,7 +83,7 @@
Expect.isTrue(copy is Int8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-128, 0, 1, 127]);
+ array.setRange(3, 7, [-128, 0, 1, 127]);
Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
array);
}
@@ -118,8 +116,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -158,7 +154,7 @@
Expect.isTrue(copy is Uint8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [257, 0, 1, 255]);
+ array.setRange(3, 7, [257, 0, 1, 255]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
array);
}
@@ -192,8 +188,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -244,7 +238,7 @@
Expect.isTrue(copy is Int16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-32768, 0, 1, 32767]);
+ array.setRange(3, 7, [-32768, 0, 1, 32767]);
Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
array);
}
@@ -278,8 +272,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -318,7 +310,7 @@
Expect.isTrue(copy is Uint16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+ array.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
array);
}
@@ -352,8 +344,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -410,7 +400,7 @@
Expect.isTrue(copy is Int32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+ array.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
array);
}
@@ -444,8 +434,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -487,7 +475,7 @@
Expect.isTrue(copy is Uint32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+ array.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
array);
}
@@ -524,8 +512,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -582,7 +568,7 @@
Expect.isTrue(copy is Int64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+ array.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
array);
@@ -617,8 +603,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -660,7 +644,7 @@
Expect.isTrue(copy is Uint64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+ array.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
array);
}
@@ -694,8 +678,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -723,7 +705,7 @@
Expect.isTrue(copy is Float32List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
array);
@@ -758,8 +740,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -787,7 +767,7 @@
Expect.isTrue(copy is Float64List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
array);
@@ -852,8 +832,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -917,7 +895,7 @@
Expect.isTrue(copy is Int8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-128, 0, 1, 127]);
+ view.setRange(3, 7, [-128, 0, 1, 127]);
Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0, 1, 2, 128, 0, 1, 127, 7, 8, 9, 0xFF],
@@ -981,8 +959,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1028,7 +1004,7 @@
Expect.isTrue(copy is Uint8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [257, 0, 1, 255]);
+ view.setRange(3, 7, [257, 0, 1, 255]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
view);
}
@@ -1090,8 +1066,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1160,7 +1134,7 @@
Expect.isTrue(copy is Int16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-32768, 0, 1, 32767]);
+ view.setRange(3, 7, [-32768, 0, 1, 32767]);
Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
@@ -1227,8 +1201,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1275,7 +1247,7 @@
Expect.isTrue(copy is Uint16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+ view.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, 0, 0, 1, 0, 2, 0,
@@ -1342,8 +1314,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1433,7 +1403,7 @@
Expect.isTrue(copy is Int32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+ view.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
@@ -1498,8 +1468,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1560,7 +1528,7 @@
Expect.isTrue(copy is Uint32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+ view.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, -1, -1, 0, 0, 0, 0,
@@ -1629,8 +1597,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1750,7 +1716,7 @@
Expect.isTrue(copy is Int64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+ view.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
view);
@@ -1830,8 +1796,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1910,7 +1874,7 @@
Expect.isTrue(copy is Uint64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+ view.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, -1, -1, -1, -1, -1, -1,
@@ -1986,8 +1950,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -2020,7 +1982,7 @@
Expect.isTrue(copy is Float32List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
view);
@@ -2091,8 +2053,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -2125,7 +2085,7 @@
Expect.isTrue(copy is Float64List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
view);
diff --git a/runtime/tests/vm/dart/byte_array_test.dart b/runtime/tests/vm/dart/byte_array_test.dart
index 388e1bb..876642a 100644
--- a/runtime/tests/vm/dart/byte_array_test.dart
+++ b/runtime/tests/vm/dart/byte_array_test.dart
@@ -31,8 +31,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -86,7 +84,7 @@
Expect.isTrue(copy is Int8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-128, 0, 1, 127]);
+ array.setRange(3, 7, [-128, 0, 1, 127]);
Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
array);
}
@@ -123,8 +121,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -166,7 +162,7 @@
Expect.isTrue(copy is Uint8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [257, 0, 1, 255]);
+ array.setRange(3, 7, [257, 0, 1, 255]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
array);
}
@@ -204,8 +200,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -244,7 +238,7 @@
Expect.isTrue(copy is Uint8ClampedList);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [257, 0, 1, 255]);
+ array.setRange(3, 7, [257, 0, 1, 255]);
Expect.listEquals([0, 1, 2, 255, 0, 1, 255, 7, 8, 9], array);
}
@@ -281,8 +275,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -336,7 +328,7 @@
Expect.isTrue(copy is Int16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-32768, 0, 1, 32767]);
+ array.setRange(3, 7, [-32768, 0, 1, 32767]);
Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
array);
}
@@ -374,8 +366,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -417,7 +407,7 @@
Expect.isTrue(copy is Uint16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+ array.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
array);
}
@@ -455,8 +445,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -516,7 +504,7 @@
Expect.isTrue(copy is Int32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+ array.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
array);
}
@@ -554,8 +542,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -600,7 +586,7 @@
Expect.isTrue(copy is Uint32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+ array.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
array);
}
@@ -639,8 +625,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -700,7 +684,7 @@
Expect.isTrue(copy is Int64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+ array.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
array);
@@ -739,8 +723,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -785,7 +767,7 @@
Expect.isTrue(copy is Uint64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- array.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+ array.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
array);
}
@@ -823,8 +805,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -855,7 +835,7 @@
Expect.isTrue(copy is Float32List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
array);
@@ -894,8 +874,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -926,7 +904,7 @@
Expect.isTrue(copy is Float64List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
array);
@@ -1138,8 +1116,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1203,7 +1179,7 @@
Expect.isTrue(copy is Int8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-128, 0, 1, 127]);
+ view.setRange(3, 7, [-128, 0, 1, 127]);
Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0, 1, 2, 128, 0, 1, 127, 7, 8, 9, 0xFF],
@@ -1269,8 +1245,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1316,7 +1290,7 @@
Expect.isTrue(copy is Uint8List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [257, 0, 1, 255]);
+ view.setRange(3, 7, [257, 0, 1, 255]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
view);
}
@@ -1380,8 +1354,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1450,7 +1422,7 @@
Expect.isTrue(copy is Int16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-32768, 0, 1, 32767]);
+ view.setRange(3, 7, [-32768, 0, 1, 32767]);
Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
@@ -1519,8 +1491,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1567,7 +1537,7 @@
Expect.isTrue(copy is Uint16List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+ view.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, 0, 0, 1, 0, 2, 0,
@@ -1636,8 +1606,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1727,7 +1695,7 @@
Expect.isTrue(copy is Int32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+ view.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
view);
Expect.listEquals([0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
@@ -1792,8 +1760,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -1854,7 +1820,7 @@
Expect.isTrue(copy is Uint32List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+ view.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, -1, -1, 0, 0, 0, 0,
@@ -1925,8 +1891,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -2046,7 +2010,7 @@
Expect.isTrue(copy is Int64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+ view.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
view);
@@ -2128,8 +2092,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { view.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { view.insertRange(0, view.length, 0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { view.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { view.removeLast(); },
@@ -2208,7 +2170,7 @@
Expect.isTrue(copy is Uint64List);
Expect.equals(4, region.length);
Expect.listEquals([3, 4, 5, 6], region);
- view.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+ view.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
view);
Expect.listEquals([-1, -1, -1, -1, -1, -1, -1, -1,
@@ -2286,8 +2248,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -2320,7 +2280,7 @@
Expect.isTrue(copy is Float32List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
view);
@@ -2393,8 +2353,6 @@
(e) { return e is UnsupportedError; });
Expect.throws(() { array.clear(); },
(e) { return e is UnsupportedError; });
- Expect.throws(() { array.insertRange(0, array.length, 0.0); },
- (e) { return e is UnsupportedError; });
Expect.throws(() { array.length = 0; },
(e) { return e is UnsupportedError; });
Expect.throws(() { array.removeLast(); },
@@ -2427,7 +2385,7 @@
Expect.isTrue(copy is Float64List);
Expect.equals(4, region.length);
Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
- view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+ view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
1.0, double.INFINITY, 7.0, 8.0, 9.0],
view);
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index e72f5a1..772ce66 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -49,7 +49,8 @@
sort(list) => list.sort(_stringCompare);
String buildMethodString(MethodMirror func) {
- var result = '${func.simpleName} return(${func.returnType.simpleName})';
+ var result = '${MirrorSystem.getName(func.simpleName)} '
+ 'return(${MirrorSystem.getName(func.returnType.simpleName)})';
if (func.isPrivate) {
result = '$result private';
}
@@ -90,7 +91,8 @@
}
String buildVariableString(VariableMirror variable) {
- var result = '${variable.simpleName} type(${variable.type.simpleName})';
+ var result = '${MirrorSystem.getName(variable.simpleName)} '
+ 'type(${MirrorSystem.getName(variable.type.simpleName)})';
if (variable.isPrivate) {
result = '$result private';
}
@@ -107,27 +109,30 @@
}
void testRootLibraryMirror(LibraryMirror lib_mirror) {
- Expect.equals('isolate_mirror_local_test', lib_mirror.simpleName);
- Expect.equals('isolate_mirror_local_test', lib_mirror.qualifiedName);
+ Expect.equals(const Symbol('isolate_mirror_local_test'),
+ lib_mirror.simpleName);
+ Expect.equals(const Symbol('isolate_mirror_local_test'),
+ lib_mirror.qualifiedName);
Expect.equals(null, lib_mirror.owner);
Expect.isFalse(lib_mirror.isPrivate);
Expect.isTrue(lib_mirror.url.contains('isolate_mirror_local_test.dart'));
- Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
- lib_mirror.toString());
+ // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+ // Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
+ // lib_mirror.toString());
// Test library invocation by calling function(123).
Expect.equals(0, global_var);
- lib_mirror.invokeAsync('function', [123]).then(
+ lib_mirror.invokeAsync(const Symbol('function'), [123]).then(
(InstanceMirror retval) {
Expect.equals(123, global_var);
- Expect.equals('int', retval.type.simpleName);
+ Expect.equals(const Symbol('int'), retval.type.simpleName);
Expect.isTrue(retval.hasReflectee);
Expect.equals(124, retval.reflectee);
testDone('testRootLibraryMirror');
});
// Check that the members map is complete.
- List keys = lib_mirror.members.keys.toList();
+ List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('['
'FuncType, '
@@ -164,7 +169,7 @@
'$keys');
// Check that the classes map is complete.
- keys = lib_mirror.classes.keys.toList();
+ keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('['
'FuncType, '
@@ -176,7 +181,7 @@
'$keys');
// Check that the functions map is complete.
- keys = lib_mirror.functions.keys.toList();
+ keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('['
'_stringCompare, '
@@ -202,17 +207,17 @@
'$keys');
// Check that the getters map is complete.
- keys = lib_mirror.getters.keys.toList();
+ keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('[myVar]', '$keys');
// Check that the setters map is complete.
- keys = lib_mirror.setters.keys.toList();
+ keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('[myVar=]', '$keys');
// Check that the variables map is complete.
- keys = lib_mirror.variables.keys.toList();
+ keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList();
sort(keys);
Expect.equals('['
'exit_port, '
@@ -222,108 +227,114 @@
'myFunc]',
'$keys');
- ClassMirror cls_mirror = lib_mirror.members['MyClass'];
- ClassMirror generic_cls_mirror = lib_mirror.members['GenericClass'];
+ ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')];
+ ClassMirror generic_cls_mirror =
+ lib_mirror.members[const Symbol('GenericClass')];
// Test function mirrors.
- MethodMirror func = lib_mirror.members['function'];
+ MethodMirror func = lib_mirror.members[const Symbol('function')];
Expect.isTrue(func is MethodMirror);
Expect.equals('function return(int) toplevel static method',
buildMethodString(func));
- func = lib_mirror.members['myVar'];
+ func = lib_mirror.members[const Symbol('myVar')];
Expect.isTrue(func is MethodMirror);
Expect.equals('myVar return(int) toplevel static getter',
buildMethodString(func));
- func = lib_mirror.members['myVar='];
+ func = lib_mirror.members[const Symbol('myVar=')];
Expect.isTrue(func is MethodMirror);
Expect.equals('myVar= return(void) toplevel static setter',
buildMethodString(func));
- func = cls_mirror.members['method'];
+ func = cls_mirror.members[const Symbol('method')];
Expect.isTrue(func is MethodMirror);
Expect.equals('method return(int) method', buildMethodString(func));
- func = cls_mirror.constructors['MyClass'];
+ func = cls_mirror.constructors[const Symbol('MyClass')];
Expect.isTrue(func is MethodMirror);
Expect.equals('MyClass return(MyClass) constructor', buildMethodString(func));
- func = cls_mirror.constructors['MyClass.named'];
+ func = cls_mirror.constructors[const Symbol('MyClass.named')];
Expect.isTrue(func is MethodMirror);
Expect.equals('MyClass.named return(MyClass) constructor',
buildMethodString(func));
- func = generic_cls_mirror.members['method'];
+ func = generic_cls_mirror.members[const Symbol('method')];
Expect.isTrue(func is MethodMirror);
Expect.equals('method return(T) method', buildMethodString(func));
// Test variable mirrors.
- VariableMirror variable = lib_mirror.members['global_var'];
+ VariableMirror variable = lib_mirror.members[const Symbol('global_var')];
Expect.isTrue(variable is VariableMirror);
Expect.equals('global_var type(int) toplevel static',
buildVariableString(variable));
- variable = lib_mirror.members['final_global_var'];
+ variable = lib_mirror.members[const Symbol('final_global_var')];
Expect.isTrue(variable is VariableMirror);
Expect.equals('final_global_var type(int) toplevel static final',
buildVariableString(variable));
- variable = cls_mirror.members['value'];
+ variable = cls_mirror.members[const Symbol('value')];
Expect.isTrue(variable is VariableMirror);
Expect.equals('value type(dynamic) final', buildVariableString(variable));
// Test type variable mirrors.
- var type_var = generic_cls_mirror.members['method'].returnType;
+ var type_var = generic_cls_mirror.members[const Symbol('method')].returnType;
Expect.isTrue(type_var is TypeVariableMirror);
- Expect.equals('GenericClass', type_var.owner.simpleName);
- Expect.equals('Object', type_var.upperBound.simpleName);
+ Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName);
+ Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName);
// Test typedef mirrors.
- var typedef_mirror = lib_mirror.members['myFunc'].type;
+ var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type;
Expect.isTrue(typedef_mirror is TypedefMirror);
- Expect.equals('isolate_mirror_local_test', typedef_mirror.owner.simpleName);
+ Expect.equals(const Symbol('isolate_mirror_local_test'),
+ typedef_mirror.owner.simpleName);
// Test function type mirrors.
var func_cls_mirror = typedef_mirror.referent;
Expect.isTrue(func_cls_mirror is FunctionTypeMirror);
- Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
- Expect.equals('void', func_cls_mirror.returnType.simpleName);
+ // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
+ Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName);
}
void testLibrariesMap(Map libraries) {
// Just look for a couple of well-known libs.
- LibraryMirror core_lib = libraries['dart.core'];
+ LibraryMirror core_lib = libraries[const Symbol('dart.core')];
Expect.isTrue(core_lib is LibraryMirror);
- LibraryMirror mirror_lib = libraries['dart.mirrors'];
+ LibraryMirror mirror_lib = libraries[const Symbol('dart.mirrors')];
Expect.isTrue(mirror_lib is LibraryMirror);
// Lookup an interface from a library and make sure it is sane.
- ClassMirror list_intf = core_lib.members['List'];
+ ClassMirror list_intf = core_lib.members[const Symbol('List')];
Expect.isTrue(list_intf is ClassMirror);
- Expect.equals('List', list_intf.simpleName);
- Expect.equals('dart.core.List', list_intf.qualifiedName);
+ Expect.equals(const Symbol('List'), list_intf.simpleName);
+ Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName);
Expect.isFalse(list_intf.isPrivate);
- Expect.equals('Object', list_intf.superclass.simpleName);
- Expect.equals('dart.core', list_intf.owner.simpleName);
+ Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName);
+ Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName);
Expect.isTrue(list_intf.isClass);
- Expect.equals('Iterable', list_intf.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'List'", list_intf.toString());
+ Expect.equals(const Symbol('Iterable'),
+ list_intf.superinterfaces[0].simpleName);
+ // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+ // Expect.equals("ClassMirror on 'List'", list_intf.toString());
// Lookup a class from a library and make sure it is sane.
- ClassMirror oom_cls = core_lib.members['OutOfMemoryError'];
+ ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
Expect.isTrue(oom_cls is ClassMirror);
- Expect.equals('OutOfMemoryError', oom_cls.simpleName);
- Expect.equals('dart.core.OutOfMemoryError', oom_cls.qualifiedName);
+ Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName);
+ Expect.equals(const Symbol('dart.core.OutOfMemoryError'),
+ oom_cls.qualifiedName);
Expect.isFalse(oom_cls.isPrivate);
- Expect.equals('Object', oom_cls.superclass.simpleName);
+ Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName);
Expect.isTrue(oom_cls.defaultFactory == null);
- Expect.equals('dart.core', oom_cls.owner.simpleName);
+ Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
Expect.isTrue(oom_cls.isClass);
- Expect.equals('Error', oom_cls.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'OutOfMemoryError'",
- oom_cls.toString());
+ Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
+ // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+ // Expect.equals("ClassMirror on 'OutOfMemoryError'",
+ // oom_cls.toString());
testDone('testLibrariesMap');
}
@@ -331,21 +342,21 @@
Expect.isTrue(mirrors.isolate.debugName.contains('main'));
testRootLibraryMirror(mirrors.isolate.rootLibrary);
testLibrariesMap(mirrors.libraries);
- Expect.equals('void', mirrors.voidType.simpleName);
- Expect.equals('dynamic', mirrors.dynamicType.simpleName);
+ Expect.equals(const Symbol('void'), mirrors.voidType.simpleName);
+ Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName);
testDone('testMirrorSystem');
}
void testIntegerInstanceMirror(InstanceMirror mirror) {
- Expect.equals('int', mirror.type.simpleName);
+ Expect.equals(const Symbol('int'), mirror.type.simpleName);
Expect.isTrue(mirror.hasReflectee);
Expect.equals(1001, mirror.reflectee);
Expect.equals("InstanceMirror on <1001>", mirror.toString());
// Invoke (mirror + mirror).
- mirror.invokeAsync('+', [ mirror ]).then(
+ mirror.invokeAsync(const Symbol('+'), [ mirror ]).then(
(InstanceMirror retval) {
- Expect.equals('int', retval.type.simpleName);
+ Expect.equals(const Symbol('int'), retval.type.simpleName);
Expect.isTrue(retval.hasReflectee);
Expect.equals(2002, retval.reflectee);
testDone('testIntegerInstanceMirror');
@@ -353,16 +364,16 @@
}
void testStringInstanceMirror(InstanceMirror mirror) {
- Expect.equals('String', mirror.type.simpleName);
+ Expect.equals(const Symbol('String'), mirror.type.simpleName);
Expect.isTrue(mirror.hasReflectee);
Expect.equals('This\nis\na\nString', mirror.reflectee);
Expect.equals("InstanceMirror on <'This\\nis\\na\\nString'>",
mirror.toString());
// Invoke mirror[0].
- mirror.invokeAsync('[]', [ 0 ]).then(
+ mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then(
(InstanceMirror retval) {
- Expect.equals('String', retval.type.simpleName);
+ Expect.equals(const Symbol('String'), retval.type.simpleName);
Expect.isTrue(retval.hasReflectee);
Expect.equals('T', retval.reflectee);
testDone('testStringInstanceMirror');
@@ -370,7 +381,7 @@
}
void testBoolInstanceMirror(InstanceMirror mirror) {
- Expect.equals('bool', mirror.type.simpleName);
+ Expect.equals(const Symbol('bool'), mirror.type.simpleName);
Expect.isTrue(mirror.hasReflectee);
Expect.equals(true, mirror.reflectee);
Expect.equals("InstanceMirror on <true>", mirror.toString());
@@ -379,7 +390,7 @@
void testNullInstanceMirror(InstanceMirror mirror) {
// TODO(turnidge): This is returning the wrong class. Fix it.
- Expect.equals('Object', mirror.type.simpleName);
+ Expect.equals(const Symbol('Object'), mirror.type.simpleName);
Expect.isTrue(mirror.hasReflectee);
Expect.equals(null, mirror.reflectee);
Expect.equals("InstanceMirror on <null>", mirror.toString());
@@ -418,23 +429,25 @@
saw_exception = true;
}
Expect.isFalse(saw_exception);
- Expect.equals("InstanceMirror on instance of 'MyClass'", mirror.toString());
+ // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+ // Expect.equals("InstanceMirror on instance of 'MyClass'",
+ // mirror.toString());
ClassMirror cls = mirror.type;
Expect.isTrue(cls is ClassMirror);
- Expect.equals('MyClass', cls.simpleName);
- Expect.equals('MySuperClass', cls.superclass.simpleName);
+ Expect.equals(const Symbol('MyClass'), cls.simpleName);
+ Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
Expect.isTrue(cls.defaultFactory == null);
- Expect.equals('isolate_mirror_local_test', cls.owner.simpleName);
+ Expect.equals(const Symbol('isolate_mirror_local_test'), cls.owner.simpleName);
Expect.isTrue(cls.isClass);
- Expect.equals('MyInterface', cls.superinterfaces[0].simpleName);
- Expect.equals("ClassMirror on 'MyClass'",
- cls.toString());
+ Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
+ // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+ // Expect.equals("ClassMirror on 'MyClass'", cls.toString());
// Invoke mirror.method(1000).
- mirror.invokeAsync('method', [ 1000 ]).then(
+ mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
(InstanceMirror retval) {
- Expect.equals('int', retval.type.simpleName);
+ Expect.equals(const Symbol('int'), retval.type.simpleName);
Expect.isTrue(retval.hasReflectee);
Expect.equals(1017, retval.reflectee);
testDone('testCustomInstanceMirror');
@@ -460,44 +473,44 @@
void testMirrorErrors(MirrorSystem mirrors) {
LibraryMirror lib_mirror = mirrors.isolate.rootLibrary;
- lib_mirror.invokeAsync('methodWithException', [])
+ lib_mirror.invokeAsync(const Symbol('methodWithException'), [])
.then((InstanceMirror retval) {
// Should not reach here.
Expect.isTrue(false);
})
- .catchError((exc) {
- Expect.isTrue(exc.error is MirroredUncaughtExceptionError);
- Expect.equals('MyException',
- exc.error.exception_mirror.type.simpleName);
+ .catchError((error) {
+ Expect.isTrue(error is MirroredUncaughtExceptionError);
+ Expect.equals(const Symbol('MyException'),
+ error.exception_mirror.type.simpleName);
Expect.equals('MyException: from methodWithException',
- exc.error.exception_string);
- Expect.isTrue(exc.error.stacktrace.toString().contains(
+ error.exception_string);
+ Expect.isTrue(error.stacktrace.toString().contains(
'isolate_mirror_local_test.dart'));
testDone('testMirrorErrors1');
});
- lib_mirror.invokeAsync('methodWithError', [])
+ lib_mirror.invokeAsync(const Symbol('methodWithError'), [])
.then((InstanceMirror retval) {
// Should not reach here.
Expect.isTrue(false);
})
- .catchError((exc) {
- Expect.isTrue(exc.error is MirroredCompilationError);
- Expect.isTrue(exc.error.message.contains('unexpected token'));
+ .catchError((error) {
+ Expect.isTrue(error is MirroredCompilationError);
+ Expect.isTrue(error.message.contains('unexpected token'));
testDone('testMirrorErrors2');
});
// TODO(turnidge): When we call a method that doesn't exist, we
// should probably call noSuchMethod(). I'm adding this test to
// document the current behavior in the meantime.
- lib_mirror.invokeAsync('methodNotFound', [])
+ lib_mirror.invokeAsync(const Symbol('methodNotFound'), [])
.then((InstanceMirror retval) {
// Should not reach here.
Expect.isTrue(false);
})
- .catchError((exc) {
- Expect.isTrue(exc.error is MirroredCompilationError);
- Expect.isTrue(exc.error.message.contains(
+ .catchError((error) {
+ Expect.isTrue(error is MirroredCompilationError);
+ Expect.isTrue(error.message.contains(
"did not find top-level function 'methodNotFound'"));
testDone('testMirrorErrors3');
});
diff --git a/runtime/tests/vm/dart/optimized_stacktrace_test.dart b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
index 40413c5..d002a2e 100644
--- a/runtime/tests/vm/dart/optimized_stacktrace_test.dart
+++ b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
@@ -4,7 +4,7 @@
// Test correct source positions in stack trace with optimized functions.
import "package:expect/expect.dart";
-// (1) Test normal exception.
+// (1) Test normal exception.
foo(x) => bar(x);
bar(x) {
@@ -19,8 +19,8 @@
Expect.fail("Unreachable");
} catch (e, stacktrace) {
String s = stacktrace.toString();
- Expect.equals(-1, s.indexOf("-1:-1"));
- Expect.notEquals(-1, s.indexOf("11:18"));
+ Expect.isFalse(s.contains("-1:-1"));
+ Expect.isTrue(s.contains("11:18"));
}
// Optimized.
@@ -30,8 +30,8 @@
Expect.fail("Unreachable");
} catch (e, stacktrace) {
String s = stacktrace.toString();
- Expect.equals(-1, s.indexOf("-1:-1"));
- Expect.notEquals(-1, s.indexOf("11:18"));
+ Expect.isFalse(s.contains("-1:-1"));
+ Expect.isTrue(s.contains("11:18"));
}
}
@@ -56,9 +56,9 @@
} catch (e, stacktrace) {
String s = stacktrace.toString();
print(s);
- Expect.notEquals(-1, s.indexOf("maximus"));
- Expect.notEquals(-1, s.indexOf("moritz"));
- Expect.equals(-1, s.indexOf("-1:-1"));
+ Expect.isTrue(s.contains("maximus"));
+ Expect.isTrue(s.contains("moritz"));
+ Expect.isFalse(s.contains("-1:-1"));
}
try {
@@ -66,9 +66,9 @@
} catch (e, stacktrace) {
String s = stacktrace.toString();
print(s);
- Expect.notEquals(-1, s.indexOf("maximus"));
- Expect.notEquals(-1, s.indexOf("moritz"));
- Expect.equals(-1, s.indexOf("-1:-1"));
+ Expect.isTrue(s.contains("maximus"));
+ Expect.isTrue(s.contains("moritz"));
+ Expect.isFalse(s.contains("-1:-1"));
}
}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 45afdd9..8d62b96 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -70,7 +70,6 @@
[ $arch == simmips ]
# Tests needing an assembler.
cc/Dart2JSCompileAll: Skip
-cc/UseDartApi: Skip
# Tests needing Dart execution.
dart/*: Skip
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index b8aed32..8f21b6d 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -117,6 +117,45 @@
}
+void Assembler::SubuDetectOverflow(Register rd, Register rs, Register rt,
+ Register ro) {
+ ASSERT(rd != ro);
+ ASSERT(rd != TMP1);
+ ASSERT(ro != TMP1);
+ ASSERT(ro != rs);
+ ASSERT(ro != rt);
+ ASSERT(rs != TMP1);
+ ASSERT(rt != TMP1);
+
+ // This happens with some crankshaft code. Since Subu works fine if
+ // left == right, let's not make that restriction here.
+ if (rs == rt) {
+ mov(rd, ZR);
+ mov(ro, ZR);
+ return;
+ }
+
+ if (rd == rs) {
+ mov(TMP1, rs); // Preserve left.
+ subu(rd, rs, rt); // Left is overwritten.
+ xor_(ro, rd, TMP1); // scratch is original left.
+ xor_(TMP1, TMP1, rs); // scratch is original left.
+ and_(ro, TMP1, ro);
+ } else if (rd == rt) {
+ mov(TMP1, rt); // Preserve right.
+ subu(rd, rs, rt); // Right is overwritten.
+ xor_(ro, rd, rs);
+ xor_(TMP1, rs, TMP1); // Original right.
+ and_(ro, TMP1, ro);
+ } else {
+ subu(rd, rs, rt);
+ xor_(ro, rd, rs);
+ xor_(TMP1, rs, rt);
+ and_(ro, TMP1, ro);
+ }
+}
+
+
void Assembler::LoadObject(Register rd, const Object& object) {
// Smi's and VM heap objects are never relocated; do not use object pool.
if (object.IsSmi()) {
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index f21d030..770eecd 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -553,6 +553,12 @@
EmitFpuLoadStore(SWC1, ft, addr);
}
+ void xori(Register rt, Register rs, const Immediate& imm) {
+ ASSERT(Utils::IsUint(kImmBits, imm.value()));
+ const uint16_t imm_value = static_cast<uint16_t>(imm.value());
+ EmitIType(XORI, rs, rt, imm_value);
+ }
+
void xor_(Register rd, Register rs, Register rt) {
EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
}
@@ -573,6 +579,20 @@
AdduDetectOverflow(rd, rs, rd, ro);
}
+ // Subtraction of rt from rs (rs - rt) with the result placed in rd.
+ // After, ro < 0 if there was signed overflow, ro >= 0 otherwise.
+ // None of rd, rs, rt, or ro may be TMP1.
+ // ro must be different from the other registers.
+ void SubuDetectOverflow(Register rd, Register rs, Register rt, Register ro);
+
+ // ro must be different from rd and rs.
+ // None of rd, rs, rt, or ro may be TMP1.
+ void SubImmediateDetectOverflow(Register rd, Register rs, int32_t imm,
+ Register ro) {
+ LoadImmediate(rd, imm);
+ SubuDetectOverflow(rd, rs, rd, ro);
+ }
+
void Branch(const ExternalLabel* label) {
LoadImmediate(TMP1, label->address());
jr(TMP1);
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 0bd651c..f5ff667 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -576,6 +576,19 @@
}
+ASSEMBLER_TEST_GENERATE(Xori, assembler) {
+ __ LoadImmediate(T0, 51);
+ __ xori(V0, T0, Immediate(25));
+ __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Xori, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
ASSEMBLER_TEST_GENERATE(Slt, assembler) {
__ LoadImmediate(R1, -1);
__ LoadImmediate(R2, 0);
@@ -1108,6 +1121,54 @@
}
+ASSEMBLER_TEST_GENERATE(SubOverflow_detect, assembler) {
+ Register left = T0;
+ Register right = T1;
+ Register result = T2;
+ Register overflow = T3;
+ Label error, done;
+
+ __ LoadImmediate(V0, 1); // Success value.
+
+ __ LoadImmediate(left, 0x80000000);
+ __ LoadImmediate(right, 1);
+ __ SubuDetectOverflow(result, left, right, overflow);
+ __ bgez(overflow, &error); // INT_MIN - 1 overflows.
+
+ __ LoadImmediate(left, 0x7fffffff);
+ __ LoadImmediate(right, 0x8000000);
+ __ SubuDetectOverflow(result, left, left, overflow);
+ __ bltz(overflow, &error); // INT_MIN - INT_MAX does not overflow.
+
+ __ LoadImmediate(left, 0x80000000);
+ __ LoadImmediate(right, 0x80000000);
+ __ SubuDetectOverflow(result, left, right, overflow);
+ __ bltz(overflow, &error); // INT_MIN - INT_MIN does not overflow.
+
+ __ LoadImmediate(left, 0x7fffffff);
+ __ LoadImmediate(right, 0x80000000);
+ __ SubuDetectOverflow(result, left, right, overflow);
+ __ bgez(overflow, &error); // INT_MAX - INT_MIN overflows.
+
+ __ LoadImmediate(left, 1);
+ __ LoadImmediate(right, -1);
+ __ SubuDetectOverflow(result, left, right, overflow);
+ __ bltz(overflow, &error); // 1 - -1 does not overflow.
+
+ __ b(&done);
+ __ Bind(&error);
+ __ mov(V0, ZR);
+ __ Bind(&done);
+ __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(SubOverflow_detect, test) {
+ typedef int (*SimpleCode)();
+ EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
ASSEMBLER_TEST_GENERATE(Mtc1Mfc1, assembler) {
__ mtc1(ZR, F0);
__ mfc1(V0, F0);
diff --git a/runtime/vm/bit_vector.cc b/runtime/vm/bit_vector.cc
index 80b640b..b97c18e 100644
--- a/runtime/vm/bit_vector.cc
+++ b/runtime/vm/bit_vector.cc
@@ -88,10 +88,10 @@
}
-void BitVector::Intersect(const BitVector& other) {
- ASSERT(other.length() == length());
+void BitVector::Intersect(const BitVector* other) {
+ ASSERT(other->length() == length());
for (int i = 0; i < data_length_; i++) {
- data_[i] = data_[i] & other.data_[i];
+ data_[i] = data_[i] & other->data_[i];
}
}
diff --git a/runtime/vm/bit_vector.h b/runtime/vm/bit_vector.h
index 3dcd118..76f6450 100644
--- a/runtime/vm/bit_vector.h
+++ b/runtime/vm/bit_vector.h
@@ -83,7 +83,7 @@
// bitvector kill.
bool KillAndAdd(BitVector* kill, BitVector* gen);
- void Intersect(const BitVector& other);
+ void Intersect(const BitVector* other);
bool Contains(int i) const {
ASSERT(i >= 0 && i < length());
diff --git a/runtime/vm/bit_vector_test.cc b/runtime/vm/bit_vector_test.cc
index de2fe4f..83bc2cf 100644
--- a/runtime/vm/bit_vector_test.cc
+++ b/runtime/vm/bit_vector_test.cc
@@ -91,7 +91,7 @@
b->Add(1);
b->Add(31);
b->Add(32);
- a->Intersect(*b);
+ a->Intersect(b);
EXPECT_EQ(true, a->Equals(*b));
}
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 06527b7..d52fc5e 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -51,7 +51,7 @@
RawScript* Bootstrap::LoadCollectionDevScript(bool patch) {
const char* url =
patch ? "dart:_collection-dev-patch" : "dart:_collection-dev";
- const char* source = patch ? collection_dev_source_ : collection_dev_source_;
+ const char* source = patch ? collection_dev_patch_ : collection_dev_source_;
return LoadScript(url, source, patch);
}
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index fdb616d..020d819 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -42,6 +42,7 @@
static const char collection_source_[];
static const char collection_patch_[];
static const char collection_dev_source_[];
+ static const char collection_dev_patch_[];
static const char crypto_source_[];
static const char isolate_source_[];
static const char isolate_patch_[];
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index e39278b..6d0b880 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -224,6 +224,10 @@
// A canonicalization pass to remove e.g. smi checks on smi constants.
optimizer.Canonicalize();
DEBUG_ASSERT(flow_graph->VerifyUseLists());
+ // Canonicalization introduced more opportunities for constant
+ // propagation.
+ ConstantPropagator::Optimize(flow_graph);
+ DEBUG_ASSERT(flow_graph->VerifyUseLists());
}
// Propagate types and eliminate even more type tests.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 435b7d8..78866cf 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -183,6 +183,11 @@
enum Condition {
EQ, // equal
NE, // not equal
+ GT, // greater than
+ GE, // greater equal
+ LT, // less than
+ LE, // less equal
+ VS, // overflow
};
diff --git a/runtime/vm/cpu_mips.cc b/runtime/vm/cpu_mips.cc
index 06aa026..51a679b 100644
--- a/runtime/vm/cpu_mips.cc
+++ b/runtime/vm/cpu_mips.cc
@@ -7,6 +7,7 @@
#if defined(TARGET_ARCH_MIPS)
#if defined(HOST_ARCH_MIPS)
+#include <asm/cachectl.h> /* NOLINT */
#include <sys/syscall.h> /* NOLINT */
#include <unistd.h> /* NOLINT */
#endif
@@ -16,7 +17,15 @@
namespace dart {
void CPU::FlushICache(uword start, uword size) {
- UNIMPLEMENTED();
+#if defined(HOST_ARCH_MIPS)
+ int res;
+ // See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
+ res = syscall(__NR_cacheflush, start, size, ICACHE);
+ ASSERT(res == 0);
+#else // defined(HOST_ARCH_MIPS)
+ // When running in simulated mode we do not need to flush the ICache because
+ // we are not running on the actual hardware.
+#endif // defined(HOST_ARCH_MIPS)
}
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e7ee27b..f8d8b96 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2404,6 +2404,11 @@
case kExternalTypedDataFloat64ArrayCid :
type = kFloat64;
break;
+ case kTypedDataFloat32x4ArrayCid :
+ case kTypedDataFloat32x4ArrayViewCid :
+ case kExternalTypedDataFloat32x4ArrayCid :
+ type = kFloat32x4;
+ break;
default:
type = kInvalid;
break;
@@ -2566,6 +2571,8 @@
return NewTypedData(isolate, kTypedDataFloat32ArrayCid, length);
case kFloat64 :
return NewTypedData(isolate, kTypedDataFloat64ArrayCid, length);
+ case kFloat32x4:
+ return NewTypedData(isolate, kTypedDataFloat32x4ArrayCid, length);
default:
return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
CURRENT_FUNC);
@@ -2588,74 +2595,80 @@
}
CHECK_CALLBACK_STATE(isolate);
switch (type) {
- case kByteData :
+ case kByteData:
return NewExternalByteData(isolate, data, length, peer, callback);
- case kInt8 :
+ case kInt8:
return NewExternalTypedData(kExternalTypedDataInt8ArrayCid,
data,
length,
peer,
callback);
- case kUint8 :
+ case kUint8:
return NewExternalTypedData(kExternalTypedDataUint8ArrayCid,
data,
length,
peer,
callback);
- case kUint8Clamped :
+ case kUint8Clamped:
return NewExternalTypedData(kExternalTypedDataUint8ClampedArrayCid,
data,
length,
peer,
callback);
- case kInt16 :
+ case kInt16:
return NewExternalTypedData(kExternalTypedDataInt16ArrayCid,
data,
length,
peer,
callback);
- case kUint16 :
+ case kUint16:
return NewExternalTypedData(kExternalTypedDataUint16ArrayCid,
data,
length,
peer,
callback);
- case kInt32 :
+ case kInt32:
return NewExternalTypedData(kExternalTypedDataInt32ArrayCid,
data,
length,
peer,
callback);
- case kUint32 :
+ case kUint32:
return NewExternalTypedData(kExternalTypedDataUint32ArrayCid,
data,
length,
peer,
callback);
- case kInt64 :
+ case kInt64:
return NewExternalTypedData(kExternalTypedDataInt64ArrayCid,
data,
length,
peer,
callback);
- case kUint64 :
+ case kUint64:
return NewExternalTypedData(kExternalTypedDataUint64ArrayCid,
data,
length,
peer,
callback);
- case kFloat32 :
+ case kFloat32:
return NewExternalTypedData(kExternalTypedDataFloat32ArrayCid,
data,
length,
peer,
callback);
- case kFloat64 :
+ case kFloat64:
return NewExternalTypedData(kExternalTypedDataFloat64ArrayCid,
data,
length,
peer,
callback);
+ case kFloat32x4:
+ return NewExternalTypedData(kExternalTypedDataFloat32x4ArrayCid,
+ data,
+ length,
+ peer,
+ callback);
default:
return Api::NewError("%s expects argument 'type' to be of"
" 'external TypedData'", CURRENT_FUNC);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index cc2d2de..a47c70c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1359,6 +1359,55 @@
EXPECT(peer == 42);
}
+
+static void CheckFloat32x4Data(Dart_Handle obj) {
+ void* raw_data = NULL;
+ intptr_t len;
+ Dart_TypedData_Type type;
+ EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len));
+ EXPECT_EQ(kFloat32x4, type);
+ EXPECT_EQ(len, 10);
+ float* float_data = reinterpret_cast<float*>(raw_data);
+ for (int i = 0; i < len * 4; i++) {
+ EXPECT_EQ(0.0, float_data[i]);
+ }
+ EXPECT_VALID(Dart_TypedDataReleaseData(obj));
+}
+
+
+TEST_CASE(Float32x4List) {
+ const char* kScriptChars =
+ "import 'dart:typeddata';\n"
+ "Float32x4List float32x4() {\n"
+ " return new Float32x4List(10);\n"
+ "}\n";
+ // Create a test library and Load up a test script in it.
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+
+ Dart_Handle obj = Dart_Invoke(lib, NewString("float32x4"), 0, NULL);
+ EXPECT_VALID(obj);
+ CheckFloat32x4Data(obj);
+
+ obj = Dart_NewTypedData(kFloat32x4, 10);
+ EXPECT_VALID(obj);
+ CheckFloat32x4Data(obj);
+
+ int peer = 0;
+ float data[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+ obj = Dart_NewExternalTypedData(kFloat32x4,
+ data,
+ 10,
+ &peer,
+ ExternalTypedDataCallbackFinalizer);
+ CheckFloat32x4Data(obj);
+ Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+ EXPECT(peer == 42);
+}
+
+
#endif
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 5315301b..34eb977 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -125,21 +125,49 @@
}
-Dart_CObject* ApiMessageReader::AllocateDartCObjectUint8Array(intptr_t length) {
+static int GetTypedDataSizeInBytes(Dart_CObject::TypedDataType type) {
+ switch (type) {
+ case Dart_CObject::kInt8Array:
+ case Dart_CObject::kUint8Array:
+ case Dart_CObject::kUint8ClampedArray:
+ return 1;
+ case Dart_CObject::kInt16Array:
+ case Dart_CObject::kUint16Array:
+ return 2;
+ case Dart_CObject::kInt32Array:
+ case Dart_CObject::kUint32Array:
+ case Dart_CObject::kFloat32Array:
+ return 4;
+ case Dart_CObject::kInt64Array:
+ case Dart_CObject::kUint64Array:
+ case Dart_CObject::kFloat64Array:
+ return 8;
+ default:
+ break;
+ }
+ UNREACHABLE();
+ return -1;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData(
+ Dart_CObject::TypedDataType type, intptr_t length) {
// Allocate a Dart_CObject structure followed by an array of bytes
// for the byte array content. The pointer to the byte array content
// is set up to this area.
+ intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length;
Dart_CObject* value =
reinterpret_cast<Dart_CObject*>(
- alloc_(NULL, 0, sizeof(Dart_CObject) + length));
+ alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes));
ASSERT(value != NULL);
- value->type = Dart_CObject::kUint8Array;
- value->value.as_array.length = length;
+ value->type = Dart_CObject::kTypedData;
+ value->value.as_typed_data.type = type;
+ value->value.as_typed_data.length = length_in_bytes;
if (length > 0) {
- value->value.as_byte_array.values =
+ value->value.as_typed_data.values =
reinterpret_cast<uint8_t*>(value) + sizeof(*value);
} else {
- value->value.as_byte_array.values = NULL;
+ value->value.as_typed_data.values = NULL;
}
return value;
}
@@ -191,6 +219,47 @@
}
+static Dart_CObject::TypedDataType GetTypedDataTypeFromView(
+ Dart_CObject_Internal* object) {
+ struct {
+ const char* name;
+ Dart_CObject::TypedDataType type;
+ } view_class_names[] = {
+ { "_Int8ArrayView", Dart_CObject::kInt8Array },
+ { "_Uint8ArrayView", Dart_CObject::kUint8Array },
+ { "_Uint8ClampedArrayView", Dart_CObject::kUint8ClampedArray },
+ { "_Int16ArrayView", Dart_CObject::kInt16Array },
+ { "_Uint16ArrayView", Dart_CObject::kUint16Array },
+ { "_Int32ArrayView", Dart_CObject::kInt32Array },
+ { "_Uint32ArrayView", Dart_CObject::kUint32Array },
+ { "_Int64ArrayView", Dart_CObject::kInt64Array },
+ { "_Uint64ArrayView", Dart_CObject::kUint64Array },
+ { "_ByteDataView", Dart_CObject::kUint8Array },
+ { "_Float32ArrayView", Dart_CObject::kFloat32Array },
+ { "_Float64ArrayView", Dart_CObject::kFloat64Array },
+ { NULL, Dart_CObject::kNumberOfTypedDataTypes },
+ };
+
+ char* library_url =
+ object->cls->internal.as_class.library_url->value.as_string;
+ char* class_name =
+ object->cls->internal.as_class.class_name->value.as_string;
+ if (strcmp("dart:typeddata", library_url) != 0) {
+ return Dart_CObject::kNumberOfTypedDataTypes;
+ }
+ int i = 0;
+ while (view_class_names[i].name != NULL) {
+ if (strncmp(view_class_names[i].name,
+ class_name,
+ strlen(view_class_names[i].name)) == 0) {
+ return view_class_names[i].type;
+ }
+ i++;
+ }
+ return Dart_CObject::kNumberOfTypedDataTypes;
+}
+
+
Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
// Read the class header information and lookup the class.
intptr_t class_header = ReadIntptrValue();
@@ -217,30 +286,29 @@
Dart_CObject_Internal::kUninitialized));
// Handle typed data views.
- char* library_url =
- object->cls->internal.as_class.library_url->value.as_string;
- char* class_name =
- object->cls->internal.as_class.class_name->value.as_string;
- if (strcmp("dart:typeddata", library_url) == 0 &&
- strncmp("_Uint8ArrayView", class_name, 15) == 0) {
+ Dart_CObject::TypedDataType type = GetTypedDataTypeFromView(object);
+ if (type != Dart_CObject::kNumberOfTypedDataTypes) {
object->type =
static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView);
- // Skip type arguments.
- ReadObjectImpl();
+ ReadObjectImpl(); // Skip type arguments.
object->internal.as_view.buffer = ReadObjectImpl();
object->internal.as_view.offset_in_bytes = ReadSmiValue();
object->internal.as_view.length = ReadSmiValue();
+ ReadObjectImpl(); // Skip last field.
// The buffer is fully read now as typed data objects are
// serialized in-line.
Dart_CObject* buffer = object->internal.as_view.buffer;
- ASSERT(buffer->type == Dart_CObject::kUint8Array);
+ ASSERT(buffer->type == Dart_CObject::kTypedData);
// Now turn the view into a byte array.
- object->type = Dart_CObject::kUint8Array;
- object->value.as_byte_array.length = object->internal.as_view.length;
- object->value.as_byte_array.values =
- buffer->value.as_byte_array.values +
+ object->type = Dart_CObject::kTypedData;
+ object->value.as_typed_data.type = type;
+ object->value.as_typed_data.length =
+ object->internal.as_view.length *
+ GetTypedDataSizeInBytes(type);
+ object->value.as_typed_data.values =
+ buffer->value.as_typed_data.values +
object->internal.as_view.offset_in_bytes;
} else {
// TODO(sgjesse): Handle other instances. Currently this will
@@ -509,19 +577,67 @@
::free(utf16);
return object;
}
+
+#define READ_TYPED_DATA(type, ctype) \
+ { \
+ intptr_t len = ReadSmiValue(); \
+ Dart_CObject* object = \
+ AllocateDartCObjectTypedData(Dart_CObject::k##type##Array, len); \
+ AddBackRef(object_id, object, kIsDeserialized); \
+ if (len > 0) { \
+ ctype* p = \
+ reinterpret_cast<ctype*>(object->value.as_typed_data.values); \
+ for (intptr_t i = 0; i < len; i++) { \
+ p[i] = Read<ctype>(); \
+ } \
+ } \
+ return object; \
+ } \
+
+ case kTypedDataInt8ArrayCid:
+ case kExternalTypedDataInt8ArrayCid:
+ READ_TYPED_DATA(Int8, int8_t);
+
case kTypedDataUint8ArrayCid:
- case kExternalTypedDataUint8ArrayCid: {
- intptr_t len = ReadSmiValue();
- Dart_CObject* object = AllocateDartCObjectUint8Array(len);
- AddBackRef(object_id, object, kIsDeserialized);
- if (len > 0) {
- uint8_t* p = object->value.as_byte_array.values;
- for (intptr_t i = 0; i < len; i++) {
- p[i] = Read<uint8_t>();
- }
- }
- return object;
- }
+ case kExternalTypedDataUint8ArrayCid:
+ READ_TYPED_DATA(Uint8, uint8_t);
+
+ case kTypedDataUint8ClampedArrayCid:
+ case kExternalTypedDataUint8ClampedArrayCid:
+ READ_TYPED_DATA(Uint8Clamped, uint8_t);
+
+ case kTypedDataInt16ArrayCid:
+ case kExternalTypedDataInt16ArrayCid:
+ READ_TYPED_DATA(Int16, int16_t);
+
+ case kTypedDataUint16ArrayCid:
+ case kExternalTypedDataUint16ArrayCid:
+ READ_TYPED_DATA(Uint16, uint16_t);
+
+ case kTypedDataInt32ArrayCid:
+ case kExternalTypedDataInt32ArrayCid:
+ READ_TYPED_DATA(Int32, int32_t);
+
+ case kTypedDataUint32ArrayCid:
+ case kExternalTypedDataUint32ArrayCid:
+ READ_TYPED_DATA(Uint32, uint32_t);
+
+ case kTypedDataInt64ArrayCid:
+ case kExternalTypedDataInt64ArrayCid:
+ READ_TYPED_DATA(Int64, int64_t);
+
+ case kTypedDataUint64ArrayCid:
+ case kExternalTypedDataUint64ArrayCid:
+ READ_TYPED_DATA(Uint64, uint64_t);
+
+ case kTypedDataFloat32ArrayCid:
+ case kExternalTypedDataFloat32ArrayCid:
+ READ_TYPED_DATA(Float32, float);
+
+ case kTypedDataFloat64ArrayCid:
+ case kExternalTypedDataFloat64ArrayCid:
+ READ_TYPED_DATA(Float64, double);
+
case kGrowableObjectArrayCid: {
// A GrowableObjectArray is serialized as its length followed by
// its backing store. The backing store is an array with a
@@ -924,22 +1040,34 @@
}
break;
}
- case Dart_CObject::kUint8Array: {
+ case Dart_CObject::kTypedData: {
// Write out the serialization header value for this object.
WriteInlinedHeader(object);
// Write out the class and tags information.
- WriteIndexedObject(kTypedDataUint8ArrayCid);
- WriteIntptrValue(RawObject::ClassIdTag::update(
- kTypedDataUint8ArrayCid, 0));
- uint8_t* bytes = object->value.as_byte_array.values;
- intptr_t len = object->value.as_byte_array.length;
+ intptr_t class_id;
+ switch (object->value.as_typed_data.type) {
+ case Dart_CObject::kInt8Array:
+ class_id = kTypedDataInt8ArrayCid;
+ break;
+ case Dart_CObject::kUint8Array:
+ class_id = kTypedDataUint8ArrayCid;
+ break;
+ default:
+ class_id = kTypedDataUint8ArrayCid;
+ UNIMPLEMENTED();
+ }
+
+ WriteIndexedObject(class_id);
+ WriteIntptrValue(RawObject::ClassIdTag::update(class_id, 0));
+ uint8_t* bytes = object->value.as_typed_data.values;
+ intptr_t len = object->value.as_typed_data.length;
WriteSmi(len);
for (intptr_t i = 0; i < len; i++) {
Write<uint8_t>(bytes[i]);
}
break;
}
- case Dart_CObject::kExternalUint8Array: {
+ case Dart_CObject::kExternalTypedData: {
// TODO(ager): we are writing C pointers into the message in
// order to post external arrays through ports. We need to make
// sure that messages containing pointers can never be posted
@@ -951,11 +1079,11 @@
WriteIndexedObject(kExternalTypedDataUint8ArrayCid);
WriteIntptrValue(RawObject::ClassIdTag::update(
kExternalTypedDataUint8ArrayCid, 0));
- int length = object->value.as_external_byte_array.length;
- uint8_t* data = object->value.as_external_byte_array.data;
- void* peer = object->value.as_external_byte_array.peer;
+ int length = object->value.as_external_typed_data.length;
+ uint8_t* data = object->value.as_external_typed_data.data;
+ void* peer = object->value.as_external_typed_data.peer;
Dart_WeakPersistentHandleFinalizer callback =
- object->value.as_external_byte_array.callback;
+ object->value.as_external_typed_data.callback;
WriteSmi(length);
WriteIntptrValue(reinterpret_cast<intptr_t>(data));
WriteIntptrValue(reinterpret_cast<intptr_t>(peer));
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index d215ab0..3ad8fb9 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -88,8 +88,9 @@
Dart_CObject* AllocateDartCObjectDouble(double value);
// Allocates a Dart_CObject object for string data.
Dart_CObject* AllocateDartCObjectString(intptr_t length);
- // Allocates a C Dart_CObject object for byte data.
- Dart_CObject* AllocateDartCObjectUint8Array(intptr_t length);
+ // Allocates a C Dart_CObject object for a typed data.
+ Dart_CObject* AllocateDartCObjectTypedData(
+ Dart_CObject::TypedDataType type, intptr_t length);
// Allocates a C array of Dart_CObject objects.
Dart_CObject* AllocateDartCObjectArray(intptr_t length);
// Allocates a Dart_CObject_Internal object with the specified type.
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 08bef08..63fc459 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -111,7 +111,7 @@
const Array& arguments,
const Array& arguments_descriptor) {
ASSERT(receiver.raw() == arguments.At(0));
- // Allocate an InvocationMirror object.
+ // Allocate an Invocation object.
const Library& core_lib = Library::Handle(Library::CoreLibrary());
Class& invocation_mirror_class = Class::Handle(
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index cf4c340..e18ad81 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -224,23 +224,22 @@
DART_EXPORT Dart_Handle Dart_ActivationFrameGetLocation(
Dart_ActivationFrame activation_frame,
- Dart_Handle* script_url,
- intptr_t* library_id,
- intptr_t* token_number) {
- // TODO(hausner): Implement implement a way to recognize when there
+ Dart_Handle* function_name,
+ Dart_CodeLocation* location) {
+ // TODO(hausner): Implement a way to recognize when there
// is no source code for the code in the frame.
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
- if (script_url != NULL) {
- *script_url = Api::NewHandle(isolate, frame->SourceUrl());
+ if (function_name != NULL) {
+ *function_name = Api::NewHandle(isolate, frame->QualifiedFunctionName());
}
- if (library_id != NULL) {
+
+ if (location != NULL) {
+ location->script_url = Api::NewHandle(isolate, frame->SourceUrl());
const Library& lib = Library::Handle(frame->Library());
- *library_id = lib.index();
- }
- if (token_number != NULL) {
- *token_number = frame->TokenPos();
+ location->library_id = lib.index();
+ location->token_pos = frame->TokenPos();
}
return Api::True(isolate);
}
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 717acbf..bfa3438 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -632,6 +632,10 @@
Format(instr, "swc1 'ft, 'imms('rs)");
break;
}
+ case XORI: {
+ Format(instr, "xori 'rt, 'rs, 'immu");
+ break;
+ }
default: {
Unknown(instr);
break;
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 03074f7..cb8ca07 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -19,7 +19,6 @@
GraphEntryInstr* graph_entry,
intptr_t max_block_id)
: parent_(),
- assigned_vars_(),
current_ssa_temp_index_(0),
max_block_id_(max_block_id),
parsed_function_(builder.parsed_function()),
@@ -87,14 +86,12 @@
postorder_.Clear();
reverse_postorder_.Clear();
parent_.Clear();
- assigned_vars_.Clear();
// Perform a depth-first traversal of the graph to build preorder and
// postorder block orders.
graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor.
&preorder_,
&postorder_,
&parent_,
- &assigned_vars_,
variable_count(),
num_non_copied_params());
// Create an array of blocks in reverse postorder.
@@ -208,17 +205,231 @@
#endif // DEBUG
+LivenessAnalysis::LivenessAnalysis(
+ intptr_t variable_count,
+ const GrowableArray<BlockEntryInstr*>& postorder)
+ : variable_count_(variable_count),
+ postorder_(postorder),
+ live_out_(postorder.length()),
+ kill_(postorder.length()),
+ live_in_(postorder.length()) {
+}
+
+
+bool LivenessAnalysis::UpdateLiveOut(const BlockEntryInstr& block) {
+ BitVector* live_out = live_out_[block.postorder_number()];
+ bool changed = false;
+ Instruction* last = block.last_instruction();
+ ASSERT(last != NULL);
+ for (intptr_t i = 0; i < last->SuccessorCount(); i++) {
+ BlockEntryInstr* succ = last->SuccessorAt(i);
+ ASSERT(succ != NULL);
+ if (live_out->AddAll(live_in_[succ->postorder_number()])) {
+ changed = true;
+ }
+ }
+ return changed;
+}
+
+
+bool LivenessAnalysis::UpdateLiveIn(const BlockEntryInstr& block) {
+ BitVector* live_out = live_out_[block.postorder_number()];
+ BitVector* kill = kill_[block.postorder_number()];
+ BitVector* live_in = live_in_[block.postorder_number()];
+ return live_in->KillAndAdd(kill, live_out);
+}
+
+
+void LivenessAnalysis::ComputeLiveInAndLiveOutSets() {
+ const intptr_t block_count = postorder_.length();
+ bool changed;
+ do {
+ changed = false;
+
+ for (intptr_t i = 0; i < block_count; i++) {
+ const BlockEntryInstr& block = *postorder_[i];
+
+ // Live-in set depends only on kill set which does not
+ // change in this loop and live-out set. If live-out
+ // set does not change there is no need to recompute
+ // live-in set.
+ if (UpdateLiveOut(block) && UpdateLiveIn(block)) {
+ changed = true;
+ }
+ }
+ } while (changed);
+}
+
+
+void LivenessAnalysis::Analyze() {
+ const intptr_t block_count = postorder_.length();
+ for (intptr_t i = 0; i < block_count; i++) {
+ live_out_.Add(new BitVector(variable_count_));
+ kill_.Add(new BitVector(variable_count_));
+ live_in_.Add(new BitVector(variable_count_));
+ }
+
+ ComputeInitialSets();
+ ComputeLiveInAndLiveOutSets();
+}
+
+
+static void PrintBitVector(const char* tag, BitVector* v) {
+ OS::Print("%s:", tag);
+ for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
+ OS::Print(" %"Pd"", it.Current());
+ }
+ OS::Print("\n");
+}
+
+
+void LivenessAnalysis::Dump() {
+ const intptr_t block_count = postorder_.length();
+ for (intptr_t i = 0; i < block_count; i++) {
+ BlockEntryInstr* block = postorder_[i];
+ OS::Print("block @%"Pd" -> ", block->block_id());
+
+ Instruction* last = block->last_instruction();
+ for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
+ BlockEntryInstr* succ = last->SuccessorAt(j);
+ OS::Print(" @%"Pd"", succ->block_id());
+ }
+ OS::Print("\n");
+
+ PrintBitVector(" live out", live_out_[i]);
+ PrintBitVector(" kill", kill_[i]);
+ PrintBitVector(" live in", live_in_[i]);
+ }
+}
+
+
+// Computes liveness information for local variables.
+class VariableLivenessAnalysis : public LivenessAnalysis {
+ public:
+ explicit VariableLivenessAnalysis(FlowGraph* flow_graph)
+ : LivenessAnalysis(flow_graph->variable_count(), flow_graph->postorder()),
+ flow_graph_(flow_graph),
+ num_non_copied_params_(flow_graph->num_non_copied_params()),
+ assigned_vars_() { }
+
+ // For every block (in preorder) compute and return set of variables that
+ // have new assigned values flowing out of that block.
+ const GrowableArray<BitVector*>& ComputeAssignedVars() {
+ // We can't directly return kill_ because it uses postorder numbering while
+ // SSA construction uses preorder numbering internally.
+ // We have to permute postorder into preorder.
+ assigned_vars_.Clear();
+
+ const intptr_t block_count = flow_graph_->preorder().length();
+ for (intptr_t i = 0; i < block_count; i++) {
+ BlockEntryInstr* block = flow_graph_->preorder()[i];
+ BitVector* kill = GetKillSet(block);
+ kill->Intersect(GetLiveOutSet(block));
+ assigned_vars_.Add(kill);
+ }
+
+ return assigned_vars_;
+ }
+
+ // Returns true if the value set by the given store reaches any load from the
+ // same local variable.
+ bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
+ if (store->is_dead()) {
+ return false;
+ }
+
+ if (store->is_last()) {
+ const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
+ return GetLiveOutSet(block)->Contains(index);
+ }
+
+ return true;
+ }
+
+ // Returns true if the given load is the last for the local and the value
+ // of the local will not flow into another one.
+ bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
+ const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
+ return load->is_last() && !GetLiveOutSet(block)->Contains(index);
+ }
+
+ private:
+ virtual void ComputeInitialSets();
+
+ const FlowGraph* flow_graph_;
+ const intptr_t num_non_copied_params_;
+ GrowableArray<BitVector*> assigned_vars_;
+};
+
+
+void VariableLivenessAnalysis::ComputeInitialSets() {
+ const intptr_t block_count = postorder_.length();
+
+ BitVector* last_loads = new BitVector(variable_count_);
+ for (intptr_t i = 0; i < block_count; i++) {
+ BlockEntryInstr* block = postorder_[i];
+
+ BitVector* kill = kill_[i];
+ BitVector* live_in = live_in_[i];
+ last_loads->Clear();
+
+ // Iterate backwards starting at the last instruction.
+ for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+ Instruction* current = it.Current();
+
+ LoadLocalInstr* load = current->AsLoadLocal();
+ if (load != NULL) {
+ const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
+ live_in->Add(index);
+ if (!last_loads->Contains(index)) {
+ last_loads->Add(index);
+ load->mark_last();
+ }
+ continue;
+ }
+
+ StoreLocalInstr* store = current->AsStoreLocal();
+ if (store != NULL) {
+ const intptr_t index =
+ store->local().BitIndexIn(num_non_copied_params_);
+ if (kill->Contains(index)) {
+ if (!live_in->Contains(index)) {
+ store->mark_dead();
+ }
+ } else {
+ if (!live_in->Contains(index)) {
+ store->mark_last();
+ }
+ kill->Add(index);
+ }
+ live_in->Remove(index);
+ continue;
+ }
+ }
+ }
+}
+
+
void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number,
GrowableArray<Definition*>* inlining_parameters) {
ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL));
current_ssa_temp_index_ = next_virtual_register_number;
GrowableArray<BitVector*> dominance_frontier;
ComputeDominators(&dominance_frontier);
- InsertPhis(preorder_, assigned_vars_, dominance_frontier);
+
+ VariableLivenessAnalysis variable_liveness(this);
+ variable_liveness.Analyze();
+
+ InsertPhis(preorder_,
+ variable_liveness.ComputeAssignedVars(),
+ dominance_frontier);
+
GrowableArray<PhiInstr*> live_phis;
+
// Rename uses to reference inserted phis where appropriate.
// Collect phis that reach a non-environment use.
- Rename(&live_phis, inlining_parameters);
+ Rename(&live_phis, &variable_liveness, inlining_parameters);
+
// Propagate alive mark transitively from alive phis and then remove
// non-live ones.
RemoveDeadPhis(&live_phis);
@@ -399,6 +610,7 @@
void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
+ VariableLivenessAnalysis* variable_liveness,
GrowableArray<Definition*>* inlining_parameters) {
// TODO(fschneider): Support catch-entry.
if (graph_entry_->SuccessorCount() > 1) {
@@ -439,7 +651,7 @@
BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
ASSERT(normal_entry != NULL); // Must have entry.
- RenameRecursive(normal_entry, &env, live_phis);
+ RenameRecursive(normal_entry, &env, live_phis, variable_liveness);
}
@@ -462,7 +674,8 @@
void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry,
GrowableArray<Definition*>* env,
- GrowableArray<PhiInstr*>* live_phis) {
+ GrowableArray<PhiInstr*>* live_phis,
+ VariableLivenessAnalysis* variable_liveness) {
// 1. Process phis first.
if (block_entry->IsJoinEntry()) {
JoinEntryInstr* join = block_entry->AsJoinEntry();
@@ -527,25 +740,37 @@
StoreLocalInstr* store = definition->AsStoreLocal();
if ((load != NULL) || (store != NULL)) {
intptr_t index;
+ Definition* result;
if (store != NULL) {
- index = store->local().BitIndexIn(num_non_copied_params_);
// Update renaming environment.
- (*env)[index] = store->value()->definition();
+ index = store->local().BitIndexIn(num_non_copied_params_);
+ result = store->value()->definition();
+
+ if (variable_liveness->IsStoreAlive(block_entry, store)) {
+ (*env)[index] = result;
+ } else {
+ (*env)[index] = constant_null();
+ }
} else {
// The graph construction ensures we do not have an unused LoadLocal
// computation.
ASSERT(definition->is_used());
index = load->local().BitIndexIn(num_non_copied_params_);
+ result = (*env)[index];
- PhiInstr* phi = (*env)[index]->AsPhi();
+ PhiInstr* phi = result->AsPhi();
if ((phi != NULL) && !phi->is_alive()) {
phi->mark_alive();
live_phis->Add(phi);
}
+
+ if (variable_liveness->IsLastLoad(block_entry, load)) {
+ (*env)[index] = constant_null();
+ }
}
// Update expression stack or remove from graph.
if (definition->is_used()) {
- env->Add((*env)[index]);
+ env->Add(result);
// We remove load/store instructions when we find their use in 2a.
} else {
it.RemoveCurrentFromGraph();
@@ -572,7 +797,7 @@
BlockEntryInstr* block = block_entry->dominated_blocks()[i];
GrowableArray<Definition*> new_env(env->length());
new_env.AddArray(*env);
- RenameRecursive(block, &new_env, live_phis);
+ RenameRecursive(block, &new_env, live_phis, variable_liveness);
}
// 4. Process successor block. We have edge-split form, so that only blocks
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 13d9cba..d761fa2 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -13,6 +13,7 @@
class FlowGraphBuilder;
class ValueInliningContext;
+class VariableLivenessAnalysis;
class BlockIterator : public ValueObject {
public:
@@ -154,11 +155,14 @@
GrowableArray<intptr_t>* label);
void Rename(GrowableArray<PhiInstr*>* live_phis,
+ VariableLivenessAnalysis* variable_liveness,
GrowableArray<Definition*>* inlining_parameters);
+
void RenameRecursive(
BlockEntryInstr* block_entry,
GrowableArray<Definition*>* env,
- GrowableArray<PhiInstr*>* live_phis);
+ GrowableArray<PhiInstr*>* live_phis,
+ VariableLivenessAnalysis* variable_liveness);
void AttachEnvironment(Instruction* instr, GrowableArray<Definition*>* env);
@@ -192,6 +196,77 @@
ConstantInstr* constant_null_;
};
+
+class LivenessAnalysis : public ValueObject {
+ public:
+ LivenessAnalysis(intptr_t variable_count,
+ const GrowableArray<BlockEntryInstr*>& postorder);
+
+ void Analyze();
+
+ virtual ~LivenessAnalysis() { }
+
+ BitVector* GetLiveInSetAt(intptr_t postorder_number) const {
+ return live_in_[postorder_number];
+ }
+
+ BitVector* GetLiveOutSetAt(intptr_t postorder_number) const {
+ return live_out_[postorder_number];
+ }
+
+ BitVector* GetLiveInSet(BlockEntryInstr* block) const {
+ return GetLiveInSetAt(block->postorder_number());
+ }
+
+ BitVector* GetKillSet(BlockEntryInstr* block) const {
+ return kill_[block->postorder_number()];
+ }
+
+ BitVector* GetLiveOutSet(BlockEntryInstr* block) const {
+ return GetLiveOutSetAt(block->postorder_number());
+ }
+
+ // Print results of liveness analysis.
+ void Dump();
+
+ protected:
+ // Compute initial values for live-out, kill and live-in sets.
+ virtual void ComputeInitialSets() = 0;
+
+ // Update live-out set for the given block: live-out should contain
+ // all values that are live-in for block's successors.
+ // Returns true if live-out set was changed.
+ bool UpdateLiveOut(const BlockEntryInstr& instr);
+
+ // Update live-in set for the given block: live-in should contain
+ // all values that are live-out from the block and are not defined
+ // by this block.
+ // Returns true if live-in set was changed.
+ bool UpdateLiveIn(const BlockEntryInstr& instr);
+
+ // Perform fix-point iteration updating live-out and live-in sets
+ // for blocks until they stop changing.
+ void ComputeLiveInAndLiveOutSets();
+
+ const intptr_t variable_count_;
+
+ const GrowableArray<BlockEntryInstr*>& postorder_;
+
+ // Live-out sets for each block. They contain indices of variables
+ // that are live out from this block: that is values that were either
+ // defined in this block or live into it and that are used in some
+ // successor block.
+ GrowableArray<BitVector*> live_out_;
+
+ // Kill sets for each block. They contain indices of variables that
+ // are defined by this block.
+ GrowableArray<BitVector*> kill_;
+
+ // Live-in sets for each block. They contain indices of variables
+ // that are used by this block or its successors.
+ GrowableArray<BitVector*> live_in_;
+};
+
} // namespace dart
#endif // VM_FLOW_GRAPH_H_
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 3b89eba..a347c8f 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -66,9 +66,7 @@
value_representations_(flow_graph.max_virtual_register_number()),
block_order_(flow_graph.reverse_postorder()),
postorder_(flow_graph.postorder()),
- live_out_(block_order_.length()),
- kill_(block_order_.length()),
- live_in_(block_order_.length()),
+ liveness_(flow_graph),
vreg_count_(flow_graph.max_virtual_register_number()),
live_ranges_(flow_graph.max_virtual_register_number()),
cpu_regs_(),
@@ -116,7 +114,7 @@
}
-void FlowGraphAllocator::ComputeInitialSets() {
+void SSALivenessAnalysis::ComputeInitialSets() {
const intptr_t block_count = postorder_.length();
for (intptr_t i = 0; i < block_count; i++) {
BlockEntryInstr* block = postorder_[i];
@@ -189,11 +187,10 @@
}
// Process initial definitions, ie, constants and incoming parameters.
- GraphEntryInstr* graph_entry = flow_graph_.graph_entry();
- for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
- intptr_t vreg = (*graph_entry->initial_definitions())[i]->ssa_temp_index();
- kill_[graph_entry->postorder_number()]->Add(vreg);
- live_in_[graph_entry->postorder_number()]->Remove(vreg);
+ for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); i++) {
+ intptr_t vreg = (*graph_entry_->initial_definitions())[i]->ssa_temp_index();
+ kill_[graph_entry_->postorder_number()]->Add(vreg);
+ live_in_[graph_entry_->postorder_number()]->Remove(vreg);
}
// Update initial live_in sets to match live_out sets. Has to be
@@ -204,93 +201,6 @@
}
-bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) {
- BitVector* live_out = live_out_[instr.postorder_number()];
- bool changed = false;
- Instruction* last = instr.last_instruction();
- ASSERT(last != NULL);
- for (intptr_t i = 0; i < last->SuccessorCount(); i++) {
- BlockEntryInstr* succ = last->SuccessorAt(i);
- ASSERT(succ != NULL);
- if (live_out->AddAll(live_in_[succ->postorder_number()])) {
- changed = true;
- }
- }
- return changed;
-}
-
-
-bool FlowGraphAllocator::UpdateLiveIn(const BlockEntryInstr& instr) {
- BitVector* live_out = live_out_[instr.postorder_number()];
- BitVector* kill = kill_[instr.postorder_number()];
- BitVector* live_in = live_in_[instr.postorder_number()];
- return live_in->KillAndAdd(kill, live_out);
-}
-
-
-void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() {
- const intptr_t block_count = postorder_.length();
- bool changed;
- do {
- changed = false;
-
- for (intptr_t i = 0; i < block_count; i++) {
- const BlockEntryInstr& block = *postorder_[i];
-
- // Live-in set depends only on kill set which does not
- // change in this loop and live-out set. If live-out
- // set does not change there is no need to recompute
- // live-in set.
- if (UpdateLiveOut(block) && UpdateLiveIn(block)) {
- changed = true;
- }
- }
- } while (changed);
-}
-
-
-void FlowGraphAllocator::AnalyzeLiveness() {
- const intptr_t block_count = postorder_.length();
- for (intptr_t i = 0; i < block_count; i++) {
- live_out_.Add(new BitVector(vreg_count_));
- kill_.Add(new BitVector(vreg_count_));
- live_in_.Add(new BitVector(vreg_count_));
- }
-
- ComputeInitialSets();
- ComputeLiveInAndLiveOutSets();
-}
-
-
-static void PrintBitVector(const char* tag, BitVector* v) {
- OS::Print("%s:", tag);
- for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
- OS::Print(" %"Pd"", it.Current());
- }
- OS::Print("\n");
-}
-
-
-void FlowGraphAllocator::DumpLiveness() {
- const intptr_t block_count = postorder_.length();
- for (intptr_t i = 0; i < block_count; i++) {
- BlockEntryInstr* block = postorder_[i];
- OS::Print("block @%"Pd" -> ", block->block_id());
-
- Instruction* last = block->last_instruction();
- for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
- BlockEntryInstr* succ = last->SuccessorAt(j);
- OS::Print(" @%"Pd"", succ->block_id());
- }
- OS::Print("\n");
-
- PrintBitVector(" live out", live_out_[i]);
- PrintBitVector(" kill", kill_[i]);
- PrintBitVector(" live in", live_in_[i]);
- }
-}
-
-
void LiveRange::AddUse(intptr_t pos, Location* location_slot) {
ASSERT(location_slot != NULL);
ASSERT((first_use_interval_->start_ <= pos) &&
@@ -535,7 +445,9 @@
// For every SSA value that is live out of this block, create an interval
// that covers the whole block. It will be shortened if we encounter a
// definition of this value in this block.
- for (BitVector::Iterator it(live_out_[i]); !it.Done(); it.Advance()) {
+ for (BitVector::Iterator it(liveness_.GetLiveOutSetAt(i));
+ !it.Done();
+ it.Advance()) {
LiveRange* range = GetLiveRange(it.Current());
range->AddUseInterval(block->start_pos(), block->end_pos());
}
@@ -548,7 +460,7 @@
// All values flowing into the loop header are live at the back-edge and
// can interfere with phi moves.
current_interference_set->AddAll(
- live_in_[loop_header->entry()->postorder_number()]);
+ liveness_.GetLiveInSet(loop_header->entry()));
loop_header->set_backedge_interference(
current_interference_set);
}
@@ -571,7 +483,9 @@
// Check if any values live into the loop can be spilled for free.
if (block_info->is_loop_header()) {
current_interference_set = NULL;
- for (BitVector::Iterator it(live_in_[i]); !it.Done(); it.Advance()) {
+ for (BitVector::Iterator it(liveness_.GetLiveInSetAt(i));
+ !it.Done();
+ it.Advance()) {
LiveRange* range = GetLiveRange(it.Current());
if (HasOnlyUnconstrainedUsesInLoop(range, block_info)) {
range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id());
@@ -2453,7 +2367,7 @@
// Resolve non-linear control flow across branches.
for (intptr_t i = 1; i < block_order_.length(); i++) {
BlockEntryInstr* block = block_order_[i];
- BitVector* live = live_in_[block->postorder_number()];
+ BitVector* live = liveness_.GetLiveInSet(block);
for (BitVector::Iterator it(live); !it.Done(); it.Advance()) {
LiveRange* range = GetLiveRange(it.Current());
for (intptr_t j = 0; j < block->PredecessorCount(); j++) {
@@ -2520,7 +2434,7 @@
EliminateEnvironments();
- AnalyzeLiveness();
+ liveness_.Analyze();
NumberInstructions();
@@ -2529,7 +2443,7 @@
BuildLiveRanges();
if (FLAG_print_ssa_liveness) {
- DumpLiveness();
+ liveness_.Dump();
}
if (FLAG_print_ssa_liveranges) {
diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
index ab60b82..8919e38 100644
--- a/runtime/vm/flow_graph_allocator.h
+++ b/runtime/vm/flow_graph_allocator.h
@@ -5,6 +5,7 @@
#ifndef VM_FLOW_GRAPH_ALLOCATOR_H_
#define VM_FLOW_GRAPH_ALLOCATOR_H_
+#include "vm/flow_graph.h"
#include "vm/growable_array.h"
#include "vm/intermediate_language.h"
@@ -35,6 +36,21 @@
};
+class SSALivenessAnalysis : public LivenessAnalysis {
+ public:
+ explicit SSALivenessAnalysis(const FlowGraph& flow_graph)
+ : LivenessAnalysis(flow_graph.max_virtual_register_number(),
+ flow_graph.postorder()),
+ graph_entry_(flow_graph.graph_entry()) { }
+
+ private:
+ // Compute initial values for live-out, kill and live-in sets.
+ virtual void ComputeInitialSets();
+
+ GraphEntryInstr* graph_entry_;
+};
+
+
class FlowGraphAllocator : public ValueObject {
public:
// Number of stack slots needed for a fpu register spill slot.
@@ -44,9 +60,6 @@
void AllocateRegisters();
- // Build live-in and live-out sets for each block.
- void AnalyzeLiveness();
-
// Map a virtual register number to its live range.
LiveRange* GetLiveRange(intptr_t vreg);
@@ -56,27 +69,6 @@
// Eliminate unnecessary environments from the IL.
void EliminateEnvironments();
- // Compute initial values for live-out, kill and live-in sets.
- void ComputeInitialSets();
-
- // Update live-out set for the given block: live-out should contain
- // all values that are live-in for block's successors.
- // Returns true if live-out set was changed.
- bool UpdateLiveOut(const BlockEntryInstr& instr);
-
- // Update live-in set for the given block: live-in should contain
- // all values that are live-out from the block and are not defined
- // by this block.
- // Returns true if live-in set was changed.
- bool UpdateLiveIn(const BlockEntryInstr& instr);
-
- // Perform fix-point iteration updating live-out and live-in sets
- // for blocks until they stop changing.
- void ComputeLiveInAndLiveOutSets();
-
- // Print results of liveness analysis.
- void DumpLiveness();
-
// Visit blocks in the code generation order (reverse post order) and
// linearly assign consequent lifetime positions to every instruction.
// We assign position as follows:
@@ -249,19 +241,7 @@
// Mapping between lifetime positions and blocks containing them.
GrowableArray<BlockInfo*> block_info_;
- // Live-out sets for each block. They contain indices of SSA values
- // that are live out from this block: that is values that were either
- // defined in this block or live into it and that are used in some
- // successor block.
- GrowableArray<BitVector*> live_out_;
-
- // Kill sets for each block. They contain indices of SSA values that
- // are defined by this block.
- GrowableArray<BitVector*> kill_;
-
- // Live-in sets for each block. They contain indices of SSA values
- // that are used by this block or its successors.
- GrowableArray<BitVector*> live_in_;
+ SSALivenessAnalysis liveness_;
// Number of virtual registers. Currently equal to the number of
// SSA values.
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 8a54d5b..75cf6b3 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -19,6 +19,7 @@
namespace dart {
+DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, print_ast);
DECLARE_FLAG(bool, print_scopes);
@@ -42,7 +43,19 @@
void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
intptr_t stub_ix) {
- UNIMPLEMENTED();
+ // Calls do not need stubs, they share a deoptimization trampoline.
+ ASSERT(reason() != kDeoptAtCall);
+ Assembler* assem = compiler->assembler();
+#define __ assem->
+ __ Comment("Deopt stub for id %"Pd"", deopt_id());
+ __ Bind(entry_label());
+ if (FLAG_trap_on_deoptimization) __ break_(0);
+
+ ASSERT(deoptimization_env() != NULL);
+
+ __ BranchLink(&StubCode::DeoptimizeLabel());
+ set_pc_offset(assem->CodeSize());
+#undef __
}
@@ -1154,57 +1167,195 @@
}
+#undef __
+#define __ compiler_->assembler()->
+
+
void ParallelMoveResolver::EmitMove(int index) {
- UNIMPLEMENTED();
+ MoveOperands* move = moves_[index];
+ const Location source = move->src();
+ const Location destination = move->dest();
+
+ if (source.IsRegister()) {
+ if (destination.IsRegister()) {
+ __ mov(destination.reg(), source.reg());
+ } else {
+ ASSERT(destination.IsStackSlot());
+ __ sw(source.reg(), destination.ToStackSlotAddress());
+ }
+ } else if (source.IsStackSlot()) {
+ if (destination.IsRegister()) {
+ __ lw(destination.reg(), source.ToStackSlotAddress());
+ } else {
+ ASSERT(destination.IsStackSlot());
+ MoveMemoryToMemory(destination.ToStackSlotAddress(),
+ source.ToStackSlotAddress());
+ }
+ } else if (source.IsFpuRegister()) {
+ if (destination.IsFpuRegister()) {
+ __ movd(destination.fpu_reg(), source.fpu_reg());
+ } else {
+ if (destination.IsDoubleStackSlot()) {
+ __ sdc1(source.fpu_reg(), destination.ToStackSlotAddress());
+ } else {
+ ASSERT(destination.IsQuadStackSlot());
+ UNIMPLEMENTED();
+ }
+ }
+ } else if (source.IsDoubleStackSlot()) {
+ if (destination.IsFpuRegister()) {
+ __ ldc1(destination.fpu_reg(), source.ToStackSlotAddress());
+ } else {
+ ASSERT(destination.IsDoubleStackSlot());
+ __ ldc1(FpuTMP, source.ToStackSlotAddress());
+ __ sdc1(FpuTMP, destination.ToStackSlotAddress());
+ }
+ } else if (source.IsQuadStackSlot()) {
+ UNIMPLEMENTED();
+ } else {
+ ASSERT(source.IsConstant());
+ if (destination.IsRegister()) {
+ const Object& constant = source.constant();
+ __ LoadObject(destination.reg(), constant);
+ } else {
+ ASSERT(destination.IsStackSlot());
+ StoreObject(destination.ToStackSlotAddress(), source.constant());
+ }
+ }
+
+ move->Eliminate();
}
void ParallelMoveResolver::EmitSwap(int index) {
- UNIMPLEMENTED();
+ MoveOperands* move = moves_[index];
+ const Location source = move->src();
+ const Location destination = move->dest();
+
+ if (source.IsRegister() && destination.IsRegister()) {
+ ASSERT(source.reg() != TMP1);
+ ASSERT(destination.reg() != TMP1);
+ __ mov(TMP1, source.reg());
+ __ mov(source.reg(), destination.reg());
+ __ mov(destination.reg(), TMP1);
+ } else if (source.IsRegister() && destination.IsStackSlot()) {
+ Exchange(source.reg(), destination.ToStackSlotAddress());
+ } else if (source.IsStackSlot() && destination.IsRegister()) {
+ Exchange(destination.reg(), source.ToStackSlotAddress());
+ } else if (source.IsStackSlot() && destination.IsStackSlot()) {
+ Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
+ } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
+ __ movd(FpuTMP, source.fpu_reg());
+ __ movd(source.fpu_reg(), destination.fpu_reg());
+ __ movd(destination.fpu_reg(), FpuTMP);
+ } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
+ ASSERT(destination.IsDoubleStackSlot() ||
+ destination.IsQuadStackSlot() ||
+ source.IsDoubleStackSlot() ||
+ source.IsQuadStackSlot());
+ bool double_width = destination.IsDoubleStackSlot() ||
+ source.IsDoubleStackSlot();
+ FRegister reg = source.IsFpuRegister() ? source.fpu_reg()
+ : destination.fpu_reg();
+ const Address& slot_address = source.IsFpuRegister()
+ ? destination.ToStackSlotAddress()
+ : source.ToStackSlotAddress();
+
+ if (double_width) {
+ __ ldc1(FpuTMP, slot_address);
+ __ sdc1(reg, slot_address);
+ __ movd(reg, FpuTMP);
+ } else {
+ UNIMPLEMENTED();
+ }
+ } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
+ const Address& source_slot_address = source.ToStackSlotAddress();
+ const Address& destination_slot_address = destination.ToStackSlotAddress();
+
+ ScratchFpuRegisterScope ensure_scratch(this, FpuTMP);
+ __ ldc1(FpuTMP, source_slot_address);
+ __ ldc1(ensure_scratch.reg(), destination_slot_address);
+ __ sdc1(FpuTMP, destination_slot_address);
+ __ sdc1(ensure_scratch.reg(), source_slot_address);
+ } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
+ UNIMPLEMENTED();
+ } else {
+ UNREACHABLE();
+ }
+
+ // The swap of source and destination has executed a move from source to
+ // destination.
+ move->Eliminate();
+
+ // Any unperformed (including pending) move with a source of either
+ // this move's source or destination needs to have their source
+ // changed to reflect the state of affairs after the swap.
+ for (int i = 0; i < moves_.length(); ++i) {
+ const MoveOperands& other_move = *moves_[i];
+ if (other_move.Blocks(source)) {
+ moves_[i]->set_src(destination);
+ } else if (other_move.Blocks(destination)) {
+ moves_[i]->set_src(source);
+ }
+ }
}
void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst,
const Address& src) {
- UNIMPLEMENTED();
+ __ lw(TMP1, src);
+ __ sw(TMP1, dst);
}
void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
- UNIMPLEMENTED();
+ __ LoadObject(TMP1, obj);
+ __ sw(TMP1, dst);
}
void ParallelMoveResolver::Exchange(Register reg, const Address& mem) {
- UNIMPLEMENTED();
+ ASSERT(reg != TMP1);
+ __ mov(TMP1, reg);
+ __ lw(reg, mem);
+ __ sw(TMP1, mem);
}
void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
- UNIMPLEMENTED();
+ ScratchRegisterScope ensure_scratch(this, TMP1);
+ __ lw(ensure_scratch.reg(), mem1);
+ __ lw(TMP1, mem2);
+ __ sw(ensure_scratch.reg(), mem2);
+ __ sw(TMP1, mem1);
}
void ParallelMoveResolver::SpillScratch(Register reg) {
- UNIMPLEMENTED();
+ __ Push(reg);
}
void ParallelMoveResolver::RestoreScratch(Register reg) {
- UNIMPLEMENTED();
+ __ Pop(reg);
}
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
- UNIMPLEMENTED();
+ __ AddImmediate(SP, -kDoubleSize);
+ __ sdc1(reg, Address(SP));
}
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
- UNIMPLEMENTED();
+ __ ldc1(reg, Address(SP));
+ __ AddImmediate(SP, kDoubleSize);
}
+#undef __
+
+
} // namespace dart
#endif // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 404caab..8833ac3 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -3371,7 +3371,7 @@
for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
BlockEntryInstr* pred = block->PredecessorAt(i);
BitVector* pred_out = out_[pred->preorder_number()];
- temp->Intersect(*pred_out);
+ temp->Intersect(pred_out);
}
}
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 71acde1..0c64c34 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -459,27 +459,6 @@
}
-// ==== Recording assigned variables.
-void Definition::RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count) {
- // Nothing to do for the base class.
-}
-
-
-void StoreLocalInstr::RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count) {
- if (!local().is_captured()) {
- assigned_vars->Add(local().BitIndexIn(fixed_parameter_count));
- }
-}
-
-
-void Instruction::RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count) {
- // Nothing to do for the base class.
-}
-
-
void Value::AddToList(Value* value, Value** list) {
Value* next = *list;
*list = value;
@@ -682,7 +661,6 @@
GrowableArray<BlockEntryInstr*>* preorder,
GrowableArray<BlockEntryInstr*>* postorder,
GrowableArray<intptr_t>* parent,
- GrowableArray<BitVector*>* assigned_vars,
intptr_t variable_count,
intptr_t fixed_parameter_count) {
// If this block has a predecessor (i.e., is not the graph entry) we can
@@ -711,16 +689,12 @@
parent->Add(parent_number);
// 4. Assign the preorder number and add the block entry to the list.
- // Allocate an empty set of assigned variables for the block.
set_preorder_number(preorder->length());
preorder->Add(this);
- BitVector* vars =
- (variable_count == 0) ? NULL : new BitVector(variable_count);
- assigned_vars->Add(vars);
- // The preorder, parent, and assigned_vars arrays are all indexed by
+
+ // The preorder and parent arrays are indexed by
// preorder block number, so they should stay in lockstep.
ASSERT(preorder->length() == parent->length());
- ASSERT(preorder->length() == assigned_vars->length());
// 5. Iterate straight-line successors to record assigned variables and
// find the last instruction in the block. The graph entry block consists
@@ -729,18 +703,18 @@
Instruction* last = this;
for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
last = it.Current();
- if (vars != NULL) {
- last->RecordAssignedVars(vars, fixed_parameter_count);
- }
}
set_last_instruction(last);
// Visit the block's successors in reverse so that they appear forwards
// the reverse postorder block ordering.
for (intptr_t i = last->SuccessorCount() - 1; i >= 0; --i) {
- last->SuccessorAt(i)->DiscoverBlocks(this, preorder, postorder,
- parent, assigned_vars,
- variable_count, fixed_parameter_count);
+ last->SuccessorAt(i)->DiscoverBlocks(this,
+ preorder,
+ postorder,
+ parent,
+ variable_count,
+ fixed_parameter_count);
}
// 6. Assign postorder number and add the block entry to the list.
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index fd21acf..1b00413 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -623,11 +623,6 @@
void Goto(JoinEntryInstr* entry);
- // Mutate assigned_vars to add the local variable index for all
- // frame-allocated locals assigned to by the instruction.
- virtual void RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count);
-
virtual const char* DebugName() const = 0;
// Printing support.
@@ -991,7 +986,6 @@
GrowableArray<BlockEntryInstr*>* preorder,
GrowableArray<BlockEntryInstr*>* postorder,
GrowableArray<intptr_t>* parent,
- GrowableArray<BitVector*>* assigned_vars,
intptr_t variable_count,
intptr_t fixed_parameter_count);
@@ -1420,9 +1414,6 @@
// NULL iterator.
void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator);
- virtual void RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count);
-
// Printing support. These functions are sometimes overridden for custom
// formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
virtual void PrintTo(BufferFormatter* f) const;
@@ -2858,7 +2849,8 @@
class LoadLocalInstr : public TemplateDefinition<0> {
public:
- explicit LoadLocalInstr(const LocalVariable& local) : local_(local) { }
+ explicit LoadLocalInstr(const LocalVariable& local)
+ : local_(local), is_last_(false) { }
DECLARE_INSTRUCTION(LoadLocal)
virtual CompileType ComputeType() const;
@@ -2874,8 +2866,12 @@
return false;
}
+ void mark_last() { is_last_ = true; }
+ bool is_last() const { return is_last_; }
+
private:
const LocalVariable& local_;
+ bool is_last_;
DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
};
@@ -2883,7 +2879,8 @@
class StoreLocalInstr : public TemplateDefinition<1> {
public:
- StoreLocalInstr(const LocalVariable& local, Value* value) : local_(local) {
+ StoreLocalInstr(const LocalVariable& local, Value* value)
+ : local_(local), is_dead_(false), is_last_(false) {
SetInputAt(0, value);
}
@@ -2893,9 +2890,6 @@
const LocalVariable& local() const { return local_; }
Value* value() const { return inputs_[0]; }
- virtual void RecordAssignedVars(BitVector* assigned_vars,
- intptr_t fixed_parameter_count);
-
virtual void PrintOperandsTo(BufferFormatter* f) const;
virtual bool CanDeoptimize() const { return false; }
@@ -2905,8 +2899,16 @@
return false;
}
+ void mark_dead() { is_dead_ = true; }
+ bool is_dead() const { return is_dead_; }
+
+ void mark_last() { is_last_ = true; }
+ bool is_last() const { return is_last_; }
+
private:
const LocalVariable& local_;
+ bool is_dead_;
+ bool is_last_;
DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
};
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index b6ec1b0..9eb5cdc 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -405,6 +405,25 @@
}
+static void LoadValueCid(FlowGraphCompiler* compiler,
+ Register value_cid_reg,
+ Register value_reg,
+ Label* value_is_smi = NULL) {
+ Label done;
+ if (value_is_smi == NULL) {
+ __ LoadImmediate(value_cid_reg, kSmiCid);
+ }
+ __ andi(TMP1, value_reg, Immediate(kSmiTagMask));
+ if (value_is_smi == NULL) {
+ __ beq(TMP1, ZR, &done);
+ } else {
+ __ beq(TMP1, ZR, value_is_smi);
+ }
+ __ LoadClassId(value_cid_reg, value_reg);
+ __ Bind(&done);
+}
+
+
// Emit code when ICData's targets are all Object == (which is ===).
static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
const ICData& ic_data,
@@ -430,11 +449,62 @@
}
+static Condition TokenKindToSmiCondition(Token::Kind kind) {
+ switch (kind) {
+ case Token::kEQ: return EQ;
+ case Token::kNE: return NE;
+ case Token::kLT: return LT;
+ case Token::kGT: return GT;
+ case Token::kLTE: return LE;
+ case Token::kGTE: return GE;
+ default:
+ UNREACHABLE();
+ return VS;
+ }
+}
+
+
static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
BranchInstr* branch) {
- UNIMPLEMENTED();
+ Location left = locs.in(0);
+ Location right = locs.in(1);
+ ASSERT(!left.IsConstant() || !right.IsConstant());
+
+ Condition true_condition = TokenKindToSmiCondition(kind);
+
+ if (left.IsConstant()) {
+ __ CompareObject(CMPRES, right.reg(), left.constant());
+ true_condition = FlowGraphCompiler::FlipCondition(true_condition);
+ } else if (right.IsConstant()) {
+ __ CompareObject(CMPRES, left.reg(), right.constant());
+ } else {
+ __ subu(CMPRES, left.reg(), right.reg());
+ }
+
+ if (branch != NULL) {
+ branch->EmitBranchOnCondition(compiler, true_condition);
+ } else {
+ Register result = locs.out().reg();
+ Label done, is_true;
+ switch (true_condition) {
+ case EQ: __ beq(CMPRES, ZR, &is_true); break;
+ case NE: __ bne(CMPRES, ZR, &is_true); break;
+ case GT: __ bgtz(CMPRES, &is_true); break;
+ case GE: __ bgez(CMPRES, &is_true); break;
+ case LT: __ bltz(CMPRES, &is_true); break;
+ case LE: __ blez(CMPRES, &is_true); break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ __ LoadObject(result, Bool::False());
+ __ b(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, Bool::True());
+ __ Bind(&done);
+ }
}
@@ -446,6 +516,14 @@
}
+static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchInstr* branch) {
+ UNIMPLEMENTED();
+}
+
+
static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
@@ -543,19 +621,135 @@
LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 2;
+ const intptr_t kNumTemps = 0;
+ if (operands_class_id() == kMintCid) {
+ const intptr_t kNumTemps = 2;
+ LocationSummary* locs =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ locs->set_in(0, Location::RequiresFpuRegister());
+ locs->set_in(1, Location::RequiresFpuRegister());
+ locs->set_temp(0, Location::RequiresRegister());
+ locs->set_temp(1, Location::RequiresRegister());
+ locs->set_out(Location::RequiresRegister());
+ return locs;
+ }
+ if (operands_class_id() == kDoubleCid) {
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresFpuRegister());
+ summary->set_in(1, Location::RequiresFpuRegister());
+ summary->set_out(Location::RequiresRegister());
+ return summary;
+ } else if (operands_class_id() == kSmiCid) {
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RegisterOrConstant(left()));
+ // Only one input can be a constant operand. The case of two constant
+ // operands should be handled by constant propagation.
+ summary->set_in(1, summary->in(0).IsConstant()
+ ? Location::RequiresRegister()
+ : Location::RegisterOrConstant(right()));
+ summary->set_out(Location::RequiresRegister());
+ return summary;
+ }
+ LocationSummary* locs =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+ // Pick arbitrary fixed input registers because this is a call.
+ locs->set_in(0, Location::RegisterLocation(A0));
+ locs->set_in(1, Location::RegisterLocation(A1));
+ locs->set_out(Location::RegisterLocation(V0));
+ return locs;
}
void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ if (operands_class_id() == kSmiCid) {
+ EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
+ return;
+ }
+ if (operands_class_id() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
+ return;
+ }
+ if (operands_class_id() == kDoubleCid) {
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
+ return;
+ }
+
+ // Push arguments for the call.
+ // TODO(fschneider): Split this instruction into different types to avoid
+ // explicitly pushing arguments to the call here.
+ Register left = locs()->in(0).reg();
+ Register right = locs()->in(1).reg();
+ __ Push(left);
+ __ Push(right);
+ if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
+ // Load class into A2.
+ const intptr_t kNumArguments = 2;
+ LoadValueCid(compiler, A2, left);
+ compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
+ A2, // Class id register.
+ kNumArguments,
+ Array::Handle(), // No named arguments.
+ deopt, // Deoptimize target.
+ deopt_id(),
+ token_pos(),
+ locs());
+ return;
+ }
+ const String& function_name =
+ String::ZoneHandle(Symbols::New(Token::Str(kind())));
+ if (!compiler->is_optimizing()) {
+ compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+ deopt_id(),
+ token_pos());
+ }
+ const intptr_t kNumArguments = 2;
+ const intptr_t kNumArgsChecked = 2; // Type-feedback.
+ ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
+ if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
+ ASSERT(!ic_data()->IsNull());
+ if (ic_data()->NumberOfChecks() == 0) {
+ // IC call for reoptimization populates original ICData.
+ relational_ic_data = ic_data()->raw();
+ } else {
+ // Megamorphic call.
+ relational_ic_data = ic_data()->AsUnaryClassChecks();
+ }
+ } else {
+ relational_ic_data = ICData::New(compiler->parsed_function().function(),
+ function_name,
+ deopt_id(),
+ kNumArgsChecked);
+ }
+ compiler->GenerateInstanceCall(deopt_id(),
+ token_pos(),
+ kNumArguments,
+ Array::ZoneHandle(), // No optional arguments.
+ locs(),
+ relational_ic_data);
}
void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
- UNIMPLEMENTED();
+ if (operands_class_id() == kSmiCid) {
+ EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
+ return;
+ }
+ if (operands_class_id() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
+ return;
+ }
+ if (operands_class_id() == kDoubleCid) {
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
+ return;
+ }
+ EmitNativeCode(compiler);
+ __ CompareObject(CMPRES, V0, Bool::True());
+ branch->EmitBranchOnCondition(compiler, EQ);
}
@@ -880,13 +1074,196 @@
LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 2;
+ if (op_kind() == Token::kTRUNCDIV) {
+ UNIMPLEMENTED();
+ return NULL;
+ } else {
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+ // We make use of 3-operand instructions by not requiring result register
+ // to be identical to first input register as on Intel.
+ summary->set_out(Location::RequiresRegister());
+ return summary;
+ }
}
void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ if (op_kind() == Token::kSHL) {
+ UNIMPLEMENTED();
+ return;
+ }
+
+ ASSERT(!is_truncating());
+ Register left = locs()->in(0).reg();
+ Register result = locs()->out().reg();
+ Label* deopt = NULL;
+ if (CanDeoptimize()) {
+ deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
+ }
+
+ if (locs()->in(1).IsConstant()) {
+ const Object& constant = locs()->in(1).constant();
+ ASSERT(constant.IsSmi());
+ int32_t imm = reinterpret_cast<int32_t>(constant.raw());
+ switch (op_kind()) {
+ case Token::kSUB: {
+ if (deopt == NULL) {
+ __ AddImmediate(result, left, -imm);
+ } else {
+ __ SubImmediateDetectOverflow(result, left, imm, CMPRES);
+ __ bltz(CMPRES, deopt);
+ }
+ break;
+ }
+ case Token::kADD: {
+ if (deopt == NULL) {
+ __ AddImmediate(result, left, imm);
+ } else {
+ __ AddImmediateDetectOverflow(result, left, imm, CMPRES);
+ __ bltz(CMPRES, deopt);
+ }
+ break;
+ }
+ case Token::kMUL: {
+ // Keep left value tagged and untag right value.
+ const intptr_t value = Smi::Cast(constant).Value();
+ if (value == 2) {
+ __ sll(result, left, 1);
+ } else {
+ __ LoadImmediate(TMP1, value);
+ __ mult(left, TMP1);
+ __ mflo(result);
+ }
+ if (deopt != NULL) {
+ UNIMPLEMENTED();
+ }
+ break;
+ }
+ case Token::kTRUNCDIV: {
+ UNIMPLEMENTED();
+ break;
+ }
+ case Token::kBIT_AND: {
+ // No overflow check.
+ if (Utils::IsUint(kImmBits, imm)) {
+ __ andi(result, left, Immediate(imm));
+ } else {
+ __ LoadImmediate(TMP1, imm);
+ __ and_(result, left, TMP1);
+ }
+ break;
+ }
+ case Token::kBIT_OR: {
+ // No overflow check.
+ if (Utils::IsUint(kImmBits, imm)) {
+ __ ori(result, left, Immediate(imm));
+ } else {
+ __ LoadImmediate(TMP1, imm);
+ __ or_(result, left, TMP1);
+ }
+ break;
+ }
+ case Token::kBIT_XOR: {
+ // No overflow check.
+ if (Utils::IsUint(kImmBits, imm)) {
+ __ xori(result, left, Immediate(imm));
+ } else {
+ __ LoadImmediate(TMP1, imm);
+ __ xor_(result, left, TMP1);
+ }
+ break;
+ }
+ case Token::kSHR: {
+ UNIMPLEMENTED();
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ Register right = locs()->in(1).reg();
+ switch (op_kind()) {
+ case Token::kADD: {
+ if (deopt == NULL) {
+ __ addu(result, left, right);
+ } else {
+ __ AdduDetectOverflow(result, left, right, CMPRES);
+ __ bltz(CMPRES, deopt);
+ }
+ break;
+ }
+ case Token::kSUB: {
+ if (deopt == NULL) {
+ __ subu(result, left, right);
+ } else {
+ __ SubuDetectOverflow(result, left, right, CMPRES);
+ __ bltz(CMPRES, deopt);
+ }
+ break;
+ }
+ case Token::kMUL: {
+ __ SmiUntag(left);
+ __ mult(left, right);
+ __ mflo(result);
+ if (deopt != NULL) {
+ UNIMPLEMENTED();
+ }
+ break;
+ }
+ case Token::kBIT_AND: {
+ // No overflow check.
+ __ and_(result, left, right);
+ break;
+ }
+ case Token::kBIT_OR: {
+ // No overflow check.
+ __ or_(result, left, right);
+ break;
+ }
+ case Token::kBIT_XOR: {
+ // No overflow check.
+ __ xor_(result, left, right);
+ break;
+ }
+ case Token::kTRUNCDIV: {
+ UNIMPLEMENTED();
+ break;
+ }
+ case Token::kSHR: {
+ UNIMPLEMENTED();
+ break;
+ }
+ case Token::kDIV: {
+ // Dispatches to 'Double./'.
+ // TODO(srdjan): Implement as conversion to double and double division.
+ UNREACHABLE();
+ break;
+ }
+ case Token::kMOD: {
+ // TODO(srdjan): Implement.
+ UNREACHABLE();
+ break;
+ }
+ case Token::kOR:
+ case Token::kAND: {
+ // Flow graph builder has dissected this operation to guarantee correct
+ // behavior (short-circuit evaluation).
+ UNREACHABLE();
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
}
@@ -1034,13 +1411,44 @@
LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ return MakeCallSummary();
}
void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
+ kDeoptPolymorphicInstanceCallTestFail);
+ if (ic_data().NumberOfChecks() == 0) {
+ __ b(deopt);
+ return;
+ }
+ ASSERT(ic_data().num_args_tested() == 1);
+ if (!with_checks()) {
+ ASSERT(ic_data().HasOneTarget());
+ const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
+ compiler->GenerateStaticCall(instance_call()->deopt_id(),
+ instance_call()->token_pos(),
+ target,
+ instance_call()->ArgumentCount(),
+ instance_call()->argument_names(),
+ locs());
+ return;
+ }
+
+ // Load receiver into R0.
+ __ lw(T0, Address(SP, (instance_call()->ArgumentCount() - 1) * kWordSize));
+
+ LoadValueCid(compiler, T2, T0,
+ (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt);
+
+ compiler->EmitTestAndCall(ic_data(),
+ T2, // Class id register.
+ instance_call()->ArgumentCount(),
+ instance_call()->argument_names(),
+ deopt,
+ instance_call()->deopt_id(),
+ instance_call()->token_pos(),
+ locs());
}
@@ -1067,13 +1475,21 @@
LocationSummary* CheckSmiInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 1;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+ summary->set_in(0, Location::RequiresRegister());
+ return summary;
}
void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ Register value = locs()->in(0).reg();
+ Label* deopt = compiler->AddDeoptStub(deopt_id(),
+ kDeoptCheckSmi);
+ __ andi(TMP1, value, Immediate(kSmiTagMask));
+ __ bne(TMP1, ZR, deopt);
}
@@ -1196,6 +1612,10 @@
switch (condition) {
case EQ: return NE;
case NE: return EQ;
+ case LT: return GE;
+ case LE: return GT;
+ case GT: return LE;
+ case GE: return LT;
default:
OS::Print("Error: Condition not recognized: %d\n", condition);
UNIMPLEMENTED();
@@ -1219,21 +1639,33 @@
Condition true_condition) {
if (compiler->CanFallThroughTo(false_successor())) {
// If the next block is the false successor we will fall through to it.
- if (true_condition == EQ) {
- __ beq(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
- } else {
- ASSERT(true_condition == NE);
- __ bne(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
+ Label* label = compiler->GetJumpLabel(true_successor());
+ switch (true_condition) {
+ case EQ: __ beq(CMPRES, ZR, label); break;
+ case NE: __ bne(CMPRES, ZR, label); break;
+ case GT: __ bgtz(CMPRES, label); break;
+ case GE: __ bgez(CMPRES, label); break;
+ case LT: __ bltz(CMPRES, label); break;
+ case LE: __ blez(CMPRES, label); break;
+ default:
+ UNREACHABLE();
+ break;
}
} else {
// If the next block is the true successor we negate comparison and fall
// through to it.
Condition false_condition = NegateCondition(true_condition);
- if (false_condition == EQ) {
- __ beq(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
- } else {
- ASSERT(false_condition == NE);
- __ bne(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
+ Label* label = compiler->GetJumpLabel(false_successor());
+ switch (false_condition) {
+ case EQ: __ beq(CMPRES, ZR, label); break;
+ case NE: __ bne(CMPRES, ZR, label); break;
+ case GT: __ bgtz(CMPRES, label); break;
+ case GE: __ bgez(CMPRES, label); break;
+ case LT: __ bltz(CMPRES, label); break;
+ case LE: __ blez(CMPRES, label); break;
+ default:
+ UNREACHABLE();
+ break;
}
// Fall through or jump to the true successor.
if (!compiler->CanFallThroughTo(true_successor())) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8b7c816..c62f845 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -593,17 +593,26 @@
intptr_t leftover_size = original_size - used_size;
uword addr = RawObject::ToAddr(obj.raw()) + used_size;
- ASSERT(TypedData::InstanceSize(0) == Object::InstanceSize());
- // Update the leftover space as an TypedDataInt8Array object.
- RawTypedData* raw =
- reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
- uword tags = 0;
- tags = RawObject::SizeTag::update(leftover_size, tags);
- tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, tags);
- raw->ptr()->tags_ = tags;
- intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
- ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
- raw->ptr()->length_ = Smi::New(leftover_len);
+ if (leftover_size >= TypedData::InstanceSize(0)) {
+ // Update the leftover space as an TypedDataInt8Array object.
+ RawTypedData* raw =
+ reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
+ uword tags = 0;
+ tags = RawObject::SizeTag::update(leftover_size, tags);
+ tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, tags);
+ raw->ptr()->tags_ = tags;
+ intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
+ ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
+ raw->ptr()->length_ = Smi::New(leftover_len);
+ } else {
+ // Update the leftover space as a basic object.
+ ASSERT(leftover_size == Object::InstanceSize());
+ RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
+ uword tags = 0;
+ tags = RawObject::SizeTag::update(leftover_size, tags);
+ tags = RawObject::ClassIdTag::update(kInstanceCid, tags);
+ raw->ptr()->tags_ = tags;
+ }
}
}
@@ -1014,7 +1023,7 @@
INIT_LIBRARY(Async, async, true);
INIT_LIBRARY(Collection, collection, true);
- INIT_LIBRARY(CollectionDev, collection_dev, false);
+ INIT_LIBRARY(CollectionDev, collection_dev, true);
INIT_LIBRARY(Crypto, crypto, false);
INIT_LIBRARY(Isolate, isolate, true);
INIT_LIBRARY(Json, json, true);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a81aaa0..02c4831 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4140,7 +4140,8 @@
// All strings share the same maximum element count to keep things
// simple. We choose a value that will prevent integer overflow for
// 2 byte strings, since it is the worst case.
- static const intptr_t kSizeofRawString = sizeof(RawObject) + (2 * kWordSize);
+ static const intptr_t kSizeofRawString =
+ sizeof(RawInstance) + (2 * kWordSize);
static const intptr_t kMaxElements = kSmiMax / kTwoByteChar;
class CodePointIterator : public ValueObject {
@@ -4785,7 +4786,7 @@
static intptr_t InstanceSize(intptr_t len) {
// Ensure that variable length data is not adding to the object length.
- ASSERT(sizeof(RawArray) == (sizeof(RawObject) + (2 * kWordSize)));
+ ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize)));
ASSERT(0 <= len && len <= kMaxElements);
return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement));
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 09da9c6..b606a43 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -8796,9 +8796,18 @@
}
factory_type_args = factory_type_args.Canonicalize();
ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
- const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos);
- ArrayNode* list = new ArrayNode(TokenPos(), type, temp_local, element_list);
- factory_param->Add(list);
+ if (element_list.length() == 0) {
+ // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed.
+ Array& empty_array = Array::ZoneHandle(Object::empty_array().raw());
+ LiteralNode* empty_array_literal =
+ new LiteralNode(TokenPos(), empty_array);
+ factory_param->Add(empty_array_literal);
+ } else {
+ const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos);
+ ArrayNode* list =
+ new ArrayNode(TokenPos(), type, temp_local, element_list);
+ factory_param->Add(list);
+ }
return CreateConstructorCallNode(literal_pos,
factory_type_args,
factory_method,
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index 7405738..e144c8a 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1682,6 +1682,13 @@
}
break;
}
+ case XORI: {
+ // Format(instr, "xori 'rt, 'rs, 'immu");
+ int32_t rs_val = get_register(instr->RsField());
+ set_register(instr->RtField(), rs_val ^ instr->UImmField());
+ break;
+ break;
+ }
default: {
OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
instr->InstructionBits(), instr);
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 41c9461..6e0911b 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -91,12 +91,12 @@
case Dart_CObject::kString:
EXPECT_STREQ(first->value.as_string, second->value.as_string);
break;
- case Dart_CObject::kUint8Array:
- EXPECT_EQ(first->value.as_byte_array.length,
- second->value.as_byte_array.length);
- for (int i = 0; i < first->value.as_byte_array.length; i++) {
- EXPECT_EQ(first->value.as_byte_array.values[i],
- second->value.as_byte_array.values[i]);
+ case Dart_CObject::kTypedData:
+ EXPECT_EQ(first->value.as_typed_data.length,
+ second->value.as_typed_data.length);
+ for (int i = 0; i < first->value.as_typed_data.length; i++) {
+ EXPECT_EQ(first->value.as_typed_data.values[i],
+ second->value.as_typed_data.values[i]);
}
break;
case Dart_CObject::kArray:
@@ -612,30 +612,30 @@
// Write snapshot with object content.
uint8_t* buffer;
MessageWriter writer(&buffer, &zone_allocator);
- const int kByteArrayLength = 256;
- TypedData& byte_array = TypedData::Handle(
- TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
- for (int i = 0; i < kByteArrayLength; i++) {
- byte_array.SetUint8(i, i);
+ const int kTypedDataLength = 256;
+ TypedData& typed_data = TypedData::Handle(
+ TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
+ for (int i = 0; i < kTypedDataLength; i++) {
+ typed_data.SetUint8(i, i);
}
- writer.WriteMessage(byte_array);
+ writer.WriteMessage(typed_data);
intptr_t buffer_len = writer.BytesWritten();
// Read object back from the snapshot.
SnapshotReader reader(buffer, buffer_len,
Snapshot::kMessage, Isolate::Current());
- TypedData& serialized_byte_array = TypedData::Handle();
- serialized_byte_array ^= reader.ReadObject();
- EXPECT(serialized_byte_array.IsTypedData());
+ TypedData& serialized_typed_data = TypedData::Handle();
+ serialized_typed_data ^= reader.ReadObject();
+ EXPECT(serialized_typed_data.IsTypedData());
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
Dart_CObject* root = api_reader.ReadMessage();
- EXPECT_EQ(Dart_CObject::kUint8Array, root->type);
- EXPECT_EQ(kByteArrayLength, root->value.as_byte_array.length);
- for (int i = 0; i < kByteArrayLength; i++) {
- EXPECT(root->value.as_byte_array.values[i] == i);
+ EXPECT_EQ(Dart_CObject::kTypedData, root->type);
+ EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
+ for (int i = 0; i < kTypedDataLength; i++) {
+ EXPECT(root->value.as_typed_data.values[i] == i);
}
CheckEncodeDecodeMessage(root);
}
@@ -724,26 +724,27 @@
// Write snapshot with object content.
uint8_t* buffer;
MessageWriter writer(&buffer, &zone_allocator);
- const int kByteArrayLength = 0;
- TypedData& byte_array = TypedData::Handle(
- TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
- writer.WriteMessage(byte_array);
+ const int kTypedDataLength = 0;
+ TypedData& typed_data = TypedData::Handle(
+ TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
+ writer.WriteMessage(typed_data);
intptr_t buffer_len = writer.BytesWritten();
// Read object back from the snapshot.
SnapshotReader reader(buffer, buffer_len,
Snapshot::kMessage, Isolate::Current());
- TypedData& serialized_byte_array = TypedData::Handle();
- serialized_byte_array ^= reader.ReadObject();
- EXPECT(serialized_byte_array.IsTypedData());
+ TypedData& serialized_typed_data = TypedData::Handle();
+ serialized_typed_data ^= reader.ReadObject();
+ EXPECT(serialized_typed_data.IsTypedData());
// Read object back from the snapshot into a C structure.
ApiNativeScope scope;
ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
Dart_CObject* root = api_reader.ReadMessage();
- EXPECT_EQ(Dart_CObject::kUint8Array, root->type);
- EXPECT_EQ(kByteArrayLength, root->value.as_byte_array.length);
- EXPECT(root->value.as_byte_array.values == NULL);
+ EXPECT_EQ(Dart_CObject::kTypedData, root->type);
+ EXPECT_EQ(Dart_CObject::kUint8Array, root->value.as_typed_data.type);
+ EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
+ EXPECT(root->value.as_typed_data.values == NULL);
CheckEncodeDecodeMessage(root);
}
@@ -1908,8 +1909,9 @@
for (int i = 0; i < kArrayLength; i++) {
Dart_CObject* element = root->value.as_array.values[i];
EXPECT_EQ(root->value.as_array.values[0], element);
- EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
- EXPECT_EQ(256, element->value.as_byte_array.length);
+ EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+ EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+ EXPECT_EQ(256, element->value.as_typed_data.length);
}
}
{
@@ -1923,10 +1925,11 @@
for (int i = 0; i < kArrayLength; i++) {
Dart_CObject* element = root->value.as_array.values[i];
EXPECT_EQ(root->value.as_array.values[0], element);
- EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
- EXPECT_EQ(128, element->value.as_byte_array.length);
- EXPECT_EQ(1, element->value.as_byte_array.values[0]);
- EXPECT_EQ(0, element->value.as_byte_array.values[1]);
+ EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+ EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+ EXPECT_EQ(128, element->value.as_typed_data.length);
+ EXPECT_EQ(1, element->value.as_typed_data.values[0]);
+ EXPECT_EQ(0, element->value.as_typed_data.values[1]);
}
}
{
@@ -2110,8 +2113,9 @@
for (int i = 0; i < kArrayLength; i++) {
Dart_CObject* element = root->value.as_array.values[i];
EXPECT_EQ(root->value.as_array.values[0], element);
- EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
- EXPECT_EQ(256, element->value.as_byte_array.length);
+ EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+ EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+ EXPECT_EQ(256, element->value.as_typed_data.length);
}
}
{
@@ -2125,10 +2129,11 @@
for (int i = 0; i < kArrayLength; i++) {
Dart_CObject* element = root->value.as_array.values[i];
EXPECT_EQ(root->value.as_array.values[0], element);
- EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
- EXPECT_EQ(128, element->value.as_byte_array.length);
- EXPECT_EQ(1, element->value.as_byte_array.values[0]);
- EXPECT_EQ(0, element->value.as_byte_array.values[1]);
+ EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+ EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+ EXPECT_EQ(128, element->value.as_typed_data.length);
+ EXPECT_EQ(1, element->value.as_typed_data.values[0]);
+ EXPECT_EQ(0, element->value.as_typed_data.values[1]);
}
}
{
@@ -2170,6 +2175,109 @@
}
+static void CheckTypedData(Dart_CObject* object,
+ Dart_CObject::TypedDataType typed_data_type,
+ int len) {
+ EXPECT_EQ(Dart_CObject::kTypedData, object->type);
+ EXPECT_EQ(typed_data_type, object->value.as_typed_data.type);
+ EXPECT_EQ(len, object->value.as_typed_data.length);
+}
+
+UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) {
+ const int kArrayLength = 10;
+ static const char* kScriptChars =
+ "import 'dart:typeddata';\n"
+ "final int kArrayLength = 10;\n"
+ "getTypedDataList() {\n"
+ " var list = new List(kArrayLength);\n"
+ " list[0] = new Int8List(256);\n"
+ " list[1] = new Uint8List(256);\n"
+ " list[2] = new Int16List(256);\n"
+ " list[3] = new Uint16List(256);\n"
+ " return list;\n"
+ "}\n"
+ "getTypedDataViewList() {\n"
+ " var list = new List(kArrayLength);\n"
+ " list[0] = new Int8List.view(new Int8List(256));\n"
+ " list[1] = new Uint8List.view(new Uint8List(256));\n"
+ " list[2] = new Int16List.view(new Int16List(256));\n"
+ " list[3] = new Uint16List.view(new Uint16List(256));\n"
+ " list[4] = new Int8List.view(new Int16List(256));\n"
+ " list[5] = new Uint8List.view(new Uint16List(256));\n"
+ " list[6] = new Int16List.view(new Int8List(256));\n"
+ " list[7] = new Uint16List.view(new Uint8List(256));\n"
+ " return list;\n"
+ "}\n";
+
+ TestCase::CreateTestIsolate();
+ Isolate* isolate = Isolate::Current();
+ EXPECT(isolate != NULL);
+ Dart_EnterScope();
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ EXPECT_VALID(lib);
+
+ {
+ DARTSCOPE(isolate);
+ {
+ // Generate a list of Uint8Lists from Dart code.
+ ApiNativeScope scope;
+ Dart_CObject* root = GetDeserializedDartMessage(lib, "getTypedDataList");
+ EXPECT_NOTNULL(root);
+ EXPECT_EQ(Dart_CObject::kArray, root->type);
+ EXPECT_EQ(kArrayLength, root->value.as_array.length);
+ CheckTypedData(root->value.as_array.values[0],
+ Dart_CObject::kInt8Array,
+ 256);
+ CheckTypedData(root->value.as_array.values[1],
+ Dart_CObject::kUint8Array,
+ 256);
+ CheckTypedData(root->value.as_array.values[2],
+ Dart_CObject::kInt16Array,
+ 512);
+ CheckTypedData(root->value.as_array.values[3],
+ Dart_CObject::kUint16Array,
+ 512);
+ }
+ {
+ // Generate a list of Uint8List views from Dart code.
+ ApiNativeScope scope;
+ Dart_CObject* root =
+ GetDeserializedDartMessage(lib, "getTypedDataViewList");
+ EXPECT_NOTNULL(root);
+ EXPECT_EQ(Dart_CObject::kArray, root->type);
+ EXPECT_EQ(kArrayLength, root->value.as_array.length);
+ CheckTypedData(root->value.as_array.values[0],
+ Dart_CObject::kInt8Array,
+ 256);
+ CheckTypedData(root->value.as_array.values[1],
+ Dart_CObject::kUint8Array,
+ 256);
+ CheckTypedData(root->value.as_array.values[2],
+ Dart_CObject::kInt16Array,
+ 512);
+ CheckTypedData(root->value.as_array.values[3],
+ Dart_CObject::kUint16Array,
+ 512);
+ CheckTypedData(root->value.as_array.values[4],
+ Dart_CObject::kInt8Array,
+ 512);
+ CheckTypedData(root->value.as_array.values[5],
+ Dart_CObject::kUint8Array,
+ 512);
+ CheckTypedData(root->value.as_array.values[6],
+ Dart_CObject::kInt16Array,
+ 256);
+ CheckTypedData(root->value.as_array.values[7],
+ Dart_CObject::kUint16Array,
+ 256);
+ }
+ }
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+}
+
+
UNIT_TEST_CASE(PostCObject) {
// Create a native port for posting from C to Dart
TestIsolateScope __test_isolate__;
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index b39e01b..ecdf38e 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -257,7 +257,7 @@
"} "
"class StackFrame2Test {"
" StackFrame2Test() {}"
- " noSuchMethod(InvocationMirror im) {"
+ " noSuchMethod(Invocation im) {"
" /* We should have 8 general frames and 3 dart frames as follows:"
" * exit frame"
" * dart frame corresponding to StackFrame.frameCount"
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 1a48f6b..c99c981 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1345,7 +1345,7 @@
// Uses EAX, EBX, EDI as temporary registers.
void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
// The target function was not found, so invoke method
- // "dynamic noSuchMethod(InvocationMirror invocation)".
+ // "dynamic noSuchMethod(Invocation invocation)".
const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a56f2d9..91c919d 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -984,8 +984,24 @@
}
+// Calls to the runtime to optimize the given function.
+// T0: function to be reoptimized.
+// S4: argument descriptor (preserved).
void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
- __ Unimplemented("OptimizeFunction Stub");
+ __ EnterStubFrame();
+ __ Push(S4);
+ __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
+ __ Push(TMP); // Setup space on stack for return value.
+ __ Push(T0);
+ __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
+ __ Pop(T0); // Discard argument.
+ __ Pop(T0); // Get Code object
+ __ Pop(S4); // Restore argument descriptor.
+ __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
+ __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
+ __ LeaveStubFrame();
+ __ jr(T0);
+ __ break_(0);
}
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 90d3b82..014b798 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1331,7 +1331,7 @@
// R10 : arguments descriptor array.
void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
// The target function was not found, so invoke method
- // "dynamic noSuchMethod(InvocationMirror invocation)".
+ // "dynamic noSuchMethod(Invocation invocation)".
const Immediate& raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 1cd4c5f..eaf38652 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -12,6 +12,7 @@
'collection_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_gen.cc',
'collection_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_patch_gen.cc',
'collection_dev_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_dev_gen.cc',
+ 'collection_dev_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_dev_patch_gen.cc',
'crypto_cc_file': '<(SHARED_INTERMEDIATE_DIR)/crypto_gen.cc',
'math_cc_file': '<(SHARED_INTERMEDIATE_DIR)/math_gen.cc',
'math_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/math_patch_gen.cc',
@@ -98,6 +99,7 @@
'generate_collection_cc_file',
'generate_collection_patch_cc_file',
'generate_collection_dev_cc_file',
+ 'generate_collection_dev_patch_cc_file',
'generate_crypto_cc_file',
'generate_math_cc_file',
'generate_math_patch_cc_file',
@@ -131,6 +133,7 @@
'<(collection_cc_file)',
'<(collection_patch_cc_file)',
'<(collection_dev_cc_file)',
+ '<(collection_dev_patch_cc_file)',
'<(crypto_cc_file)',
'<(math_cc_file)',
'<(math_patch_cc_file)',
@@ -376,6 +379,44 @@
]
},
{
+ 'target_name': 'generate_collection_dev_patch_cc_file',
+ 'type': 'none',
+ 'includes': [
+ # Load the runtime implementation sources.
+ '../lib/collection_dev_sources.gypi',
+ ],
+ 'sources/': [
+ # Exclude all .[cc|h] files.
+ # This is only here for reference. Excludes happen after
+ # variable expansion, so the script has to do its own
+ # exclude processing of the sources being passed.
+ ['exclude', '\\.cc|h$'],
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generate_collection_dev_patch_cc',
+ 'inputs': [
+ '../tools/create_string_literal.py',
+ '<(builtin_in_cc_file)',
+ '<@(_sources)',
+ ],
+ 'outputs': [
+ '<(collection_dev_patch_cc_file)',
+ ],
+ 'action': [
+ 'python',
+ 'tools/create_string_literal.py',
+ '--output', '<(collection_dev_patch_cc_file)',
+ '--input_cc', '<(builtin_in_cc_file)',
+ '--include', 'vm/bootstrap.h',
+ '--var_name', 'dart::Bootstrap::collection_dev_patch_',
+ '<@(_sources)',
+ ],
+ 'message': 'Generating ''<(collection_dev_patch_cc_file)'' file.'
+ },
+ ]
+ },
+ {
'target_name': 'generate_collection_dev_cc_file',
'type': 'none',
'variables': {
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
new file mode 100755
index 0000000..3f0f947
--- /dev/null
+++ b/sdk/bin/dartanalyzer
@@ -0,0 +1,79 @@
+#!/bin/bash --posix
+# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+set -e
+
+# Setting SCRIPT_DIR this way is ugly, but is needed to handle the case where
+# dart-sdk/bin has been symlinked to. On MacOS, readlink doesn't work
+# with this case.
+SCRIPT_DIR="$(cd "${0%/*}" ; pwd -P)"
+DART_ANALYZER_HOME="$(cd "${SCRIPT_DIR%/*}" ; pwd -P)"
+
+FOUND_BATCH=0
+FOUND_SDK=0
+for ARG in "$@"
+do
+ case $ARG in
+ -batch|--batch)
+ FOUND_BATCH=1
+ ;;
+ --dart-sdk)
+ FOUND_SDK=1
+ ;;
+ *)
+ ;;
+ esac
+done
+
+DART_SDK=""
+if [ $FOUND_SDK = 0 ] ; then
+ if [ -f $DART_ANALYZER_HOME/lib/core/core.dart ] ; then
+ DART_SDK="--dart-sdk $DART_ANALYZER_HOME"
+ else
+ DART_SDK_HOME=$(dirname $DART_ANALYZER_HOME)/dart-sdk
+ if [ -d $DART_SDK_HOME ] ; then
+ DART_SDK="--dart-sdk $DART_SDK_HOME"
+ else
+ DART_SDK_HOME=$(dirname $DART_SDK_HOME)/dart-sdk
+ if [ -d $DART_SDK_HOME ] ; then
+ DART_SDK="--dart-sdk $DART_SDK_HOME"
+ else
+ echo "Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument"
+ fi
+ fi
+ fi
+fi
+
+if [ -f $DART_SDK_HOME/util/dartanalyzer/dartanalyzer.jar ] ; then
+ DART_ANALYZER_LIBS=$DART_SDK_HOME/util/dartanalyzer
+elif [ -f $DART_ANALYZER_HOME/util/dartanalyzer/dartanalyzer.jar ] ; then
+ DART_ANALYZER_LIBS=$DART_ANALYZER_HOME/util/dartanalyzer
+else
+ echo "Configuration problem. Couldn't find dartanalyzer.jar."
+ exit 1
+fi
+
+if [ -x /usr/libexec/java_home ]; then
+ export JAVA_HOME=$(/usr/libexec/java_home -v '1.6+')
+fi
+
+EXTRA_JVMARGS="-Xss2M "
+OS=`uname | tr "[A-Z]" "[a-z]"`
+if [ "$OS" == "darwin" ] ; then
+ # Bump up the heap on Mac VMs, some of which default to 128M or less.
+ # Users can specify DART_JVMARGS in the environment to override this
+ # setting.
+ EXTRA_JVMARGS+=" -Xmx256M -client "
+else
+ # On other architectures
+ # -batch invocations will do better with a server vm
+ # invocations for analyzing a single file do better with a client vm
+ if [ $FOUND_BATCH = 0 ] ; then
+ EXTRA_JVMARGS+=" -client "
+ fi
+fi
+
+exec java $EXTRA_JVMARGS $DART_JVMARGS -ea -jar \
+ "$DART_ANALYZER_LIBS/dartanalyzer.jar" ${DART_SDK} $@
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
new file mode 100644
index 0000000..9a2af5e
--- /dev/null
+++ b/sdk/bin/dartanalyzer.bat
@@ -0,0 +1,58 @@
+@echo off
+rem Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+rem for details. All rights reserved. Use of this source code is governed by a
+rem BSD-style license that can be found in the LICENSE file.
+
+set SCRIPT_DIR=%~dp0
+if %SCRIPT_DIR:~-1%==\ set SCRIPT_DIR=%SCRIPT_DIR:~0,-1%
+
+for %%I in ("%SCRIPT_DIR%\..") do set "DART_ANALYZER_HOME=%%~fI"
+if %DART_ANALYZER_HOME:~-1%==\ set DART_ANALYZER_HOME=%DART_ANALYZER_HOME:~0,-1%
+
+set FOUND_BATCH=0
+set FOUND_SDK=0
+for %%a in (%*) do (
+ if [%%a] == [--batch] set FOUND_BATCH=1
+ if [%%a] == [-b] set FOUND_BATCH=1
+ if [%%a] == [--dart-sdk] set FOUND_SDK=1
+)
+
+setlocal EnableDelayedExpansion
+set DART_SDK=""
+if [%FOUND_SDK%] == [0] (
+ if exist "%DART_ANALYZER_HOME%\lib\core\core.dart" (
+ set DART_SDK=--dart-sdk "%DART_ANALYZER_HOME%"
+ ) else (
+ for /f %%i in ('echo %DART_ANALYZER_HOME%') do set DART_SDK_HOME=%%~dpi\dart-sdk
+ if exist "!DART_SDK_HOME!" (
+ set DART_SDK=--dart-sdk !DART_SDK_HOME!
+ ) else (
+ for /f %%j in ('call echo !DART_SDK_HOME!') do set DART_SDK_HOME=%%~dpj\dart-sdk
+ if exist "!DART_SDK_HOME!" (
+ set DART_SDK=--dart-sdk !DART_SDK_HOME!
+ ) else (
+ echo Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument
+ )
+ )
+ )
+)
+endlocal & set "DART_SDK=%DART_SDK%" & set "DART_SDK_HOME=%DART_SDK_HOME%"
+
+if exist "%DART_SDK_HOME%\util\dartanalyzer\dartanalyzer.jar" (
+ set DART_ANALYZER_LIBS=%DART_SDK_HOME%\util\dartanalyzer
+) else if exist "%DART_ANALYZER_HOME%\util\dartanalyzer\dartanalyzer.jar" (
+ set DART_ANALYZER_LIBS=%DART_ANALYZER_HOME%\util\dartanalyzer
+) else (
+ echo Configuration problem. Couldn't find dartanalyzer.jar.
+ exit /b 1
+)
+
+setlocal EnableDelayedExpansion
+set EXTRA_JVMARGS=-Xss2M
+if [%FOUND_BATCH%] == [1] (
+ set EXTRA_JVMARGS=!EXTRA_JVMARGS! -client
+)
+endlocal & set "EXTRA_JVMARGS=%EXTRA_JVMARGS%"
+
+java %EXTRA_JVMARGS% %DART_JVMARGS% -ea -jar \
+ "%DART_ANALYZER_LIBS%\dartanalyzer.jar" %DART_SDK% %*
diff --git a/sdk/lib/_collection_dev/collection_dev.dart b/sdk/lib/_collection_dev/collection_dev.dart
index 385d029..79ca515 100644
--- a/sdk/lib/_collection_dev/collection_dev.dart
+++ b/sdk/lib/_collection_dev/collection_dev.dart
@@ -6,11 +6,12 @@
import 'dart:collection';
+import 'dart:core' hide Symbol;
+import 'dart:core' as core;
+
part 'arrays.dart';
part 'iterable.dart';
part 'list.dart';
part 'sort.dart';
+part 'symbol.dart';
part 'to_string.dart';
-
-// TODO(floitsch): move this into core, another hidden library or remove it.
-const deprecated = 0;
diff --git a/sdk/lib/_collection_dev/collection_dev_sources.gypi b/sdk/lib/_collection_dev/collection_dev_sources.gypi
index 4f941b6..f994b42 100644
--- a/sdk/lib/_collection_dev/collection_dev_sources.gypi
+++ b/sdk/lib/_collection_dev/collection_dev_sources.gypi
@@ -11,6 +11,7 @@
'iterable.dart',
'list.dart',
'sort.dart',
+ 'symbol.dart',
'to_string.dart',
],
}
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 60777e9..c82fa03 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -10,7 +10,7 @@
* All other methods are implemented in terms of [length] and [elementAt],
* including [iterator].
*/
-abstract class ListIterable<E> extends Iterable<E> {
+abstract class ListIterable<E> extends IterableBase<E> {
int get length;
E elementAt(int i);
@@ -298,7 +298,7 @@
typedef T _Transformation<S, T>(S value);
-class MappedIterable<S, T> extends Iterable<T> {
+class MappedIterable<S, T> extends IterableBase<T> {
final Iterable<S> _iterable;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -356,7 +356,7 @@
typedef bool _ElementPredicate<E>(E element);
-class WhereIterable<E> extends Iterable<E> {
+class WhereIterable<E> extends IterableBase<E> {
final Iterable<E> _iterable;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -389,7 +389,7 @@
typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement);
-class ExpandIterable<S, T> extends Iterable<T> {
+class ExpandIterable<S, T> extends IterableBase<T> {
final Iterable<S> _iterable;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -436,7 +436,7 @@
}
}
-class TakeIterable<E> extends Iterable<E> {
+class TakeIterable<E> extends IterableBase<E> {
final Iterable<E> _iterable;
final int _takeCount;
@@ -474,7 +474,7 @@
}
}
-class TakeWhileIterable<E> extends Iterable<E> {
+class TakeWhileIterable<E> extends IterableBase<E> {
final Iterable<E> _iterable;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -511,7 +511,7 @@
}
}
-class SkipIterable<E> extends Iterable<E> {
+class SkipIterable<E> extends IterableBase<E> {
final Iterable<E> _iterable;
final int _skipCount;
@@ -550,7 +550,7 @@
E get current => _iterator.current;
}
-class SkipWhileIterable<E> extends Iterable<E> {
+class SkipWhileIterable<E> extends IterableBase<E> {
final Iterable<E> _iterable;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -588,7 +588,7 @@
/**
* The always empty [Iterable].
*/
-class EmptyIterable<E> extends Iterable<E> {
+class EmptyIterable<E> extends IterableBase<E> {
const EmptyIterable();
Iterator<E> get iterator => const EmptyIterator();
@@ -666,3 +666,379 @@
abstract class BidirectionalIterator<T> implements Iterator<T> {
bool movePrevious();
}
+
+/**
+ * This class provides default implementations for Iterables (including Lists).
+ *
+ * The uses of this class will be replaced by mixins.
+ */
+class IterableMixinWorkaround {
+ static bool contains(Iterable iterable, var element) {
+ for (final e in iterable) {
+ if (element == e) return true;
+ }
+ return false;
+ }
+
+ static void forEach(Iterable iterable, void f(o)) {
+ for (final e in iterable) {
+ f(e);
+ }
+ }
+
+ static bool any(Iterable iterable, bool f(o)) {
+ for (final e in iterable) {
+ if (f(e)) return true;
+ }
+ return false;
+ }
+
+ static bool every(Iterable iterable, bool f(o)) {
+ for (final e in iterable) {
+ if (!f(e)) return false;
+ }
+ return true;
+ }
+
+ static dynamic reduce(Iterable iterable,
+ dynamic combine(previousValue, element)) {
+ Iterator iterator = iterable.iterator;
+ if (!iterator.moveNext()) throw new StateError("No elements");
+ var value = iterator.current;
+ while (iterator.moveNext()) {
+ value = combine(value, iterator.current);
+ }
+ return value;
+ }
+
+ static dynamic fold(Iterable iterable,
+ dynamic initialValue,
+ dynamic combine(dynamic previousValue, element)) {
+ for (final element in iterable) {
+ initialValue = combine(initialValue, element);
+ }
+ return initialValue;
+ }
+
+ /**
+ * Removes elements matching [test] from [list].
+ *
+ * This is performed in two steps, to avoid exposing an inconsistent state
+ * to the [test] function. First the elements to retain are found, and then
+ * the original list is updated to contain those elements.
+ */
+ static void removeWhereList(List list, bool test(var element)) {
+ List retained = [];
+ int length = list.length;
+ for (int i = 0; i < length; i++) {
+ var element = list[i];
+ if (!test(element)) {
+ retained.add(element);
+ }
+ if (length != list.length) {
+ throw new ConcurrentModificationError(list);
+ }
+ }
+ if (retained.length == length) return;
+ list.length = retained.length;
+ for (int i = 0; i < retained.length; i++) {
+ list[i] = retained[i];
+ }
+ }
+
+ static bool isEmpty(Iterable iterable) {
+ return !iterable.iterator.moveNext();
+ }
+
+ static dynamic first(Iterable iterable) {
+ Iterator it = iterable.iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ return it.current;
+ }
+
+ static dynamic last(Iterable iterable) {
+ Iterator it = iterable.iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ dynamic result;
+ do {
+ result = it.current;
+ } while(it.moveNext());
+ return result;
+ }
+
+ static dynamic single(Iterable iterable) {
+ Iterator it = iterable.iterator;
+ if (!it.moveNext()) throw new StateError("No elements");
+ dynamic result = it.current;
+ if (it.moveNext()) throw new StateError("More than one element");
+ return result;
+ }
+
+ static dynamic firstWhere(Iterable iterable,
+ bool test(dynamic value),
+ dynamic orElse()) {
+ for (dynamic element in iterable) {
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ static dynamic lastWhere(Iterable iterable,
+ bool test(dynamic value),
+ dynamic orElse()) {
+ dynamic result = null;
+ bool foundMatching = false;
+ for (dynamic element in iterable) {
+ if (test(element)) {
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ static dynamic lastWhereList(List list,
+ bool test(dynamic value),
+ dynamic orElse()) {
+ // TODO(floitsch): check that arguments are of correct type?
+ for (int i = list.length - 1; i >= 0; i--) {
+ dynamic element = list[i];
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) {
+ dynamic result = null;
+ bool foundMatching = false;
+ for (dynamic element in iterable) {
+ if (test(element)) {
+ if (foundMatching) {
+ throw new StateError("More than one matching element");
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ throw new StateError("No matching element");
+ }
+
+ static dynamic elementAt(Iterable iterable, int index) {
+ if (index is! int || index < 0) throw new RangeError.value(index);
+ int remaining = index;
+ for (dynamic element in iterable) {
+ if (remaining == 0) return element;
+ remaining--;
+ }
+ throw new RangeError.value(index);
+ }
+
+ static String join(Iterable iterable, [String separator]) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.writeAll(iterable, separator);
+ return buffer.toString();
+ }
+
+ static String joinList(List list, [String separator]) {
+ if (list.isEmpty) return "";
+ if (list.length == 1) return "${list[0]}";
+ StringBuffer buffer = new StringBuffer();
+ if (separator.isEmpty) {
+ for (int i = 0; i < list.length; i++) {
+ buffer.write(list[i]);
+ }
+ } else {
+ buffer.write(list[0]);
+ for (int i = 1; i < list.length; i++) {
+ buffer.write(separator);
+ buffer.write(list[i]);
+ }
+ }
+ return buffer.toString();
+ }
+
+ static Iterable where(Iterable iterable, bool f(var element)) {
+ return new WhereIterable(iterable, f);
+ }
+
+ static Iterable map(Iterable iterable, f(var element)) {
+ return new MappedIterable(iterable, f);
+ }
+
+ static Iterable mapList(List list, f(var element)) {
+ return new MappedListIterable(list, f);
+ }
+
+ static Iterable expand(Iterable iterable, Iterable f(var element)) {
+ return new ExpandIterable(iterable, f);
+ }
+
+ static Iterable takeList(List list, int n) {
+ // The generic type is currently lost. It will be fixed with mixins.
+ return new SubListIterable(list, 0, n);
+ }
+
+ static Iterable takeWhile(Iterable iterable, bool test(var value)) {
+ // The generic type is currently lost. It will be fixed with mixins.
+ return new TakeWhileIterable(iterable, test);
+ }
+
+ static Iterable skipList(List list, int n) {
+ // The generic type is currently lost. It will be fixed with mixins.
+ return new SubListIterable(list, n, null);
+ }
+
+ static Iterable skipWhile(Iterable iterable, bool test(var value)) {
+ // The generic type is currently lost. It will be fixed with mixins.
+ return new SkipWhileIterable(iterable, test);
+ }
+
+ static Iterable reversedList(List list) {
+ return new ReversedListIterable(list);
+ }
+
+ static void sortList(List list, int compare(a, b)) {
+ if (compare == null) compare = Comparable.compare;
+ Sort.sort(list, compare);
+ }
+
+ static int indexOfList(List list, var element, int start) {
+ return Arrays.indexOf(list, element, start, list.length);
+ }
+
+ static int lastIndexOfList(List list, var element, int start) {
+ if (start == null) start = list.length - 1;
+ return Arrays.lastIndexOf(list, element, start);
+ }
+
+ static void _rangeCheck(List list, int start, int end) {
+ if (start < 0 || start > list.length) {
+ throw new RangeError.range(start, 0, list.length);
+ }
+ if (end < start || end > list.length) {
+ throw new RangeError.range(end, start, list.length);
+ }
+ }
+
+ static Iterable getRangeList(List list, int start, int end) {
+ _rangeCheck(list, start, end);
+ // The generic type is currently lost. It will be fixed with mixins.
+ return new SubListIterable(list, start, end);
+ }
+
+ static void setRangeList(List list, int start, int end,
+ Iterable from, int skipCount) {
+ _rangeCheck(list, start, end);
+ int length = end - start;
+ if (length == 0) return;
+
+ if (skipCount < 0) throw new ArgumentError(skipCount);
+
+ // TODO(floitsch): Make this accept more.
+ List otherList;
+ int otherStart;
+ if (from is List) {
+ otherList = from;
+ otherStart = skipCount;
+ } else {
+ otherList = from.skip(skipCount).toList(growable: false);
+ otherStart = 0;
+ }
+ if (otherStart + length > otherList.length) {
+ throw new StateError("Not enough elements");
+ }
+ Arrays.copy(otherList, otherStart, list, start, length);
+ }
+
+ static void replaceRangeList(List list, int start, int end,
+ Iterable iterable) {
+ _rangeCheck(list, start, end);
+ // TODO(floitsch): optimize this.
+ list.removeRange(start, end);
+ list.insertAll(start, iterable);
+ }
+
+ static void fillRangeList(List list, int start, int end, fillValue) {
+ _rangeCheck(list, start, end);
+ for (int i = start; i < end; i++) {
+ list[i] = fillValue;
+ }
+ }
+
+ static void insertAllList(List list, int index, Iterable iterable) {
+ if (index < 0 || index > list.length) {
+ throw new RangeError.range(index, 0, list.length);
+ }
+ if (iterable is! List && iterable is! Set) {
+ iterable = iterable.toList(growable: false);
+ }
+ int insertionLength = iterable.length;
+ list.length += insertionLength;
+ list.setRange(index + insertionLength, list.length, list, index);
+ for (var element in iterable) {
+ list[index++] = element;
+ }
+ }
+
+ static void setAllList(List list, int index, Iterable iterable) {
+ if (index < 0 || index > list.length) {
+ throw new RangeError.range(index, 0, list.length);
+ }
+ for (var element in iterable) {
+ list[index++] = element;
+ }
+ }
+
+ static Map<int, dynamic> asMapList(List l) {
+ return new ListMapView(l);
+ }
+
+ static bool setContainsAll(Set set, Iterable other) {
+ for (var element in other) {
+ if (!set.contains(element)) return false;
+ }
+ return true;
+ }
+
+ static Set setIntersection(Set set, Set other, Set result) {
+ Set smaller;
+ Set larger;
+ if (set.length < other.length) {
+ smaller = set;
+ larger = other;
+ } else {
+ smaller = other;
+ larger = set;
+ }
+ for (var element in smaller) {
+ if (larger.contains(element)) {
+ result.add(element);
+ }
+ }
+ return result;
+ }
+
+ static Set setUnion(Set set, Set other, Set result) {
+ result.addAll(set);
+ result.addAll(other);
+ return result;
+ }
+
+ static Set setDifference(Set set, Set other, Set result) {
+ for (var element in set) {
+ if (!other.contains(element)) {
+ result.add(element);
+ }
+ }
+ return result;
+ }
+}
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index 3ab841d..93e49ae 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -25,6 +25,11 @@
"Cannot add to a fixed-length list");
}
+ void insertAll(int at, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot add to a fixed-length list");
+ }
+
void addAll(Iterable<E> iterable) {
throw new UnsupportedError(
"Cannot add to a fixed-length list");
@@ -70,14 +75,14 @@
"Cannot remove from a fixed-length list");
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot remove from a fixed-length list");
}
- void insertRange(int start, int length, [E initialValue]) {
+ void replaceRange(int start, int end, Iterable<E> iterable) {
throw new UnsupportedError(
- "Cannot insert range in a fixed-length list");
+ "Cannot remove from a fixed-length list");
}
}
@@ -100,6 +105,11 @@
"Cannot change the length of an unmodifiable list");
}
+ void setAll(int at, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot modify an unmodifiable list");
+ }
+
void add(E value) {
throw new UnsupportedError(
"Cannot add to an unmodifiable list");
@@ -110,6 +120,11 @@
"Cannot add to an unmodifiable list");
}
+ void insertAll(int at, Iterable<E> iterable) {
+ throw new UnsupportedError(
+ "Cannot add to an unmodifiable list");
+ }
+
void addAll(Iterable<E> iterable) {
throw new UnsupportedError(
"Cannot add to an unmodifiable list");
@@ -160,19 +175,24 @@
"Cannot remove from an unmodifiable list");
}
- void setRange(int start, int length, List<E> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
throw new UnsupportedError(
"Cannot modify an unmodifiable list");
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot remove from an unmodifiable list");
}
- void insertRange(int start, int length, [E initialValue]) {
+ void replaceRange(int start, int end, Iterable<E> iterable) {
throw new UnsupportedError(
- "Cannot insert range in an unmodifiable list");
+ "Cannot remove from an unmodifiable list");
+ }
+
+ void fillRange(int start, int end, [E fillValue]) {
+ throw new UnsupportedError(
+ "Cannot modify an unmodifiable list");
}
}
diff --git a/sdk/lib/_collection_dev/symbol.dart b/sdk/lib/_collection_dev/symbol.dart
new file mode 100644
index 0000000..1a81f47
--- /dev/null
+++ b/sdk/lib/_collection_dev/symbol.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart._collection.dev;
+
+/**
+ * Implementation of [core.Symbol]. This class uses the same name as
+ * a core class so a user can't tell the difference.
+ *
+ * The purpose of this class is to hide [_name] from user code, but
+ * make it accessible to Dart platform code via the static method
+ * [getName].
+ */
+class Symbol implements core.Symbol {
+ final String _name;
+
+ external const Symbol(String name);
+
+ /**
+ * Platform-private method used by the mirror system to create
+ * otherwise invalid names.
+ */
+ const Symbol.unvalidated(this._name);
+
+ bool operator ==(other) => other is Symbol && _name == other._name;
+
+ int get hashCode {
+ const arbitraryPrime = 664597;
+ return 0x1fffffff & (arbitraryPrime * _name.hashCode);
+ }
+
+ /// Platform-private accessor which cannot be called from user libraries.
+ static String getName(Symbol symbol) => symbol._name;
+}
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b3c72c4..41c5ac1 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -105,7 +105,7 @@
..close();
code = ''; // Non-null signals success.
}
- return new Future.immediate(code);
+ return new Future.value(code);
}
/**
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 1e2ab51..4493412 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -1275,7 +1275,7 @@
add(String value) {}
- void addError(AsyncError error) {}
+ void addError(Object error) {}
void close() {}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index d1f08f9..4031beb 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -344,7 +344,7 @@
count += value.length;
}
- void addError(AsyncError error) { sink.addError(error); }
+ void addError(Object error) { sink.addError(error); }
void close() { sink.close(); }
}
diff --git a/sdk/lib/_internal/compiler/implementation/js/builder.dart b/sdk/lib/_internal/compiler/implementation/js/builder.dart
index 5247d67..7e71928 100644
--- a/sdk/lib/_internal/compiler/implementation/js/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/builder.dart
@@ -158,7 +158,7 @@
/// * dot access.
/// * method calls.
/// * [] access.
-/// * array, string, boolean, null and numeric literals (no hex).
+/// * array, string, regexp, boolean, null and numeric literals.
/// * most operators.
/// * brackets.
/// * var declarations.
@@ -173,10 +173,9 @@
/// Literal strings are passed through to the final JS source code unchanged,
/// including the choice of surrounding quotes, so if you parse
/// r'var x = "foo\n\"bar\""' you will end up with
-/// var x = "foo\n\"bar\"" in the final program. String literals are
-/// restricted to a small subset of the full set of allowed JS escapes in order
-/// to get early errors for unintentional escape sequences without complicating
-/// this parser unneccessarily.
+/// var x = "foo\n\"bar\"" in the final program. \x and \u escapes are not
+/// allowed in string and regexp literals because the machinery for checking
+/// their correctness is rather involved.
class MiniJsParser {
MiniJsParser(this.src, this.interpolatedValues)
: lastCategory = NONE,
@@ -184,7 +183,7 @@
lastPosition = 0,
position = 0,
valuesUsed = 0 {
- getSymbol();
+ getToken();
}
int lastCategory;
@@ -230,6 +229,7 @@
case RPAREN: return "RPAREN";
case LBRACE: return "LBRACE";
case RBRACE: return "RBRACE";
+ case LSQUARE: return "LSQUARE";
case RSQUARE: return "RSQUARE";
case STRING: return "STRING";
case COMMA: return "COMMA";
@@ -284,12 +284,37 @@
static final UNARY_OPERATORS =
['++', '--', '+', '-', '~', '!', 'typeof', 'void', 'delete'].toSet();
+ static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS =
+ ['typeof', 'void', 'delete', 'in', 'instanceof'].toSet();
+
static int category(int code) {
if (code >= CATEGORIES.length) return OTHER;
return CATEGORIES[code];
}
- void getSymbol() {
+ String getDelimited(int startPosition) {
+ position = startPosition;
+ int delimiter = src.codeUnitAt(startPosition);
+ int currentCode;
+ do {
+ position++;
+ if (position >= src.length) error("Unterminated literal");
+ currentCode = src.codeUnitAt(position);
+ if (currentCode == charCodes.$BACKSLASH) {
+ if (++position >= src.length) error("Unterminated literal");
+ int escaped = src.codeUnitAt(position);
+ if (escaped == charCodes.$x || escaped == charCodes.$X ||
+ escaped == charCodes.$u || escaped == charCodes.$U ||
+ category(escaped) == NUMERIC) {
+ error('Numeric and hex escapes are not allowed in literals');
+ }
+ }
+ } while (currentCode != delimiter);
+ position++;
+ return src.substring(lastPosition, position);
+ }
+
+ void getToken() {
while (position < src.length &&
category(src.codeUnitAt(position)) == WHITESPACE) {
position++;
@@ -303,42 +328,44 @@
int code = src.codeUnitAt(position);
lastPosition = position;
if (code == charCodes.$SQ || code == charCodes.$DQ) {
- int currentCode;
- do {
- position++;
- if (position >= src.length) {
- throw new MiniJsParserError(this, "Unterminated string");
- }
- currentCode = src.codeUnitAt(position);
- if (currentCode == charCodes.$BACKSLASH) {
- if (++position >= src.length) {
- throw new MiniJsParserError(this, "Unterminated string");
- }
- int escapedCode = src.codeUnitAt(position);
- if (!(escapedCode == charCodes.$BACKSLASH ||
- escapedCode == charCodes.$SQ ||
- escapedCode == charCodes.$DQ ||
- escapedCode == charCodes.$n)) {
- throw new MiniJsParserError(
- this,
- 'Only escapes allowed in string literals are '
- r'''\\, \', \" and \n''');
- }
- }
- } while (currentCode != code);
+ // String literal.
lastCategory = STRING;
+ lastToken = getDelimited(position);
+ } else if (code == charCodes.$0 &&
+ position + 2 < src.length &&
+ src.codeUnitAt(position + 1) == charCodes.$x) {
+ // Hex literal.
+ for (position += 2; position < src.length; position++) {
+ int cat = category(src.codeUnitAt(position));
+ if (cat != NUMERIC && cat != ALPHA) break;
+ }
+ lastCategory = NUMERIC;
+ lastToken = src.substring(lastPosition, position);
+ int.parse(lastToken, onError: (_) {
+ error("Unparseable number");
+ });
+ } else if (code == charCodes.$SLASH) {
+ // Tokens that start with / are special due to regexp literals.
+ lastCategory = SYMBOL;
position++;
+ if (position < src.length && src.codeUnitAt(position) == charCodes.$EQ) {
+ position++;
+ }
lastToken = src.substring(lastPosition, position);
} else {
+ // All other tokens handled here.
int cat = category(src.codeUnitAt(position));
int newCat;
do {
position++;
if (position == src.length) break;
int code = src.codeUnitAt(position);
- // Special code to disallow ! in non-first position in token, so that
- // !! parses as two tokens and != parses as one.
- newCat = (code == charCodes.$BANG) ? NONE : category(code);
+ // Special code to disallow ! and / in non-first position in token, so
+ // that !! parses as two tokens and != parses as one, while =/ parses
+ // as a an equals token followed by a regexp literal start.
+ newCat = (code == charCodes.$BANG || code == charCodes.$SLASH)
+ ? NONE
+ : category(code);
} while (!singleCharCategory(cat) &&
(cat == newCat ||
(cat == ALPHA && newCat == NUMERIC) || // eg. level42.
@@ -347,18 +374,16 @@
lastToken = src.substring(lastPosition, position);
if (cat == NUMERIC) {
double.parse(lastToken, (_) {
- throw new MiniJsParserError(this, "Unparseable number");
+ error("Unparseable number");
});
} else if (cat == SYMBOL) {
int binaryPrecendence = BINARY_PRECEDENCE[lastToken];
if (binaryPrecendence == null && !UNARY_OPERATORS.contains(lastToken)) {
- throw new MiniJsParserError(this, "Unknown operator");
+ error("Unknown operator");
}
if (isAssignment(lastToken)) lastCategory = ASSIGNMENT;
} else if (cat == ALPHA) {
- if (lastToken == 'typeof' || lastToken == 'void' ||
- lastToken == 'delete' || lastToken == 'in' ||
- lastToken == 'instanceof') {
+ if (OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(lastToken)) {
lastCategory = SYMBOL;
}
}
@@ -366,15 +391,13 @@
}
void expectCategory(int cat) {
- if (cat != lastCategory) {
- throw new MiniJsParserError(this, "Expected ${categoryToString(cat)}");
- }
- getSymbol();
+ if (cat != lastCategory) error("Expected ${categoryToString(cat)}");
+ getToken();
}
bool acceptCategory(int cat) {
if (cat == lastCategory) {
- getSymbol();
+ getToken();
return true;
}
return false;
@@ -382,12 +405,16 @@
bool acceptString(String string) {
if (lastToken == string) {
- getSymbol();
+ getToken();
return true;
}
return false;
}
+ void error(message) {
+ throw new MiniJsParserError(this, message);
+ }
+
Expression parsePrimary() {
String last = lastToken;
if (acceptCategory(ALPHA)) {
@@ -420,14 +447,21 @@
expectCategory(RSQUARE);
}
return new ArrayInitializer(values.length, values);
+ } else if (last.startsWith("/")) {
+ String regexp = getDelimited(lastPosition);
+ getToken();
+ String flags = lastToken;
+ if (!acceptCategory(ALPHA)) flags = "";
+ Expression expression = new RegExpLiteral(regexp + flags);
+ return expression;
} else if (acceptCategory(HASH)) {
if (interpolatedValues == null ||
valuesUsed >= interpolatedValues.length) {
- throw new MiniJsParserError(this, "Too few values for #es");
+ error("Too few values for '#'s");
}
return interpolatedValues[valuesUsed++];
} else {
- throw new MiniJsParserError(this, "Expected primary expression");
+ error("Expected primary expression");
}
}
@@ -435,9 +469,7 @@
Expression receiver = parsePrimary();
while (true) {
if (acceptCategory(DOT)) {
- String identifier = lastToken;
- expectCategory(ALPHA);
- receiver = new PropertyAccess.field(receiver, identifier);
+ receiver = getDotRhs(receiver);
} else if (acceptCategory(LSQUARE)) {
Expression inBraces = parseExpression();
expectCategory(RSQUARE);
@@ -466,16 +498,34 @@
new New(receiver, arguments) :
new Call(receiver, arguments);
constructor = false;
+ } else if (!constructor && acceptCategory(LSQUARE)) {
+ Expression inBraces = parseExpression();
+ expectCategory(RSQUARE);
+ receiver = new PropertyAccess(receiver, inBraces);
+ } else if (!constructor && acceptCategory(DOT)) {
+ receiver = getDotRhs(receiver);
} else {
- if (constructor) {
- // JS allows new without (), but we don't.
- throw new MiniJsParserError(this, "Parentheses are required for new");
- }
+ // JS allows new without (), but we don't.
+ if (constructor) error("Parentheses are required for new");
return receiver;
}
}
}
+ Expression getDotRhs(Expression receiver) {
+ String identifier = lastToken;
+ // In ES5 keywords like delete and continue are allowed as property
+ // names, and the IndexedDB API uses that, so we need to allow it here.
+ if (acceptCategory(SYMBOL)) {
+ if (!OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(identifier)) {
+ error("Expected alphanumeric identifier");
+ }
+ } else {
+ expectCategory(ALPHA);
+ }
+ return new PropertyAccess.field(receiver, identifier);
+ }
+
Expression parsePostfix() {
Expression expression = parseCall();
String operator = lastToken;
@@ -582,11 +632,10 @@
Expression expression() {
Expression expression = parseVarDeclarationOrExpression();
if (lastCategory != NONE || position != src.length) {
- throw new MiniJsParserError(
- this, "Unparsed junk: ${categoryToString(lastCategory)}");
+ error("Unparsed junk: ${categoryToString(lastCategory)}");
}
if (interpolatedValues != null && valuesUsed != interpolatedValues.length) {
- throw new MiniJsParserError(this, "Too many values for #es");
+ error("Too many values for #es");
}
return expression;
}
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 6f0b755..5fe00a4 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -519,7 +519,9 @@
accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this);
void visitChildren(NodeVisitor visitor) {
- for (Expression expr in inputs) expr.accept(visitor);
+ if (inputs != null) {
+ for (Expression expr in inputs) expr.accept(visitor);
+ }
}
// Code that uses JS must take care of operator precedences, and
@@ -916,7 +918,7 @@
}
/**
- * [RegExpLiteral]s, despite being called "Literal", are not inheriting from
+ * [RegExpLiteral]s, despite being called "Literal", do not inherit from
* [Literal]. Indeed, regular expressions in JavaScript have a side-effect and
* are thus not in the same category as numbers or strings.
*/
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 5af3a42..91d46b5 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -836,13 +836,14 @@
List<Expression> inputs = node.inputs;
List<String> parts = template.split('#');
- if (parts.length != inputs.length + 1) {
+ int inputsLength = inputs == null ? 0 : inputs.length;
+ if (parts.length != inputsLength + 1) {
compiler.internalError('Wrong number of arguments for JS: $template');
}
// Code that uses JS must take care of operator precedences, and
// put parenthesis if needed.
out(parts[0]);
- for (int i = 0; i < inputs.length; i++) {
+ for (int i = 0; i < inputsLength; i++) {
visit(inputs[i]);
out(parts[i + 1]);
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 69caf46..98e41ed 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -676,8 +676,9 @@
// classes.
Element dispatchPropertyName;
Element getNativeInterceptorMethod;
- Element setNativeInterceptorMethod;
Element defineNativeMethodsFinishMethod;
+ Element getDispatchPropertyMethod;
+ Element setDispatchPropertyMethod;
bool seenAnyClass = false;
@@ -861,12 +862,20 @@
compiler.findInterceptor(const SourceString('interceptedNames'));
dispatchPropertyName =
compiler.findInterceptor(const SourceString('dispatchPropertyName'));
+ getDispatchPropertyMethod =
+ compiler.findInterceptor(const SourceString('getDispatchProperty'));
+ setDispatchPropertyMethod =
+ compiler.findInterceptor(const SourceString('setDispatchProperty'));
getNativeInterceptorMethod =
compiler.findInterceptor(const SourceString('getNativeInterceptor'));
- setNativeInterceptorMethod =
- compiler.findInterceptor(const SourceString('setNativeInterceptor'));
defineNativeMethodsFinishMethod =
compiler.findHelper(const SourceString('defineNativeMethodsFinish'));
+
+ // These methods are overwritten with generated versions.
+ canBeInlined[getInterceptorMethod] = false;
+ canBeInlined[getDispatchPropertyMethod] = false;
+ canBeInlined[setDispatchPropertyMethod] = false;
+
List<ClassElement> classes = [
jsInterceptorClass =
compiler.findInterceptor(const SourceString('Interceptor')),
@@ -1021,7 +1030,6 @@
// TODO(9577): Make it so that these are not needed when there are no
// native classes.
enqueuer.registerStaticUse(getNativeInterceptorMethod);
- enqueuer.registerStaticUse(setNativeInterceptorMethod);
enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
}
}
@@ -1098,7 +1106,6 @@
// TODO(9577): Make it so that these are not needed when there are no native
// classes.
enqueuer.registerStaticUse(getNativeInterceptorMethod);
- enqueuer.registerStaticUse(setNativeInterceptorMethod);
enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 124a132..effe177 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -343,7 +343,7 @@
return [
js('var $supportsProtoName = false'),
- js('var tmp = (defineClass("c", ["f?"], {})).prototype'),
+ js('var tmp = defineClass("c", ["f?"], {}).prototype'),
js.if_(js('tmp.__proto__'), [
js('tmp.__proto__ = {}'),
diff --git a/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart
new file mode 100644
index 0000000..f224f24
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+patch class Symbol implements core.Symbol {
+ patch const Symbol(String name)
+ : this._name = name;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
index 1fd94cd..10afb9a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
@@ -301,7 +301,7 @@
}
}
-class HashMapKeyIterable<E> extends Iterable<E> {
+class HashMapKeyIterable<E> extends IterableBase<E> {
final _map;
HashMapKeyIterable(this._map);
@@ -653,7 +653,7 @@
LinkedHashMapCell(this._key, this._value);
}
-class LinkedHashMapKeyIterable<E> extends Iterable<E> {
+class LinkedHashMapKeyIterable<E> extends IterableBase<E> {
final _map;
LinkedHashMapKeyIterable(this._map);
@@ -1316,4 +1316,4 @@
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
index 75446c7..d84b4a5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
@@ -67,7 +67,7 @@
}
}
-class _ConstantMapKeyIterable extends Iterable<String> {
+class _ConstantMapKeyIterable extends IterableBase<String> {
ConstantMap _map;
_ConstantMapKeyIterable(this._map);
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 6569d60..56baf45 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -11,6 +11,7 @@
Primitives,
TypeImpl,
stringJoinUnchecked;
+import "dart:_collection-dev" as _symbol_dev;
patch void print(var object) {
Primitives.printString(object.toString());
@@ -22,7 +23,7 @@
patch String toString() => Primitives.objectToString(this);
- patch dynamic noSuchMethod(InvocationMirror invocation) {
+ patch dynamic noSuchMethod(Invocation invocation) {
throw new NoSuchMethodError(this,
invocation.memberName,
invocation.positionalArguments,
@@ -39,9 +40,19 @@
patch class Function {
patch static apply(Function function,
List positionalArguments,
- [Map<String,dynamic> namedArguments]) {
+ [Map<Symbol, dynamic> namedArguments]) {
return Primitives.applyFunction(
- function, positionalArguments, namedArguments);
+ function, positionalArguments, _toMangledNames(namedArguments));
+ }
+
+ static Map<String, dynamic> _toMangledNames(
+ Map<Symbol, dynamic> namedArguments) {
+ if (namedArguments == null) return null;
+ Map<String, dynamic> result = {};
+ namedArguments.forEach((symbol, value) {
+ result[_symbol_dev.Symbol.getName(symbol)] = value;
+ });
+ return result;
}
}
@@ -288,29 +299,3 @@
}
}
}
-
-patch class StackTrace {
- patch String get fullStackTrace {
- throw new UnsupportedError('fullStackTrace');
- }
-
- patch String get stackTrace {
- throw new UnsupportedError('stackTrace');
- }
-}
-
-patch class Symbol {
- final String _name;
-
- patch const Symbol(String name) :
- this._name = name;
-
- patch bool operator ==(other) {
- return other is Symbol && _name == other._name;
- }
-
- patch int get hashCode {
- const arbitraryPrime = 664597;
- return 0x1fffffff & (arbitraryPrime * _name.hashCode);
- }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
index 70c46ec..915fbf1 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
@@ -22,7 +22,8 @@
stringReplaceAllFuncUnchecked,
stringReplaceAllUnchecked,
stringReplaceFirstUnchecked,
- TypeImpl;
+ TypeImpl,
+ lookupDispatchRecord;
import 'dart:_foreign_helper' show JS;
part 'js_array.dart';
@@ -48,28 +49,98 @@
*/
var dispatchPropertyName = '_zzyzx';
+getDispatchProperty(object) {
+ // TODO(sra): Implement the magic.
+ // This is a magic method: the compiler replaces it with a runtime generated
+ // function
+ //
+ // function(object){return object._zzyzx;}
+ //
+ // where _zzyzx is replaced with the actual [dispatchPropertyName].
+ //
+ // The body is the CSP compliant version.
+ return JS('', '#[#]', object, dispatchPropertyName);
+}
+
+setDispatchProperty(object, value) {
+ // TODO(sra): Implement the magic.
+ // This is a magic method: the compiler replaces it with a runtime generated
+ // function
+ //
+ // function(object, value){object._zzyzx = value;}
+ //
+ // where _zzyzx is replaced with the actual [dispatchPropertyName].
+ //
+ // The body is the CSP compliant version.
+ JS('void', '#[#] = #', object, dispatchPropertyName, value);
+}
+
+makeDispatchRecord(interceptor, proto, extension) {
+ // Dispatch records are stored in the prototype chain, and in some cases, on
+ // instances.
+ //
+ // The record layout and field usage is designed to minimize the number of
+ // operations on the common paths.
+ //
+ // [interceptor] is the interceptor - a holder of methods for the object,
+ // i.e. the prototype of the interceptor class.
+ //
+ // [proto] is usually the prototype, used to check that the dispatch record
+ // matches the object and is not the dispatch record of a superclass. Other
+ // values:
+ // - `false` for leaf classes that need no check.
+ // - `true` for Dart classes where the object is its own interceptor (unused)
+ // - a function used to continue matching.
+ //
+ // [extension] is used for irregular cases.
+ //
+ // proto interceptor extension action
+ // ----- ----------- --------- ------
+ // false I use interceptor I
+ // true - use object
+ // P I if object's prototype is P, use I
+ // F - P if object's prototype is P, call F
+
+ return JS('', '{i: #, p: #, e: #}', interceptor, proto, extension);
+}
+
+dispatchRecordInterceptor(record) => JS('', '#.i', record);
+dispatchRecordProto(record) => JS('', '#.p', record);
+dispatchRecordExtension(record) => JS('', '#.e', record);
+
/**
* Returns the interceptor for a native class instance. Used by
* [getInterceptor].
*/
getNativeInterceptor(object) {
- // This is a magic method: the compiler replaces it with a runtime generated
- // function
- //
- // function(object){return object._zzyzx();}
- //
- // where _zzyzx is replaced with the actual [dispatchPropertyName].
- //
- // The body is the CSP compliant version.
- return JS('', '#[#]()', object, dispatchPropertyName);
-}
+ var record = getDispatchProperty(object);
-setNativeInterceptor(prototype, function) {
- JS('', '#[#]=#', prototype, dispatchPropertyName, function);
+ if (record != null) {
+ var proto = dispatchRecordProto(record);
+ if (false == proto) return dispatchRecordInterceptor(record);
+ if (true == proto) return object;
+ var objectProto = JS('', 'Object.getPrototypeOf(#)', object);
+ if (JS('bool', '# === #', proto, objectProto)) {
+ return dispatchRecordInterceptor(record);
+ }
+
+ var extension = dispatchRecordExtension(record);
+ if (JS('bool', '# === #', extension, objectProto)) {
+ // The extension handler will do any required patching. A typical use
+ // case is where one native class represents two Dart classes. The
+ // extension method will inspect the native object instance to determine
+ // its class and patch the instance. Needed to fix dartbug.com/9654.
+ return JS('', '(#)(#, #)', proto, object, record);
+ }
+ }
+
+ record = lookupDispatchRecord(object);
+ setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', object), record);
+ return getNativeInterceptor(object);
}
/**
- * If [InvocationMirror.invokeOn] is being used, this variable
+ * If [Invocation.invokeOn] is being used, this variable
* contains a JavaScript array with the names of methods that are
* intercepted.
*/
@@ -132,7 +203,7 @@
String toString() => Primitives.objectToString(this);
- dynamic noSuchMethod(InvocationMirror invocation) {
+ dynamic noSuchMethod(Invocation invocation) {
throw new NoSuchMethodError(this,
invocation.memberName,
invocation.positionalArguments,
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index 2702d9d..49cf730 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -111,14 +111,14 @@
patch static _read(int id, int bytes) {
throw new UnsupportedError("RandomAccessFile._read");
}
- patch static _readList(int id, List<int> buffer, int offset, int bytes) {
- throw new UnsupportedError("RandomAccessFile._readList");
+ patch static _readInto(int id, List<int> buffer, int start, int end) {
+ throw new UnsupportedError("RandomAccessFile._readInto");
}
patch static _writeByte(int id, int value) {
throw new UnsupportedError("RandomAccessFile._writeByte");
}
- patch static _writeList(int id, List<int> buffer, int offset, int bytes) {
- throw new UnsupportedError("RandomAccessFile._writeList");
+ patch static _writeFrom(int id, List<int> buffer, int start, int end) {
+ throw new UnsupportedError("RandomAccessFile._writeFrom");
}
patch static _position(int id) {
throw new UnsupportedError("RandomAccessFile._position");
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
index 22e13da..db10b54 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
@@ -33,8 +33,8 @@
_port.send(message);
}
- void addError(AsyncError errorEvent) {
- throw new UnimplementedError("signalError on isolate streams");
+ void addError(errorEvent) {
+ throw new UnimplementedError("addError on isolate streams");
}
void close() {
@@ -450,7 +450,7 @@
// such as d8 and jsshell. We should move this code to a helper
// library that is only loaded when testing on those engines.
- var stack = JS('String|Null', '(new Error()).stack');
+ var stack = JS('String|Null', 'new Error().stack');
if (stack == null) {
// According to Internet Explorer documentation, the stack
// property is not set until the exception is thrown. The stack
@@ -835,7 +835,7 @@
SendPort _port;
/**
- * Future of the underlying port, so that we can detect when this port can be
+ * Future.sync the underlying port, so that we can detect when this port can be
* sent on messages.
*/
Future<SendPort> _futurePort;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 7a57e31..ca01210 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -36,6 +36,16 @@
JS('void', r'#.splice(#, 0, #)', this, index, value);
}
+ void insertAll(int index, Iterable<E> iterable) {
+ checkGrowable(this, 'insertAll');
+ IterableMixinWorkaround.insertAllList(this, index, iterable);
+ }
+
+ void setAll(int index, Iterable<E> iterable) {
+ checkMutable(this, 'setAll');
+ IterableMixinWorkaround.setAllList(this, index, iterable);
+ }
+
E removeLast() {
checkGrowable(this, 'removeLast');
if (length == 0) throw new RangeError.value(-1);
@@ -160,34 +170,6 @@
return IterableMixinWorkaround.getRangeList(this, start, end);
}
- void insertRange(int start, int length, [E initialValue]) {
- checkGrowable(this, 'insertRange');
- if (length == 0) {
- return;
- }
- if (length is !int) throw new ArgumentError(length);
- if (length < 0) throw new ArgumentError(length);
- if (start is !int) throw new ArgumentError(start);
-
- var receiver = this;
- var receiverLength = receiver.length;
- if (start < 0 || start > receiverLength) {
- throw new RangeError.value(start);
- }
- receiver.length = receiverLength + length;
- Arrays.copy(receiver,
- start,
- receiver,
- start + length,
- receiverLength - start);
- if (initialValue != null) {
- for (int i = start; i < start + length; i++) {
- receiver[i] = initialValue;
- }
- }
- receiver.length = receiverLength + length;
- }
-
E get first {
if (length > 0) return this[0];
throw new StateError("No elements");
@@ -204,34 +186,36 @@
throw new StateError("More than one element");
}
- void removeRange(int start, int length) {
+ void removeRange(int start, int end) {
checkGrowable(this, 'removeRange');
- if (length == 0) {
- return;
+ int receiverLength = this.length;
+ if (start < 0 || start > receiverLength) {
+ throw new RangeError.range(start, 0, receiverLength);
}
- checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
- checkNull(length); // TODO(ahe): This is not specified but co19 tests it.
- if (start is !int) throw new ArgumentError(start);
- if (length is !int) throw new ArgumentError(length);
- if (length < 0) throw new ArgumentError(length);
- var receiverLength = this.length;
- if (start < 0 || start >= receiverLength) {
- throw new RangeError.value(start);
- }
- if (start + length > receiverLength) {
- throw new RangeError.value(start + length);
+ if (end < start || end > receiverLength) {
+ throw new RangeError.range(end, start, receiverLength);
}
Arrays.copy(this,
- start + length,
+ end,
this,
start,
- receiverLength - length - start);
- this.length = receiverLength - length;
+ receiverLength - end);
+ this.length = receiverLength - (end - start);
}
- void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
checkMutable(this, 'set range');
- IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
+ IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
+ }
+
+ void fillRange(int start, int end, [E fillValue]) {
+ checkMutable(this, 'fill range');
+ IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+ }
+
+ void replaceRange(int start, int end, Iterable<E> iterable) {
+ checkGrowable(this, 'removeRange');
+ IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
}
bool any(bool f(E element)) => IterableMixinWorkaround.any(this, f);
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index b77092f..a6ed014 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -16,6 +16,8 @@
import 'dart:_interceptors' show getInterceptor,
interceptedNames,
dispatchPropertyName,
+ makeDispatchRecord,
+ setDispatchProperty,
Interceptor,
JSIndexable;
@@ -63,7 +65,7 @@
createInvocationMirror(name, internalName, type, arguments, argumentNames) =>
new JSInvocationMirror(name, internalName, type, arguments, argumentNames);
-class JSInvocationMirror implements InvocationMirror {
+class JSInvocationMirror implements Invocation {
static const METHOD = 0;
static const GETTER = 1;
static const SETTER = 2;
@@ -503,7 +505,7 @@
static applyFunction(Function function,
List positionalArguments,
- Map<String, dynamic> namedArguments) {
+ Map<Symbol, dynamic> namedArguments) {
int argumentCount = 0;
StringBuffer buffer = new StringBuffer();
List arguments = [];
@@ -627,7 +629,7 @@
// Otherwise, produce a stack trace and record it in the wrapper.
// This is a slower way to create a stack trace which works on
// some browsers, but may simply evaluate to null.
- String stackTrace = JS('', '(new Error()).stack');
+ String stackTrace = JS('', 'new Error().stack');
JS('void', '#.stack = #', wrapper, stackTrace);
}
return wrapper;
@@ -822,13 +824,13 @@
* exception.
*/
StackTrace getTraceFromException(exception) {
- return new StackTrace(JS("var", r"#.stack", exception));
+ return new _StackTrace(JS("var", r"#.stack", exception));
}
-class StackTrace {
- var stack;
- StackTrace(this.stack);
- String toString() => stack != null ? stack : '';
+class _StackTrace implements StackTrace {
+ var _stack;
+ _StackTrace(this._stack);
+ String toString() => _stack != null ? _stack : '';
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index e6184c0..56a494da 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -89,42 +89,6 @@
return JS('String', r'#.substring(#, #)', this, startIndex, endIndex);
}
- String slice([int startIndex, int endIndex]) {
- int start, end;
- if (startIndex == null) {
- start = 0;
- } else if (startIndex is! int) {
- throw new ArgumentError("startIndex is not int");
- } else if (startIndex >= 0) {
- start = startIndex;
- } else {
- start = this.length + startIndex;
- }
- if (start < 0 || start > this.length) {
- throw new RangeError(
- "startIndex out of range: $startIndex (length: $length)");
- }
- if (endIndex == null) {
- end = this.length;
- } else if (endIndex is! int) {
- throw new ArgumentError("endIndex is not int");
- } else if (endIndex >= 0) {
- end = endIndex;
- } else {
- end = this.length + endIndex;
- }
- if (end < 0 || end > this.length) {
- throw new RangeError(
- "endIndex out of range: $endIndex (length: $length)");
- }
- if (end < start) {
- throw new ArgumentError(
- "End before start: $endIndex < $startIndex (length: $length)");
- }
- return JS('String', '#.substring(#, #)', this, start, end);
- }
-
-
String toLowerCase() {
return JS('String', r'#.toLowerCase()', this);
}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
index a41e099..020b836 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
@@ -23,6 +23,13 @@
bool _mirrorsEnabled = false;
+patch class MirrorSystem {
+ patch static String getName(Symbol symbol) {
+ throw new UnimplementedError('MirrorSystem.getName is not yet implemented '
+ 'in dart2js');
+ }
+}
+
/**
* Stub class for the mirror system.
*/
diff --git a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
index 566fb58..345120a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
@@ -224,71 +224,6 @@
value);
}
-/**
- * This method looks up the type name of [obj] in [methods]. [methods]
- * is a Javascript object. If it cannot find it, it looks into the
- * [_dynamicMetadata] array. If the method can still not be found, it
- * creates a method that will throw a [NoSuchMethodError].
- *
- * Once it has a method, the prototype of [obj] is patched with that
- * method, on the property [name]. The method is then invoked.
- *
- * This method returns the result of invoking the found method.
- */
-dynamicBind(var obj,
- String name,
- var methods,
- List arguments) {
- // The tag is related to the class name. E.g. the dart:html class
- // '_ButtonElement' has the tag 'HTMLButtonElement'. TODO(erikcorry): rename
- // getTypeNameOf to getTypeTag.
-
- var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
- var method = null;
- if (!isDartObject(obj)) {
- String tag = getTypeNameOf(obj);
-
- method = dynamicBindLookup(hasOwnPropertyFunction, tag, methods);
- if (method == null) {
- String secondTag = alternateTag(obj, tag);
- if (secondTag != null) {
- method = dynamicBindLookup(hasOwnPropertyFunction, secondTag, methods);
- }
- }
- }
-
- // If we didn't find the method then look up in the Dart Object class, using
- // getTypeNameOf in case the minifier has renamed Object.
- if (method == null) {
- String nameOfObjectClass = getTypeNameOf(const Object());
- method = lookupDynamicClass(
- hasOwnPropertyFunction, methods, nameOfObjectClass);
- }
-
- if (method == null) {
- // Throw the `TypeError` that would have happened if this dynamic bind hook
- // had not been installed on `Object.prototype`.
- JS('void',
- // `(function(){...})()` converts statement `throw` into an expression.
- '(function(){throw new TypeError(# + " is not a function");})()',
- name);
- } else {
- var proto = JS('var', 'Object.getPrototypeOf(#)', obj);
- // Patch the method onto the prototype to avoid repeating the lookup. We
- // expect that there is nothing called [name] on the immediate prototype,
- // except it is OK to patch over the dispatch hook on `Object.prototype`.
- // What this means is we are calling method [name] on a plain JavaScript
- // Object. If the patched method needs to access the dispatch hook (for
- // example, a check against being called from a yet-to-be-patched subclass),
- // it gets the hook from [dynamicDispatchTable].
- if (!callHasOwnProperty(hasOwnPropertyFunction, proto, name) ||
- JS('bool', '# === Object.prototype', proto)) {
- defineProperty(proto, name, method);
- }
- }
-
- return JS('var', '#.apply(#, #)', method, obj, arguments);
-}
// Is [obj] an instance of a Dart-defined class?
bool isDartObject(obj) {
@@ -296,7 +231,93 @@
return JS('bool', '((#) instanceof (#))', obj, JS_DART_OBJECT_CONSTRUCTOR());
}
-dynamicBindLookup(var hasOwnPropertyFunction, String tag, var methods) {
+// For each method name and class inheritance subtree, we use an ordinary JS
+// object as a hash map to store the methods for each class. Entries are added
+// in native_emitter.dart (see dynamicName). In order to avoid class names
+// clashing with the method names on Object.prototype (needed for native
+// objects) we must always use hasOwnProperty.
+lookupDynamicClass(var hasOwnPropertyFunction, var methods, String className) {
+ return callHasOwnProperty(hasOwnPropertyFunction, methods, className)
+ ? propertyGet(methods, className)
+ : null;
+}
+
+/// A JavaScript object mapping tags to interceptors.
+var interceptorsByTag;
+
+/// A JavaScript object mapping tags to `true` or `false`.
+var leafTags;
+
+/**
+ * Associates tags with an interceptor. Called from generated code. The tags
+ * are all 'leaf' tags representing classes that have no subclasses with
+ * different behaviour.
+ *
+ * [tags] is a string of `|`-separated tags.
+ */
+void defineNativeMethods(String tags, interceptorClass) {
+ defineNativeMethodsCommon(tags, interceptorClass, true);
+}
+
+/**
+ * Associates tags with an interceptor. Called from generated code. The tags
+ * are all non-'leaf' tags, representing classes that have a subclass with
+ * different behaviour.
+ */
+void defineNativeMethodsNonleaf(String tags, interceptorClass) {
+ defineNativeMethodsCommon(tags, interceptorClass, false);
+}
+
+void defineNativeMethodsCommon(String tags, var interceptorClass, bool isLeaf) {
+ var methods = JS('', '#.prototype', interceptorClass);
+ if (interceptorsByTag == null) interceptorsByTag = JS('=Object', '{}');
+ if (leafTags == null) leafTags = JS('=Object', '{}');
+
+ var tagsList = JS('=List', '#.split("|")', tags);
+ for (int i = 0; i < tagsList.length; i++) {
+ var tag = tagsList[i];
+ JS('void', '#[#] = #', interceptorsByTag, tag, methods);
+ JS('void', '#[#] = #', leafTags, tag, isLeaf);
+ }
+}
+
+void defineNativeMethodsFinish() {
+ // TODO(sra): Investigate placing a dispatch record on Object.prototype that
+ // returns an interceptor for JavaScript objects. This avoids needing a test
+ // in every interceptor, and prioritizes the performance of known native
+ // classes over unknown.
+}
+
+lookupDispatchRecord(obj) {
+ var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
+ var interceptor = null;
+ assert(!isDartObject(obj));
+ String tag = getTypeNameOf(obj);
+
+ interceptor = lookupInterceptor(
+ hasOwnPropertyFunction, tag, interceptorsByTag);
+
+ if (interceptor == null) {
+ String secondTag = alternateTag(obj, tag);
+ if (secondTag != null) {
+ interceptor = lookupInterceptor(
+ hasOwnPropertyFunction, secondTag, interceptorsByTag);
+ }
+ }
+ if (interceptor == null) {
+ // TODO(sra): Think about the error case.
+ interceptor = JS('', '{__what: "interceptor not found", __tag: #}', tag);
+ }
+ var isLeaf = JS('', '#[#]', leafTags, tag);
+ if (true == isLeaf) {
+ return makeDispatchRecord(interceptor, false, null);
+ } else {
+ var proto = JS('', 'Object.getPrototypeOf(#)', obj);
+ return makeDispatchRecord(interceptor, proto, null);
+ }
+}
+
+lookupInterceptor(var hasOwnPropertyFunction, String tag, var methods) {
var method = lookupDynamicClass(hasOwnPropertyFunction, methods, tag);
// Look at the inheritance data, getting the class tags and using them
// to check the methods table for this method name.
@@ -314,148 +335,6 @@
return method;
}
-// For each method name and class inheritance subtree, we use an ordinary JS
-// object as a hash map to store the method for each class. Entries are added
-// in native_emitter.dart (see dynamicName). In order to avoid the class names
-// clashing with the method names on Object.prototype (needed for native
-// objects) we must always use hasOwnProperty.
-lookupDynamicClass(var hasOwnPropertyFunction,
- var methods,
- String className) {
- return callHasOwnProperty(hasOwnPropertyFunction, methods, className) ?
- propertyGet(methods, className) :
- null;
-}
-
-/**
- * Code for doing the dynamic dispatch on JavaScript prototypes that are not
- * available at compile-time. Each property of a native Dart class
- * is registered through this function, which is called with the
- * following pattern:
- *
- * dynamicFunction('propertyName').prototypeName = // JS code
- *
- * What this function does is:
- * - Creates a map of { prototypeName: JS code }.
- * - Attaches 'propertyName' to the JS Object prototype that will
- * intercept at runtime all calls to propertyName.
- * - Sets the value of 'propertyName' to the returned method from
- * [dynamicBind].
- *
- */
-dynamicFunction(name) {
- var table = dynamicFunctionTable;
- if (table == null) {
- dynamicFunctionTable = table = JS('=Object', '{}');
- }
-
- var f = JS('var', '#[#]', table, name);
- if (f != null && JS('bool', '!!#.methods', f)) {
- return JS('var', '#.methods', f);
- }
-
- // TODO(ngeoffray): We could make this a map if the code we
- // generate plays well with a Dart map.
- var methods = JS('=Object', '{}');
-
- var bind = JS('var',
- 'function() {'
- 'return #(this, #, #, Array.prototype.slice.call(arguments));'
- '}',
- DART_CLOSURE_TO_JS(dynamicBind), name, methods);
-
- JS('void', '#.methods = #', bind, methods);
- // Install dispatch function on `Object.prototype`, so that `x.name()` will
- // initially enter the dispatch code for any object.
- defineProperty(JS('var', 'Object.prototype'), name, bind);
- // Install dispatch function in table, so it can be called without relying on
- // patching on the line above.
- defineProperty(table, name, bind);
- return methods;
-}
-
-/**
- * Table of dispatch _bind_ functions created by [dynamicFunction].
- *
- * methodName -> dispatchFunction
- */
-var dynamicFunctionTable;
-
-
-/**
- * Associates a tag of a leaf native class (with no subclasses) with the
- * interceptor for that class. Called from generated code.
- */
-void defineNativeMethods(String tag, interceptorClass) {
- var methods = JS('', '#.prototype', interceptorClass);
- var method = dispatchPropertyName;
- JS('void', '#[#]=#', dynamicFunction(method), tag,
- _unguardedConstantJSFunction(methods));
-}
-
-/**
- * Associates a tag of a native class with subclasses with the interceptor for
- * that class. Called from generated code.
- */
-void defineNativeMethodsNonleaf(String tag, interceptorClass) {
- var methods = JS('', '#.prototype', interceptorClass);
- var method = dispatchPropertyName;
- JS('void', '#[#]=#', dynamicFunction(method), tag,
- _guardedConstantJSFunction(method, methods));
-}
-
-void defineNativeMethodsFinish() {
- // Replace dispatch hook on Object.prototype with one that returns an
- // interceptor for JavaScript objects. This avoids needing a test in every
- // interceptor, and prioritizes the performance of known native classes over
- // unknown.
- JS('void', 'Object.prototype[#]=#', dispatchPropertyName,
- _guardedConstantJSFunctionForObject(dispatchPropertyName,
- JS('', 'Object.getPrototypeOf(#)', const Interceptor())));
-}
-
-/**
- * Returns a JavaScript function that returns [value].
- */
-_unguardedConstantJSFunction(var value) {
- return JS('', 'function(){return #}', value);
-}
-
-/**
- * Returns a JavaScript function that returns [value] when called from a patched
- * prototype, and calls the dispatch hook when called from an unpatched
- * prototype.
- */
-_guardedConstantJSFunction(String name, var value) {
- return JS('',
- 'function(){'
- 'if(Object.getPrototypeOf(this).hasOwnProperty(#))'
- 'return #;'
- 'return #(#,this);'
- '}',
- name,
- value,
- RAW_DART_FUNCTION_REF(_redispatchGetNativeInterceptorHook), name);
-}
-
-_redispatchGetNativeInterceptorHook(name, receiver) {
- return JS('', '#[#].call(#)', dynamicFunctionTable, name, receiver);
-}
-
-_guardedConstantJSFunctionForObject(String name, var value) {
- var objectPrototype = JS('', 'Object.prototype');
- return JS('',
- 'function(){'
- 'if (Object.getPrototypeOf(this) === #)'
- 'return #;'
- 'return #(#,this);'
- '}',
- objectPrototype,
- value,
- RAW_DART_FUNCTION_REF(_redispatchGetNativeInterceptorHook), name);
-}
-
-
/**
* This class encodes the class hierarchy when we need it for dynamic
* dispatch.
diff --git a/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
index bdd5d23..f8243c5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
@@ -114,7 +114,7 @@
}
}
-class _AllMatchesIterable extends Iterable<Match> {
+class _AllMatchesIterable extends IterableBase<Match> {
final JSSyntaxRegExp _re;
final String _str;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index c86321f..17f40f6 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -265,11 +265,9 @@
compiler.librariesToAnalyzeWhenRun = libraries;
bool success = compiler.run(null);
if (success && !compilationFailed) {
- return new Future<MirrorSystem>.immediate(
- new Dart2JsMirrorSystem(compiler));
+ return new Future<MirrorSystem>.value(new Dart2JsMirrorSystem(compiler));
} else {
- return new Future<MirrorSystem>.immediateError(
- 'Failed to create mirror system.');
+ return new Future<MirrorSystem>.error('Failed to create mirror system.');
}
}
@@ -1626,7 +1624,7 @@
Future<InstanceMirror> operator[](int index) {
if (index < 0) throw new RangeError('Negative index');
if (index >= _constant.length) throw new RangeError('Index out of bounds');
- return new Future<InstanceMirror>.immediate(
+ return new Future<InstanceMirror>.value(
_convertConstantToInstanceMirror(mirrors, _constant.entries[index]));
}
}
@@ -1663,7 +1661,7 @@
Future<InstanceMirror> operator[](String key) {
int index = _list.indexOf(key);
if (index == -1) return null;
- return new Future<InstanceMirror>.immediate(
+ return new Future<InstanceMirror>.value(
_convertConstantToInstanceMirror(mirrors, _constant.values[index]));
}
}
@@ -1709,7 +1707,7 @@
Future<InstanceMirror> getField(String fieldName) {
Constant fieldConstant = _fieldMap[fieldName];
if (fieldConstant != null) {
- return new Future<InstanceMirror>.immediate(
+ return new Future<InstanceMirror>.value(
_convertConstantToInstanceMirror(mirrors, fieldConstant));
}
return super.getField(fieldName);
@@ -1745,13 +1743,13 @@
Future<InstanceMirror> getField(String fieldName) {
if (fieldName == 'isDocComment') {
- return new Future.immediate(
+ return new Future.value(
new Dart2JsBoolConstantMirror.fromBool(mirrors, isDocComment));
} else if (fieldName == 'text') {
- return new Future.immediate(
+ return new Future.value(
new Dart2JsStringConstantMirror.fromString(mirrors, text));
} else if (fieldName == 'trimmedText') {
- return new Future.immediate(
+ return new Future.value(
new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText));
}
// TODO(johnniwinther): Which exception/error should be thrown here?
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
index 2a2c1fe..41a085e 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
@@ -4,7 +4,7 @@
library mirrors_util;
-import 'dart:collection' show Queue;
+import 'dart:collection' show Queue, IterableBase;
// TODO(rnystrom): Use "package:" URL (#4968).
import 'mirrors.dart';
@@ -55,7 +55,7 @@
throw new Exception('Unexpected owner: ${owner}');
}
-class HierarchyIterable extends Iterable<ClassMirror> {
+class HierarchyIterable extends IterableBase<ClassMirror> {
final bool includeType;
final ClassMirror type;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index c8598e8..9504271 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -2013,7 +2013,7 @@
{'className': currentClass, 'memberName': name});
// We still need to register the invocation, because we might
// call [:super.noSuchMethod:] that does a
- // [:InvocationMirror.invokeOn:].
+ // [:Invocation.invokeOn:].
world.registerDynamicInvocation(selector.name, selector);
compiler.backend.registerSuperNoSuchMethod(mapping);
}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
index 92fcdc5..4ae62ed 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
@@ -5,7 +5,7 @@
/**
* An abstract string representation.
*/
-abstract class ByteString extends Iterable<int> implements SourceString {
+abstract class ByteString extends IterableBase<int> implements SourceString {
final List<int> bytes;
final int offset;
final int length;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
index aa85287..262a64b 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
@@ -7,7 +7,7 @@
/**
* A keyword in the Dart programming language.
*/
-class Keyword extends Iterable<int> implements SourceString {
+class Keyword extends IterableBase<int> implements SourceString {
static const List<Keyword> values = const <Keyword> [
const Keyword("assert"),
const Keyword("break"),
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
index e3cd591..8bdf120 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
@@ -4,7 +4,7 @@
library scanner;
-import 'dart:collection' show LinkedHashMap;
+import 'dart:collection' show LinkedHashMap, IterableBase;
import 'dart:uri';
import 'scanner_implementation.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
index 5d1a42a..e898f41 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
@@ -53,7 +53,7 @@
}
}
-class SubstringWrapper extends Iterable<int> implements SourceString {
+class SubstringWrapper extends IterableBase<int> implements SourceString {
final String internalString;
final int begin;
final int end;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index fcf4e87..23b4f78 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -185,7 +185,7 @@
String slowToString() => value.slowToString();
}
-abstract class SourceString extends Iterable<int> {
+abstract class SourceString extends IterableBase<int> {
const factory SourceString(String string) = StringWrapper;
void printOn(StringBuffer sb);
@@ -205,7 +205,7 @@
bool isPrivate();
}
-class StringWrapper extends Iterable<int> implements SourceString {
+class StringWrapper extends IterableBase<int> implements SourceString {
final String stringValue;
const StringWrapper(String this.stringValue);
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 4157fc9..b75ba4a 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -20,7 +20,7 @@
var file = (new File(filename)).openSync();
var length = file.lengthSync();
var buffer = new List<int>(length);
- var bytes = file.readListSync(buffer, 0, length);
+ var bytes = file.readIntoSync(buffer, 0, length);
file.closeSync();
return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
}
@@ -45,7 +45,7 @@
dartCharactersRead += source.length;
sourceFiles[resourceUri.toString()] =
new SourceFile(relativize(cwd, resourceUri, isWindows), source);
- return new Future.immediate(source);
+ return new Future.value(source);
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index d32bfb3..97c585c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1138,7 +1138,6 @@
}
PartialFunctionElement function = element;
- if (function == backend.getInterceptorMethod) return false;
bool canBeInlined = backend.canBeInlined[function];
if (canBeInlined == false) return false;
if (!selector.applies(function, compiler)) return false;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index e201af0..936ad61 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -89,33 +89,6 @@
}
}
-// Stop-gap until the core classes have such a class.
-class OrderedSet<T> {
- final LinkedHashMap<T, bool> map = new LinkedHashMap<T, bool>();
-
- void add(T x) {
- if (!map.containsKey(x)) {
- map[x] = true;
- }
- }
-
- bool contains(T x) => map.containsKey(x);
-
- bool remove(T x) => map.remove(x) != null;
-
- bool get isEmpty => map.isEmpty;
-
- void forEach(f) => map.keys.forEach(f);
-
- T get first {
- var iterator = map.keys.iterator;
- if (!iterator.moveNext()) throw new StateError("No elements");
- return iterator.current;
- }
-
- get length => map.length;
-}
-
typedef void ElementAction(Element element);
abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
@@ -168,7 +141,7 @@
* we do this most of the time, because it reduces the size unless there
* is only one variable.
*/
- final OrderedSet<String> collectedVariableDeclarations;
+ final LinkedHashSet<String> collectedVariableDeclarations;
/**
* Set of variables and parameters that have already been declared.
@@ -188,7 +161,7 @@
SsaCodeGenerator(this.backend, CodegenWorkItem work)
: this.work = work,
declaredLocals = new Set<String>(),
- collectedVariableDeclarations = new OrderedSet<String>(),
+ collectedVariableDeclarations = new LinkedHashSet<String>(),
currentContainer = new js.Block.empty(),
parameters = <js.Parameter>[],
expressionStack = <js.Expression>[],
@@ -261,7 +234,7 @@
}
void insertStatementAtStart(js.Statement statement) {
- currentContainer.statements.insertRange(0, 1, statement);
+ currentContainer.statements.insert(0, statement);
}
/**
@@ -857,6 +830,7 @@
inits.add(new js.VariableInitialization(declaration,
assignment.value));
collectedVariableDeclarations.remove(id);
+ declaredLocals.add(id);
}
jsInitialization = new js.VariableDeclarationList(inits);
}
@@ -1743,23 +1717,22 @@
}
pushStatement(new js.LiteralStatement(code), node);
} else {
- // We can parse simple JS with the mini parser. At the moment we can't
- // handle expression interpolation with # and we can't handle JSON
- // literals and function literals, both of which contain "{".
- if (!code.contains("#") && !code.contains("{")) {
- js.Expression codeAst = js.js(code);
- push(codeAst, node);
- if (!inputs.isEmpty) {
- compiler.internalError("Too many arguments to JS expression",
- instruction: node);
- }
- } else {
- List<js.Expression> data = <js.Expression>[];
+ List<js.Expression> interpolatedExpressions;
+ if (!inputs.isEmpty) {
+ interpolatedExpressions = <js.Expression>[];
for (int i = 0; i < inputs.length; i++) {
use(inputs[i]);
- data.add(pop());
+ interpolatedExpressions.add(pop());
}
- push(new js.LiteralExpression.withData(code, data), node);
+ }
+ // We can parse simple JS with the mini parser. At the moment we can't
+ // handle JSON literals and function literals, both of which contain "{".
+ if (!code.contains("{") && !code.startsWith("throw ")) {
+ js.Expression codeAst = js.js(code, interpolatedExpressions);
+ push(codeAst, node);
+ } else {
+ push(new js.LiteralExpression.withData(code, interpolatedExpressions),
+ node);
}
}
registerForeignType(node.instructionType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 745f489..fdea257 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -659,7 +659,7 @@
if (index == dominatedBlocks.length) {
dominatedBlocks.add(block);
} else {
- dominatedBlocks.insertRange(index, 1, block);
+ dominatedBlocks.insert(index, block);
}
assert(block.dominator == null);
block.dominator = this;
@@ -673,7 +673,7 @@
if (index == dominatedBlocks.length - 1) {
dominatedBlocks.removeLast();
} else {
- dominatedBlocks.removeRange(index, 1);
+ dominatedBlocks.removeRange(index, index + 1);
}
assert(identical(block.dominator, this));
block.dominator = null;
diff --git a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
index 3b1b210..3b0c2fb 100644
--- a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
@@ -6,7 +6,7 @@
import 'dart:io';
import 'dart:typeddata';
-
+import 'dart:collection';
import 'dart:utf';
import '../elements/elements.dart';
@@ -164,7 +164,7 @@
try {
int size = file.lengthSync();
List<int> bytes = new Uint8List(size + 1);
- file.readListSync(bytes, 0, size);
+ file.readIntoSync(bytes, 0, size);
bytes[size] = $EOF;
threw = false;
return bytes;
diff --git a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
index 2166f7d..8f962ad 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
@@ -11,7 +11,7 @@
* representing its content after removing quotes and resolving escapes in
* its source.
*/
-abstract class DartString extends Iterable<int> {
+abstract class DartString extends IterableBase<int> {
factory DartString.empty() => const LiteralDartString("");
// This is a convenience constructor. If you need a const literal DartString,
// use [const LiteralDartString(string)] directly.
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 4f265f0..13ea311 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -212,7 +212,7 @@
* [: (A, D) :], [: (B, C) :] and finally [: (B, D) :].
*/
class ConcreteTypeCartesianProduct
- extends Iterable<ConcreteTypesEnvironment> {
+ extends IterableBase<ConcreteTypesEnvironment> {
final ConcreteTypesInferrer inferrer;
final ClassElement typeOfThis;
final Map<Element, ConcreteType> concreteTypes;
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 48c6c1c..35965c0 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -4,7 +4,7 @@
library types;
-import 'dart:collection' show Queue;
+import 'dart:collection' show Queue, IterableBase;
import '../dart2jslib.dart' hide Selector;
import '../js_backend/js_backend.dart' show JavaScriptBackend;
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index d3f93ca..614b657 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -4,7 +4,7 @@
part of org_dartlang_compiler_util;
-class Link<T> extends Iterable<T> {
+class Link<T> extends IterableBase<T> {
T get head => null;
Link<T> get tail => null;
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 9d4056a..c9c0e66 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -4,6 +4,7 @@
library org_dartlang_compiler_util;
+import "dart:collection";
import 'util_implementation.dart';
import 'characters.dart';
diff --git a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
index d898f59..1f9d63f 100644
--- a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
+++ b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
@@ -82,11 +82,11 @@
new Conversation(request, request.response).handle();
}
- static onError(AsyncError e) {
- if (e.error is HttpParserException) {
- print('Error: ${e.error.message}');
+ static onError(error) {
+ if (error is HttpParserException) {
+ print('Error: ${error.message}');
} else {
- print('Error: ${e.error}');
+ print('Error: ${error}');
}
}
@@ -116,7 +116,7 @@
print('HTTP server started on http://$host:${server.port}/');
server.listen(Conversation.onRequest, onError: Conversation.onError);
}).catchError((e) {
- print("HttpServer.bind error: ${e.error}");
+ print("HttpServer.bind error: $e");
exit(1);
});
}
diff --git a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
index 9190f31..47eb828 100644
--- a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
@@ -39,7 +39,7 @@
final argParser = new ArgParser();
- final Path libPath = scriptDir.append('../../../../');
+ Path libPath = scriptDir.append('../../../../');
String packageRoot;
@@ -172,6 +172,14 @@
}
});
+ argParser.addOption('library-root',
+ help: 'Sets the library root directory to the specified directory.',
+ callback: (libraryRoot) {
+ if (libraryRoot != null) {
+ libPath = new Path(libraryRoot);
+ }
+ });
+
// TODO(amouravski): This method is deprecated. Remove on April 22.
argParser.addOption('pkg',
help: 'Deprecated: same as --package-root.',
@@ -243,6 +251,8 @@
})
.catchError((e) {
print('Error: generation failed: ${e}');
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
dartdoc.cleanup();
exit(1);
})
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 38d1706..b20f3cb 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -126,7 +126,7 @@
}
},
onDone: () => completer.complete(),
- onError: (e) => completer.completeError(e.error, e.stackTrace));
+ onError: (e) => completer.completeError(e));
return completer.future;
}
@@ -149,7 +149,7 @@
void _compileScript() {
port.receive((message, replyTo) {
- new Future.of(() {
+ new Future.sync(() {
var clientScript = (message['mode'] == MODE_STATIC) ?
'static' : 'live-nav';
var dartPath = pathos.join(message['libPath'], 'lib', '_internal',
@@ -163,8 +163,10 @@
});
}).then((_) {
replyTo.send(['success']);
- }).catchError((e) {
- replyTo.send(['error', e.error.toString(), e.stackTrace.toString()]);
+ }).catchError((error) {
+ var trace = getAttachedStackTrace(error);
+ var traceString = trace == null ? "" : trace.toString();
+ replyTo.send(['error', error.toString(), traceString]);
});
});
}
diff --git a/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
index e197b0b..90455c0 100755
--- a/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
@@ -54,7 +54,8 @@
// TODO(jacobr): this code works only because futures for mirrors return
// immediately.
for(String memberName in members) {
- var result = deprecatedFutureValue(mirror.getFieldAsync(memberName));
+ var result =
+ deprecatedFutureValue(mirror.getFieldAsync(new Symbol(memberName)));
_serialize(memberName, result.reflectee, printer);
}
printer.endObject();
@@ -62,19 +63,25 @@
void determineAllMembers(ClassMirror classMirror,
List<String> members) {
- for(String getterName in classMirror.getters.keys) {
- if (!members.contains(getterName)) {
- members.add(getterName);
+ for(Symbol getterName in classMirror.getters.keys) {
+ if (!members.contains(MirrorSystem.getName(getterName))) {
+ members.add(MirrorSystem.getName(getterName));
}
}
- for(String fieldName in classMirror.variables.keys) {
- if (!members.contains(fieldName)) {
- members.add(fieldName);
+ for(Symbol fieldName in classMirror.variables.keys) {
+ if (!members.contains(MirrorSystem.getName(fieldName))) {
+ members.add(MirrorSystem.getName(fieldName));
}
}
if (classMirror.superclass != null &&
+
+ // TODO(ahe): What is this test for? Consider removing it,
+ // dart2js will issue an error if there is a cycle in superclass
+ // hierarchy.
classMirror.superclass.qualifiedName != classMirror.qualifiedName &&
- classMirror.superclass.qualifiedName != 'dart.core.Object') {
+
+ MirrorSystem.getName(classMirror.superclass.qualifiedName) !=
+ 'dart.core.Object') {
determineAllMembers(classMirror.superclass, members);
}
}
diff --git a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
index 26c9484..d3ec7ae 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
@@ -80,8 +80,7 @@
syntaxes = defaultSyntaxes;
}
// Custom link resolver goes after the generic text syntax.
- syntaxes.insertRange(1, 1,
- new LinkSyntax(linkResolver: document.linkResolver));
+ syntaxes.insert(1, new LinkSyntax(linkResolver: document.linkResolver));
}
List<Node> parse() {
@@ -388,7 +387,7 @@
// Remove the unmatched children.
final unmatchedTags = parser._stack.sublist(index + 1);
- parser._stack.removeRange(index + 1, parser._stack.length - index - 1);
+ parser._stack.removeRange(index + 1, parser._stack.length);
// Flatten them out onto this tag.
for (final unmatched in unmatchedTags) {
diff --git a/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart b/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart
deleted file mode 100644
index 0025791..0000000
--- a/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-library fake_package;
-class FakePackage {
-
-}
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index d5f8a46..f41f2253 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -119,7 +119,9 @@
"_collection-dev": const LibraryInfo(
"_collection_dev/collection_dev.dart",
category: "Internal",
- documented: false),
+ documented: false,
+ dart2jsPatchPath:
+ "_internal/compiler/implementation/lib/collection_dev_patch.dart"),
"_js_helper": const LibraryInfo(
"_internal/compiler/implementation/lib/js_helper.dart",
diff --git a/sdk/lib/async/async_error.dart b/sdk/lib/async/async_error.dart
index fa90e87..05fbb88b2 100644
--- a/sdk/lib/async/async_error.dart
+++ b/sdk/lib/async/async_error.dart
@@ -4,70 +4,24 @@
part of dart.async;
-/**
- * Error result of an asynchronous computation.
- */
-class AsyncError {
- /** The actual error thrown by the computation. */
- final error;
- /** Stack trace corresponding to the error, if available. */
- final Object stackTrace;
- /** Asynchronous error leading to this error, if error handling fails. */
- final AsyncError cause;
+final Expando _stackTraceExpando = new Expando("asynchronous error");
- // TODO(lrn): When possible, combine into one constructor with both optional
- // positional and named arguments.
- AsyncError(this.error, [this.stackTrace]): cause = null;
- AsyncError.withCause(this.error, this.stackTrace, this.cause);
-
- void _writeOn(StringSink buffer) {
- buffer.write("'");
- String message;
- try {
- message = error.toString();
- } catch (e) {
- message = Error.safeToString(error);
- }
- buffer.write(message);
- buffer.write("'\n");
- if (stackTrace != null) {
- buffer.write("Stack trace:\n");
- buffer.writeln(stackTrace.toString());
- }
- }
-
- String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.write("AsyncError: ");
- _writeOn(buffer);
- AsyncError cause = this.cause;
- while (cause != null) {
- buffer.write("Caused by: ");
- cause._writeOn(buffer);
- cause = cause.cause;
- }
- return buffer.toString();
- }
-
- throwDelayed() {
- reportError() {
- print("Uncaught Error: $error");
- if (stackTrace != null) {
- print("Stack Trace:\n$stackTrace\n");
- }
- }
-
- try {
- Timer.run(() {
- reportError();
- // TODO(floitsch): we potentially want to call the global error handler
- // directly so that we can pass the stack trace.
- throw error;
- });
- } catch (e) {
- // Unfortunately there is not much more we can do...
- reportError();
- }
- }
+void _attachStackTrace(o, st) {
+ if (o == null || o is bool || o is num || o is String) return;
+ _stackTraceExpando[o] = st;
}
+/**
+ * *This is an experimental API.*
+ *
+ * Get the [StackTrace] attached to [o].
+ *
+ * If object [o] was thrown and caught in a dart:async method, a [StackTrace]
+ * object was attached to it. Use [getAttachedStackTrace] to get that object.
+ *
+ * Returns [null] if no [StackTrace] was attached.
+ */
+getAttachedStackTrace(o) {
+ if (o == null || o is bool || o is num || o is String) return null;
+ return _stackTraceExpando[o];
+}
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 96bf0cc..7219719 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -25,7 +25,7 @@
* // Invoked when the future is completed with a value.
* return 42; // The successor is completed with the value 42.
* },
- * onError: (AsyncError e) {
+ * onError: (e) {
* // Invoked when the future is completed with an error.
* if (canHandle(e)) {
* return 499; // The successor is completed with the value 499.
@@ -84,31 +84,43 @@
*/
// TODO(floitsch): document chaining.
abstract class Future<T> {
+
/**
- * Creates a future containing the result of calling [function].
+ * Creates a future containing the result of calling [computation]
+ * asynchronously with [runAsync].
*
- * The result of computing [:function():] is either a returned value or
- * a throw.
- *
- * If a value is returned, it becomes the result of the created future.
- *
- * If calling [function] throws, the created [Future] will be completed
- * with an async error containing the thrown value and a captured
- * stacktrace.
- *
- * However, if the result of calling [function] is already an asynchronous
- * result, we treat it specially.
+ * if the result of executing [computation] throws, the returned future is
+ * completed with the error. If a thrown value is an [AsyncError], it is used
+ * directly, instead of wrapping this error again in another [AsyncError].
*
* If the returned value is itself a [Future], completion of
* the created future will wait until the returned future completes,
* and will then complete with the same result.
*
- * If a thrown value is an [AsyncError], it is used directly as the result
- * of the created future.
+ * If a value is returned, it becomes the result of the created future.
*/
- factory Future.of(function()) {
+ factory Future(computation()) {
+ _ThenFuture<dynamic, T> future =
+ new _ThenFuture<dynamic, T>((_) => computation());
+ runAsync(() => future._sendValue(null));
+ return future;
+ }
+
+ /**
+ * Creates a future containing the result of immediately calling
+ * [computation].
+ *
+ * if the result of executing [computation] throws, the returned future is
+ * completed with the error. If a thrown value is an [AsyncError], it is used
+ * directly, instead of wrapping this error again in another [AsyncError].
+ *
+ * If the returned value is itself a [Future], completion of
+ * the created future will wait until the returned future completes,
+ * and will then complete with the same result.
+ */
+ factory Future.sync(computation()) {
try {
- var result = function();
+ var result = computation();
return new _FutureImpl<T>().._setOrChainValue(result);
} catch (error, stackTrace) {
return new _FutureImpl<T>.immediateError(error, stackTrace);
@@ -119,18 +131,18 @@
* A future whose value is available in the next event-loop iteration.
*
* If [value] is not a [Future], using this constructor is equivalent
- * to [:new Future.of(() => value):].
+ * to [:new Future.sync(() => value):].
*
* See [Completer] to create a Future and complete it later.
*/
- factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
+ factory Future.value([T value]) => new _FutureImpl<T>.immediate(value);
/**
* A future that completes with an error in the next event-loop iteration.
*
* See [Completer] to create a Future and complete it later.
*/
- factory Future.immediateError(var error, [Object stackTrace]) {
+ factory Future.error(var error, [Object stackTrace]) {
return new _FutureImpl<T>.immediateError(error, stackTrace);
}
@@ -187,7 +199,7 @@
Iterator iterator = input.iterator;
void nextElement(_) {
if (iterator.moveNext()) {
- new Future.of(() => f(iterator.current))
+ new Future.sync(() => f(iterator.current))
.then(nextElement, onError: doneSignal._setError);
} else {
doneSignal._setValue(null);
@@ -207,9 +219,7 @@
* [this] completes with an error).
*
* If the invoked callback throws an exception, the returned future `f` is
- * completed with the error. If the value thrown is an [AsyncError], it is
- * used directly, as the error result. Otherwise it is wrapped in an
- * [AsyncError] first.
+ * completed with the error.
*
* If the invoked callback returns a [Future] `f2` then `f` and `f2` are
* chained. That is, `f` is completed with the completion value of `f2`.
@@ -221,7 +231,7 @@
* with a `test` parameter, instead of handling both value and error in a
* single [then] call.
*/
- Future then(onValue(T value), { onError(AsyncError asyncError) });
+ Future then(onValue(T value), { onError(Object error) });
/**
* Handles errors emitted by this [Future].
@@ -233,8 +243,8 @@
*
* When [this] completes with an error, [test] is called with the
* error's value. If the invocation returns [true], [onError] is called with
- * the error wrapped in an [AsyncError]. The result of [onError] is handled
- * exactly the same as for [then]'s [onError].
+ * the error. The result of [onError] is handled exactly the same as for
+ * [then]'s [onError].
*
* If [test] returns false, the exception is not handled by [onError], but is
* thrown unmodified, thus forwarding it to `f`.
@@ -250,12 +260,12 @@
*
* This method is equivalent to:
*
- * Future catchError(onError(AsyncError asyncError),
- * {bool test(Object error)}) {
+ * Future catchError(onError(error),
+ * {bool test(error)}) {
* this.then((v) => v, // Forward the value.
* // But handle errors, if the [test] succeeds.
- * onError: (AsyncError e) {
- * if (test == null || test(e.error)) {
+ * onError: (e) {
+ * if (test == null || test(e)) {
* return onError(e);
* }
* throw e;
@@ -263,7 +273,7 @@
* }
*
*/
- Future catchError(onError(AsyncError asyncError),
+ Future catchError(onError(Object error),
{bool test(Object error)});
/**
@@ -295,7 +305,7 @@
* if (f2 is Future) return f2.then((_) => v);
* return v
* },
- * onError: (AsyncError e) {
+ * onError: (e) {
* var f2 = action();
* if (f2 is Future) return f2.then((_) { throw e; });
* throw e;
@@ -352,12 +362,6 @@
* while trying to produce a value.
*
* The argument [exception] should not be `null`.
- *
- * If [exception] is an [AsyncError], it is used directly as the error
- * message sent to the future's listeners, and [stackTrace] is ignored.
- *
- * Otherwise the [exception] and an optional [stackTrace] is combined into an
- * [AsyncError] and sent to this future's listeners.
*/
void completeError(Object exception, [Object stackTrace]);
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index c793d8f..3660b9f 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -7,7 +7,6 @@
deprecatedFutureValue(_FutureImpl future) =>
future._isComplete ? future._resultOrListeners : null;
-
class _CompleterImpl<T> implements Completer<T> {
final Future<T> future;
bool _isComplete = false;
@@ -24,14 +23,12 @@
void completeError(Object error, [Object stackTrace = null]) {
if (_isComplete) throw new StateError("Future already completed");
_isComplete = true;
- AsyncError asyncError;
- if (error is AsyncError) {
- asyncError = error;
- } else {
- asyncError = new AsyncError(error, stackTrace);
+ if (stackTrace != null) {
+ // Force the stack trace onto the error, even if it already had one.
+ _attachStackTrace(error, stackTrace);
}
_FutureImpl future = this.future;
- future._setError(asyncError);
+ future._setError(error);
}
bool get isCompleted => _isComplete;
@@ -51,7 +48,7 @@
return new _FutureListenerWrapper(future);
}
void _sendValue(T value);
- void _sendError(AsyncError error);
+ void _sendError(error);
}
/** Adapter for a [_FutureImpl] to be a future result listener. */
@@ -60,7 +57,7 @@
_FutureListener _nextListener;
_FutureListenerWrapper(this.future);
_sendValue(T value) { future._setValue(value); }
- _sendError(AsyncError error) { future._setError(error); }
+ _sendError(error) { future._setError(error); }
}
class _FutureImpl<T> implements Future<T> {
@@ -85,7 +82,7 @@
/**
* Either the result, or a list of listeners until the future completes.
*
- * The result of the future is either a value or an [AsyncError].
+ * The result of the future is either a value or an error.
* A result is only stored when the future has completed.
*
* The listeners is an internally linked list of [_FutureListener]s.
@@ -104,13 +101,11 @@
}
_FutureImpl.immediateError(var error, [Object stackTrace]) {
- AsyncError asyncError;
- if (error is AsyncError) {
- asyncError = error;
- } else {
- asyncError = new AsyncError(error, stackTrace);
+ if (stackTrace != null) {
+ // Force stack trace onto error, even if it had already one.
+ _attachStackTrace(error, stackTrace);
}
- _setError(asyncError);
+ _setError(error);
}
factory _FutureImpl.wait(Iterable<Future> futures) {
@@ -121,7 +116,7 @@
void handleError(error) {
if (values != null) {
values = null;
- completer.completeError(error.error, error.stackTrace);
+ completer.completeError(error);
}
}
// As each future completes, put its value into the corresponding
@@ -139,14 +134,14 @@
});
}
if (remaining == 0) {
- return new Future.immediate(const []);
+ return new Future.value(const []);
}
values = new List(remaining);
completer = new Completer<List>();
return completer.future;
}
- Future then(f(T value), { onError(AsyncError error) }) {
+ Future then(f(T value), { onError(error) }) {
if (!_isComplete) {
if (onError == null) {
return new _ThenFuture(f).._subscribeTo(this);
@@ -167,7 +162,7 @@
}
}
- Future catchError(f(AsyncError asyncError), { bool test(error) }) {
+ Future catchError(f(error), { bool test(error) }) {
if (_hasValue) {
return new _FutureWrapper(this);
}
@@ -190,7 +185,7 @@
} else {
assert(_hasError);
_clearUnhandledError();
- AsyncError error = _resultOrListeners;
+ var error = _resultOrListeners;
Timer.run(() {
whenFuture._sendError(error);
});
@@ -208,10 +203,10 @@
}
/** Handle a late listener on a completed future with an error. */
- Future _handleError(onError(AsyncError error), bool test(error)) {
+ Future _handleError(onError(error), bool test(error)) {
assert(_hasError);
_clearUnhandledError();
- AsyncError error = _resultOrListeners;
+ var error = _resultOrListeners;
_CatchErrorFuture errorFuture = new _CatchErrorFuture(onError, test);
Timer.run(() { errorFuture._sendError(error); });
return errorFuture;
@@ -232,7 +227,7 @@
}
}
- void _setError(AsyncError error) {
+ void _setError(error) {
if (_isComplete) throw new StateError("Future already completed");
_FutureListener listeners = _removeListeners();
_state = _ERROR;
@@ -257,12 +252,13 @@
if (_hasUnhandledError) {
// No error handler has been added since the error was set.
_clearUnhandledError();
- AsyncError error = _resultOrListeners;
- print("Uncaught Error: ${error.error}");
- if (error.stackTrace != null) {
- print("Stack Trace:\n${error.stackTrace}\n");
+ var error = _resultOrListeners;
+ print("Uncaught Error: ${error}");
+ var trace = getAttachedStackTrace(error);
+ if (trace != null) {
+ print("Stack Trace:\n$trace\n");
}
- throw error.error;
+ throw error;
}
});
}
@@ -351,7 +347,7 @@
void _sendValue(S value);
- void _sendError(AsyncError error);
+ void _sendError(error);
void _subscribeTo(_FutureImpl future) {
future._addListener(this);
@@ -360,7 +356,7 @@
/** The onValue and onError handlers return either a value or a future */
typedef dynamic _FutureOnValue<T>(T value);
-typedef dynamic _FutureOnError(AsyncError error);
+typedef dynamic _FutureOnError(error);
/** Test used by [Future.catchError] to handle skip some errors. */
typedef bool _FutureErrorTest(var error);
/** Used by [WhenFuture]. */
@@ -379,17 +375,14 @@
var result;
try {
result = _onValue(value);
- } on AsyncError catch (e) {
- _setError(e);
- return;
} catch (e, s) {
- _setError(new AsyncError(e, s));
+ _setError(_asyncError(e, s));
return;
}
_setOrChainValue(result);
}
- void _sendError(AsyncError error) {
+ void _sendError(error) {
_setError(error);
}
}
@@ -405,16 +398,16 @@
_setValue(value);
}
- _sendError(AsyncError error) {
+ _sendError(error) {
assert(_onError != null);
// if _test is supplied, check if it returns true, otherwise just
// forward the error unmodified.
if (_test != null) {
bool matchesTest;
try {
- matchesTest = _test(error.error);
+ matchesTest = _test(error);
} catch (e, s) {
- _setError(new AsyncError.withCause(e, s, error));
+ _setError(_asyncError(e, s));
return;
}
if (!matchesTest) {
@@ -426,11 +419,8 @@
var result;
try {
result = _onError(error);
- } on AsyncError catch (e) {
- _setError(e);
- return;
} catch (e, s) {
- _setError(new AsyncError.withCause(e, s, error));
+ _setError(_asyncError(e, s));
return;
}
_setOrChainValue(result);
@@ -445,16 +435,13 @@
// The _sendValue method is inherited from ThenFuture.
- void _sendError(AsyncError error) {
+ void _sendError(error) {
assert(_onError != null);
var result;
try {
result = _onError(error);
- } on AsyncError catch (e) {
- _setError(e);
- return;
} catch (e, s) {
- _setError(new AsyncError.withCause(e, s, error));
+ _setError(_asyncError(e, s));
return;
}
_setOrChainValue(result);
@@ -477,17 +464,14 @@
}, onError: _setError);
return;
}
- } on AsyncError catch (e) {
- _setError(e);
- return;
} catch (e, s) {
- _setError(new AsyncError(e, s));
+ _setError(_asyncError(e, s));
return;
}
_setValue(value);
}
- void _sendError(AsyncError error) {
+ void _sendError(error) {
try {
var result = _action();
if (result is Future) {
@@ -498,10 +482,8 @@
}, onError: _setError);
return;
}
- } on AsyncError catch (e) {
- error = e;
} catch (e, s) {
- error = new AsyncError.withCause(e, s, error);
+ error = _asyncError(e, s);
}
_setError(error);
}
@@ -519,11 +501,11 @@
_FutureWrapper(this._future);
- Future then(function(T value), { onError(AsyncError error) }) {
+ Future then(function(T value), { onError(error) }) {
return _future.then(function, onError: onError);
}
- Future catchError(function(AsyncError error), {bool test(var error)}) {
+ Future catchError(function(error), {bool test(var error)}) {
return _future.catchError(function, test: test);
}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 7da4451..62174c8 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -115,30 +115,28 @@
}
controller = new StreamController<T>(
- onPauseStateChange: () {
- if (controller.isPaused) {
- timer.cancel();
- timer = null;
- watch.stop();
- } else {
- assert(timer == null);
- Duration elapsed = watch.elapsed;
- watch.start();
- timer = new Timer(period - elapsed, () {
- timer = null;
- startPeriodicTimer();
- sendEvent();
- });
- }
+ onListen: () {
+ watch.start();
+ startPeriodicTimer();
},
- onSubscriptionStateChange: () {
- if (controller.hasListener) {
- watch.start();
- startPeriodicTimer();
- } else {
- if (timer != null) timer.cancel();
+ onPause: () {
+ timer.cancel();
+ timer = null;
+ watch.stop();
+ },
+ onResume: () {
+ assert(timer == null);
+ Duration elapsed = watch.elapsed;
+ watch.start();
+ timer = new Timer(period - elapsed, () {
timer = null;
- }
+ startPeriodicTimer();
+ sendEvent();
+ });
+ },
+ onCancel: () {
+ if (timer != null) timer.cancel();
+ timer = null;
});
return controller.stream;
}
@@ -170,17 +168,17 @@
* is called. If [onData] is null, nothing happens.
*
* On errors from this stream, the [onError] handler is given a
- * [AsyncError] object describing the error.
+ * object describing the error.
*
* If this stream closes, the [onDone] handler is called.
*
- * If [unsubscribeOnError] is true, the subscription is ended when
+ * If [cancelOnError] is true, the subscription is ended when
* the first error is reported. The default is false.
*/
StreamSubscription<T> listen(void onData(T event),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError});
+ bool cancelOnError});
/**
* Creates a new stream from this stream that discards some data events.
@@ -217,7 +215,7 @@
* [Stream.transformEvent] to handle the event by writing a data event to
* the output sink
*/
- Stream<T> handleError(void handle(AsyncError error), { bool test(error) }) {
+ Stream<T> handleError(void handle( error), { bool test(error) }) {
return new _HandleErrorStream<T>(this, handle, test);
}
@@ -237,9 +235,7 @@
* Binds this stream as the input of the provided [StreamConsumer].
*/
Future pipe(StreamConsumer<T> streamConsumer) {
- // TODO(floitsch): switch to:
- // streamConsumer.addStream(this).then((_) => streamConsumer.close());
- return streamConsumer.consume(this);
+ return streamConsumer.addStream(this).then((_) => streamConsumer.close());
}
/**
@@ -275,12 +271,12 @@
onError: result._setError,
onDone: () {
if (!seenFirst) {
- result._setError(new AsyncError(new StateError("No elements")));
+ result._setError(new StateError("No elements"));
} else {
result._setValue(value);
}
},
- unsubscribeOnError: true
+ cancelOnError: true
);
return result;
}
@@ -300,13 +296,13 @@
_cancelAndError(subscription, result)
);
},
- onError: (AsyncError e) {
+ onError: (e) {
result._setError(e);
},
onDone: () {
result._setValue(value);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return result;
}
@@ -338,7 +334,7 @@
onDone: () {
future._setValue(false);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -370,7 +366,7 @@
onDone: () {
future._setValue(true);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -402,7 +398,7 @@
onDone: () {
future._setValue(false);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -417,7 +413,7 @@
onDone: () {
future._setValue(count);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -434,7 +430,7 @@
onDone: () {
future._setValue(true);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -452,7 +448,7 @@
onDone: () {
future._setValue(result);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -470,7 +466,7 @@
onDone: () {
future._setValue(result);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -550,9 +546,9 @@
},
onError: future._setError,
onDone: () {
- future._setError(new AsyncError(new StateError("No elements")));
+ future._setError(new StateError("No elements"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -579,9 +575,9 @@
future._setValue(result);
return;
}
- future._setError(new AsyncError(new StateError("No elements")));
+ future._setError(new StateError("No elements"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -603,7 +599,7 @@
subscription.cancel();
// This is the second element we get.
Error error = new StateError("More than one element");
- future._setError(new AsyncError(error));
+ future._setError(error);
return;
}
foundResult = true;
@@ -615,9 +611,9 @@
future._setValue(result);
return;
}
- future._setError(new AsyncError(new StateError("No elements")));
+ future._setError(new StateError("No elements"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -659,10 +655,9 @@
_runUserCode(defaultValue, future._setValue, future._setError);
return;
}
- future._setError(
- new AsyncError(new StateError("firstMatch ended without match")));
+ future._setError(new StateError("firstMatch ended without match"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -703,10 +698,9 @@
_runUserCode(defaultValue, future._setValue, future._setError);
return;
}
- future._setError(
- new AsyncError(new StateError("lastMatch ended without match")));
+ future._setError(new StateError("lastMatch ended without match"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -731,8 +725,8 @@
if (isMatch) {
if (foundResult) {
subscription.cancel();
- future._setError(new AsyncError(
- new StateError('Multiple matches for "single"')));
+ future._setError(
+ new StateError('Multiple matches for "single"'));
return;
}
foundResult = true;
@@ -748,10 +742,9 @@
future._setValue(result);
return;
}
- future._setError(
- new AsyncError(new StateError("single ended without match")));
+ future._setError(new StateError("single ended without match"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
@@ -780,10 +773,9 @@
},
onError: future._setError,
onDone: () {
- future._setError(new AsyncError(
- new StateError("Not enough elements for elementAt")));
+ future._setError(new StateError("Not enough elements for elementAt"));
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return future;
}
}
@@ -809,7 +801,7 @@
void onData(void handleData(T data));
/** Set or override the error event handler of this subscription. */
- void onError(void handleError(AsyncError error));
+ void onError(void handleError(error));
/** Set or override the done event handler of this subscription. */
void onDone(void handleDone());
@@ -832,6 +824,20 @@
* Resume after a pause.
*/
void resume();
+
+ /**
+ * Returns a future that handles the [onDone] and [onError] callbacks.
+ *
+ * This method *overwrites* the existing [onDone] and [onError] callbacks
+ * with new ones that complete the returned future.
+ *
+ * In case of an error the subscription will automatically cancel (even
+ * when it was listening with `cancelOnError` set to `false`).
+ *
+ * In case of a `done` event the future completes with the given
+ * [futureValue].
+ */
+ Future asFuture([var futureValue]);
}
@@ -842,7 +848,7 @@
/** Create a data event */
void add(T event);
/** Create an async error. */
- void addError(AsyncError errorEvent);
+ void addError(errorEvent);
/** Request a stream to close. */
void close();
}
@@ -859,24 +865,24 @@
Stream<T> asBroadcastStream() => _stream.asBroadcastStream();
StreamSubscription<T> listen(void onData(T value),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError }) {
+ bool cancelOnError }) {
return _stream.listen(onData, onError: onError, onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
}
/**
* [EventSink] wrapper that only exposes the [EventSink] interface.
*/
-class EventSinkView<T> extends EventSink<T> {
+class _EventSinkView<T> extends EventSink<T> {
final EventSink<T> _sink;
- EventSinkView(this._sink);
+ _EventSinkView(this._sink);
void add(T value) { _sink.add(value); }
- void addError(AsyncError error) { _sink.addError(error); }
+ void addError(error) { _sink.addError(error); }
void close() { _sink.close(); }
}
@@ -891,12 +897,41 @@
abstract class StreamConsumer<S> {
Future addStream(Stream<S> stream);
Future close();
+}
+/**
+ * A [StreamSink] unifies the asynchronous methods from [StreamConsumer<S>] and
+ * the synchronous methods from [EventSink<S>].
+ *
+ * The [EventSink<S>] methods can't be used while the [addStream] is called.
+ * As soon as the [addStream]'s [Future] completes with a value, the
+ * [EventSink<S>] methods can be used again.
+ *
+ * If [addStream] is called after any of the [EventSink<S>] methods, it'll
+ * be delayed until the underlying system has consumed the data added by the
+ * [EventSink<S>] methods.
+ *
+ * When [EventSink<S>] methods are used, the [done] [Future] can be used to
+ * catch any errors.
+ *
+ * When [close] is called, it will return the [done] [Future].
+ */
+abstract class StreamSink<S> implements StreamConsumer<S>, EventSink<S> {
+ /**
+ * Close the [StreamSink<S>]. It'll return the [done] Future.
+ */
+ Future close();
+
/**
- * Consume is deprecated. Use [addStream] followed by [close] instead.
+ * The [done] Future completes with the same values as [close], except
+ * for the following case:
+ *
+ * * The synchronous methods of [EventSink<S>] were called, resulting in an
+ * error. If there is no active future (like from an addStream call), the
+ * [done] future will complete with that error
*/
- Future consume(Stream<S> stream);
+ Future get done;
}
@@ -926,7 +961,7 @@
*/
factory StreamTransformer({
void handleData(S data, EventSink<T> sink),
- void handleError(AsyncError error, EventSink<T> sink),
+ void handleError(error, EventSink<T> sink),
void handleDone(EventSink<T> sink)}) {
return new _StreamTransformerImpl<S, T>(handleData,
handleError,
@@ -973,23 +1008,15 @@
StreamController controller;
StreamSubscription subscription;
controller = new StreamController<T>(
- onPauseStateChange: () {
- if (controller.isPaused) {
- subscription.pause();
- } else {
- subscription.resume();
- }
+ onListen: () {
+ subscription = transformingStream.listen(
+ controller.add,
+ onError: controller.addError,
+ onDone: controller.close);
},
- onSubscriptionStateChange: () {
- if (controller.hasListener) {
- subscription = transformingStream.listen(
- controller.add,
- onError: controller.addError,
- onDone: controller.close);
- } else {
- subscription.cancel();
- }
- });
+ onPause: () => subscription.pause(),
+ onResume: () => subscription.resume(),
+ onCancel: () => subscription.cancel());
return controller.stream;
}
@@ -1010,7 +1037,7 @@
* The method may generate any number of events on the sink, but should
* not throw.
*/
- void handleError(AsyncError error, EventSink<T> sink) {
+ void handleError(error, EventSink<T> sink) {
sink.addError(error);
}
@@ -1042,13 +1069,13 @@
: _source = source, _transformer = transformer;
StreamSubscription<T> listen(void onData(T data),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError }) {
- unsubscribeOnError = identical(true, unsubscribeOnError);
+ bool cancelOnError }) {
+ cancelOnError = identical(true, cancelOnError);
return new _EventTransformStreamSubscription(_source, _transformer,
onData, onError, onDone,
- unsubscribeOnError);
+ cancelOnError);
}
}
@@ -1058,7 +1085,7 @@
/** The transformer used to transform events. */
final StreamEventTransformer<S, T> _transformer;
/** Whether to unsubscribe when emitting an error. */
- final bool _unsubscribeOnError;
+ final bool _cancelOnError;
/** Whether this stream has sent a done event. */
bool _isClosed = false;
/** Source of incoming events. */
@@ -1069,9 +1096,9 @@
_EventTransformStreamSubscription(Stream<S> source,
this._transformer,
void onData(T data),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- this._unsubscribeOnError)
+ this._cancelOnError)
: super(onData, onError, onDone) {
_sink = new _EventOutputSinkWrapper<T>(this);
_subscription = source.listen(_handleData,
@@ -1107,11 +1134,11 @@
}
}
- void _handleError(AsyncError error) {
+ void _handleError(error) {
try {
_transformer.handleError(error, _sink);
} catch (e, s) {
- _sendError(_asyncError(e, s, error));
+ _sendError(_asyncError(e, s));
}
}
@@ -1130,10 +1157,10 @@
_onData(data);
}
- void _sendError(AsyncError error) {
+ void _sendError(error) {
if (_isClosed) return;
_onError(error);
- if (_unsubscribeOnError) {
+ if (_cancelOnError) {
cancel();
}
}
@@ -1154,6 +1181,6 @@
_EventOutputSinkWrapper(this._sink);
void add(T data) { _sink._sendData(data); }
- void addError(AsyncError error) { _sink._sendError(error); }
+ void addError(error) { _sink._sendError(error); }
void close() { _sink._sendDone(); }
}
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 24a9999..3e7dbdc 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -50,44 +50,37 @@
final _StreamImpl<T> stream;
/**
- * A controller with a broadcast [stream]..
*
- * The [onPauseStateChange] function is called when the stream becomes
- * paused or resumes after being paused. The current pause state can
- * be read from [isPaused]. Ignored if [:null:].
- *
- * The [onSubscriptionStateChange] function is called when the stream
- * receives its first listener or loses its last. The current subscription
- * state can be read from [hasListener]. Ignored if [:null:].
- */
- StreamController.broadcast({void onPauseStateChange(),
- void onSubscriptionStateChange()})
- : stream = new _MultiControllerStream<T>(onSubscriptionStateChange,
- onPauseStateChange);
-
- /**
+ * If the stream is canceled before the controller needs new data the
+ * [onResume] call might not be executed.
+ : stream = new _MultiControllerStream<T>(
+ onListen, onPause, onResume, onCancel);
* A controller with a [stream] that supports only one single subscriber.
*
* The controller will buffer all incoming events until the subscriber is
* registered.
*
- * The [onPauseStateChange] function is called when the stream becomes
- * paused or resumes after being paused. The current pause state can
- * be read from [isPaused]. Ignored if [:null:].
+ * The [onPause] function is called when the stream becomes
+ * paused. [onResume] is called when the stream resumed.
*
- * The [onSubscriptionStateChange] function is called when the stream
- * receives its first listener or loses its last. The current subscription
- * state can be read from [hasListener]. Ignored if [:null:].
+ * The [onListen] callback is called when the stream
+ * receives its listener. [onCancel] when the listener cancels
+ * its subscription.
+ *
+ * If the stream is canceled before the controller needs new data the
+ * [onResume] call might not be executed.
*/
- StreamController({void onPauseStateChange(),
- void onSubscriptionStateChange()})
- : stream = new _SingleControllerStream<T>(onSubscriptionStateChange,
- onPauseStateChange);
+ StreamController({void onListen(),
+ void onPause(),
+ void onResume(),
+ void onCancel()})
+ : stream = new _SingleControllerStream<T>(
+ onListen, onPause, onResume, onCancel);
/**
* Returns a view of this object that only exposes the [EventSink] interface.
*/
- EventSink<T> get sink => new EventSinkView<T>(this);
+ EventSink<T> get sink => new _EventSinkView<T>(this);
/**
* Whether the stream is closed for adding more events.
@@ -111,23 +104,16 @@
/**
* Send or enqueue an error event.
*
- * If [error] is not an [AsyncError], [error] and an optional [stackTrace]
- * is combined into an [AsyncError] and sent this stream's listeners.
- *
- * Otherwise, if [error] is an [AsyncError], it is used directly as the
- * error object reported to listeners, and the [stackTrace] is ignored.
- *
* If a subscription has requested to be unsubscribed on errors,
* it will be unsubscribed after receiving this event.
*/
void addError(Object error, [Object stackTrace]) {
- AsyncError asyncError;
- if (error is AsyncError) {
- asyncError = error;
- } else {
- asyncError = new AsyncError(error, stackTrace);
+ if (stackTrace != null) {
+ // Force stack trace overwrite. Even if the error already contained
+ // a stack trace.
+ _attachStackTrace(error, stackTrace);
}
- stream._addError(asyncError);
+ stream._addError(error);
}
/**
@@ -141,56 +127,32 @@
typedef void _NotificationHandler();
-class _MultiControllerStream<T> extends _MultiStreamImpl<T> {
- _NotificationHandler _subscriptionHandler;
- _NotificationHandler _pauseHandler;
-
- _MultiControllerStream(this._subscriptionHandler, this._pauseHandler);
-
- void _onSubscriptionStateChange() {
- if (_subscriptionHandler != null) {
- try {
- _subscriptionHandler();
- } catch (e, s) {
- new AsyncError(e, s).throwDelayed();
- }
- }
- }
-
- void _onPauseStateChange() {
- if (_pauseHandler != null) {
- try {
- _pauseHandler();
- } catch (e, s) {
- new AsyncError(e, s).throwDelayed();
- }
- }
- }
-}
-
class _SingleControllerStream<T> extends _SingleStreamImpl<T> {
- _NotificationHandler _subscriptionHandler;
- _NotificationHandler _pauseHandler;
+ _NotificationHandler _onListen;
+ _NotificationHandler _onPause;
+ _NotificationHandler _onResume;
+ _NotificationHandler _onCancel;
- _SingleControllerStream(this._subscriptionHandler, this._pauseHandler);
-
- void _onSubscriptionStateChange() {
- if (_subscriptionHandler != null) {
- try {
- _subscriptionHandler();
- } catch (e, s) {
- new AsyncError(e, s).throwDelayed();
- }
+ // TODO(floitsch): share this code with _MultiControllerStream.
+ _runGuarded(_NotificationHandler notificationHandler) {
+ if (notificationHandler == null) return;
+ try {
+ notificationHandler();
+ } catch (e, s) {
+ _throwDelayed(e, s);
}
}
+ _SingleControllerStream(this._onListen,
+ this._onPause,
+ this._onResume,
+ this._onCancel);
+
+ void _onSubscriptionStateChange() {
+ _runGuarded(_hasListener ? _onListen : _onCancel);
+ }
+
void _onPauseStateChange() {
- if (_pauseHandler != null) {
- try {
- _pauseHandler();
- } catch (e, s) {
- new AsyncError(e, s).throwDelayed();
- }
- }
+ _runGuarded(_isPaused ? _onPause : _onResume);
}
}
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index e6de3d7..8fa1848 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -55,6 +55,20 @@
/// state, shifted by this amount.
const int _LISTENER_PAUSE_COUNT_SHIFT = 3;
+/** Throws the given error in the next cycle. */
+_throwDelayed(var error, [Object stackTrace]) {
+ // We are going to reach the top-level here, but there might be a global
+ // exception handler. This means that we shouldn't print the stack trace.
+ // TODO(floitsch): Find better solution that doesn't print the stack trace
+ // if there is a global exception handler.
+ runAsync(() {
+ if (stackTrace != null) print(stackTrace);
+ var trace = getAttachedStackTrace(error);
+ if (trace != null && trace != stackTrace) print(trace);
+ throw error;
+ });
+}
+
// -------------------------------------------------------------------
// Common base class for single and multi-subscription streams.
@@ -77,18 +91,18 @@
// Stream interface.
StreamSubscription<T> listen(void onData(T data),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError }) {
+ bool cancelOnError }) {
if (_isComplete) {
return new _DoneSubscription(onDone);
}
if (onData == null) onData = _nullDataHandler;
if (onError == null) onError = _nullErrorHandler;
if (onDone == null) onDone = _nullDoneHandler;
- unsubscribeOnError = identical(true, unsubscribeOnError);
+ cancelOnError = identical(true, cancelOnError);
_StreamSubscriptionImpl subscription =
- _createSubscription(onData, onError, onDone, unsubscribeOnError);
+ _createSubscription(onData, onError, onDone, cancelOnError);
_addListener(subscription);
return subscription;
}
@@ -123,7 +137,7 @@
* If a subscription has requested to be unsubscribed on errors,
* it will be unsubscribed after receiving this event.
*/
- void _addError(AsyncError error) {
+ void _addError(error) {
if (_isClosed) throw new StateError("Sending on closed stream");
if (!_mayFireState) {
// Not the time to send events.
@@ -374,9 +388,9 @@
/** Create a subscription object. Called by [subcribe]. */
_StreamSubscriptionImpl<T> _createSubscription(
void onData(T data),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- bool unsubscribeOnError);
+ bool cancelOnError);
/**
* Adds a listener to this stream.
@@ -493,10 +507,8 @@
_forEachSubscriber((subscriber) {
try {
subscriber._sendData(value);
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError(e, s).throwDelayed();
+ _throwDelayed(e, s);
}
});
}
@@ -504,17 +516,15 @@
/**
* Sends an error event directly to each subscriber.
*/
- void _sendError(AsyncError error) {
+ void _sendError(error) {
assert(!_isPaused);
assert(!_isComplete);
if (!_hasListener) return;
_forEachSubscriber((subscriber) {
try {
subscriber._sendError(error);
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError.withCause(e, s, error).throwDelayed();
+ _throwDelayed(e, s);
}
});
}
@@ -533,10 +543,8 @@
_cancel(subscriber);
try {
subscriber._sendDone();
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError(e, s).throwDelayed();
+ _throwDelayed(e, s);
}
});
assert(!_hasListener);
@@ -592,11 +600,11 @@
*/
_StreamSubscriptionImpl<T> _createSubscription(
void onData(T data),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- bool unsubscribeOnError) {
+ bool cancelOnError) {
return new _StreamSubscriptionImpl<T>(
- this, onData, onError, onDone, unsubscribeOnError);
+ this, onData, onError, onDone, cancelOnError);
}
void _addListener(_StreamListener subscription) {
@@ -712,11 +720,11 @@
*/
_StreamListener<T> _createSubscription(
void onData(T data),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- bool unsubscribeOnError) {
+ bool cancelOnError) {
return new _StreamSubscriptionImpl<T>(
- this, onData, onError, onDone, unsubscribeOnError);
+ this, onData, onError, onDone, cancelOnError);
}
// -------------------------------------------------------------------
@@ -841,7 +849,7 @@
throw new UnsupportedError("Cannot inject events into generated stream");
}
- void _addError(AsyncError value) {
+ void _addError(value) {
throw new UnsupportedError("Cannot inject events into generated stream");
}
@@ -876,7 +884,7 @@
stream._sendDone();
}
} catch (e, s) {
- stream._sendError(new AsyncError(e, s));
+ stream._sendError(_asyncError(e, s));
stream._sendDone();
_isDone = true;
}
@@ -901,7 +909,7 @@
*/
class _StreamSubscriptionImpl<T> extends _StreamListener<T>
implements StreamSubscription<T> {
- final bool _unsubscribeOnError;
+ final bool _cancelOnError;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
var /* _DataHandler<T> */ _onData;
@@ -911,14 +919,14 @@
this._onData,
this._onError,
this._onDone,
- this._unsubscribeOnError) : super(source);
+ this._cancelOnError) : super(source);
void onData(void handleData(T event)) {
if (handleData == null) handleData = _nullDataHandler;
_onData = handleData;
}
- void onError(void handleError(AsyncError error)) {
+ void onError(void handleError(error)) {
if (handleError == null) handleError = _nullErrorHandler;
_onError = handleError;
}
@@ -932,9 +940,9 @@
_onData(data);
}
- void _sendError(AsyncError error) {
+ void _sendError(error) {
_onError(error);
- if (_unsubscribeOnError) _source._cancel(this);
+ if (_cancelOnError) _source._cancel(this);
}
void _sendDone() {
@@ -955,13 +963,26 @@
if (!_isSubscribed || !isPaused) return;
_source._resume(this, false);
}
+
+ Future asFuture([var futureValue]) {
+ _FutureImpl<T> result = new _FutureImpl<T>();
+
+ // Overwrite the onDone and onError handlers.
+ onDone(() { result._setValue(futureValue); });
+ onError((error) {
+ cancel();
+ result._setError(error);
+ });
+
+ return result;
+ }
}
// Internal helpers.
// Types of the different handlers on a stream. Types used to type fields.
typedef void _DataHandler<T>(T value);
-typedef void _ErrorHandler(AsyncError error);
+typedef void _ErrorHandler(error);
typedef void _DoneHandler();
@@ -969,8 +990,8 @@
void _nullDataHandler(var value) {}
/** Default error handler, reports the error to the global handler. */
-void _nullErrorHandler(AsyncError error) {
- error.throwDelayed();
+void _nullErrorHandler(error) {
+ _throwDelayed(error);
}
/** Default done handler, does nothing. */
@@ -987,7 +1008,7 @@
/** A delayed data event. */
class _DelayedData<T> extends _DelayedEvent{
- T value;
+ final T value;
_DelayedData(this.value);
void perform(_StreamImpl<T> stream) {
stream._sendData(value);
@@ -996,7 +1017,7 @@
/** A delayed error event. */
class _DelayedError extends _DelayedEvent {
- AsyncError error;
+ final error;
_DelayedError(this.error);
void perform(_StreamImpl stream) {
stream._sendError(error);
@@ -1100,7 +1121,7 @@
/** Abstract type for an internal interface for sending events. */
abstract class _EventOutputSink<T> {
_sendData(T data);
- _sendError(AsyncError error);
+ _sendError(error);
_sendDone();
}
@@ -1175,7 +1196,7 @@
}
_sendData(T data);
- _sendError(AsyncError error);
+ _sendError(error);
_sendDone();
}
@@ -1263,7 +1284,7 @@
void onData(void handleAction(T value)) {}
- void onError(void handleError(AsyncError error)) {}
+ void onError(void handleError(error)) {}
void onDone(void handleDone()) {
_handler = handleDone;
@@ -1298,6 +1319,20 @@
}
_pauseCount = 0;
}
+
+ Future asFuture([var futureValue]) {
+ // TODO(floitsch): share more code.
+ _FutureImpl<T> result = new _FutureImpl<T>();
+
+ // Overwrite the onDone and onError handlers.
+ onDone(() { result._setValue(futureValue); });
+ onError((error) {
+ cancel();
+ result._setError(error);
+ });
+
+ return result;
+ }
}
class _SingleStreamMultiplexer<T> extends _MultiStreamImpl<T> {
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index aa3da2a..4e40a61 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -4,36 +4,29 @@
part of dart.async;
-/** Utility function to create an [AsyncError] if [error] isn't one already. */
-AsyncError _asyncError(Object error, Object stackTrace, [AsyncError cause]) {
- if (error is AsyncError) return error;
- if (cause == null) return new AsyncError(error, stackTrace);
- return new AsyncError.withCause(error, stackTrace, cause);
+/**
+ * Utility function to attach a stack trace to an [error] if it doesn't have
+ * one already.
+ */
+_asyncError(Object error, Object stackTrace) {
+ if (stackTrace == null) return error;
+ if (getAttachedStackTrace(error) != null) return error;
+ _attachStackTrace(error, stackTrace);
+ return error;
}
/** Runs user code and takes actions depending on success or failure. */
-_runUserCode(userCode(), onSuccess(value), onError(AsyncError error),
- { AsyncError cause }) {
- var result;
+_runUserCode(userCode(), onSuccess(value), onError(error)) {
try {
- result = userCode();
- } on AsyncError catch (e) {
- return onError(e);
+ onSuccess(userCode());
} catch (e, s) {
- if (cause == null) {
- onError(new AsyncError(e, s));
- } else {
- onError(new AsyncError.withCause(e, s, cause));
- }
- // onError is allowed to return. Don't execute the onSuccess below.
- return;
+ onError(_asyncError(e, s));
}
- onSuccess(result);
}
/** Helper function to make an onError argument to [_runUserCode]. */
_cancelAndError(StreamSubscription subscription, _FutureImpl future) =>
- (AsyncError error) {
+ (error) {
subscription.cancel();
future._setError(error);
};
@@ -56,22 +49,22 @@
bool get isBroadcast => _source.isBroadcast;
StreamSubscription<T> listen(void onData(T value),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError }) {
+ bool cancelOnError }) {
if (onData == null) onData = _nullDataHandler;
if (onError == null) onError = _nullErrorHandler;
if (onDone == null) onDone = _nullDoneHandler;
- unsubscribeOnError = identical(true, unsubscribeOnError);
- return _createSubscription(onData, onError, onDone, unsubscribeOnError);
+ cancelOnError = identical(true, cancelOnError);
+ return _createSubscription(onData, onError, onDone, cancelOnError);
}
StreamSubscription<T> _createSubscription(void onData(T value),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- bool unsubscribeOnError) {
+ bool cancelOnError) {
return new _ForwardingStreamSubscription<S, T>(
- this, onData, onError, onDone, unsubscribeOnError);
+ this, onData, onError, onDone, cancelOnError);
}
// Override the following methods in subclasses to change the behavior.
@@ -81,7 +74,7 @@
sink._sendData(outputData);
}
- void _handleError(AsyncError error, _EventOutputSink<T> sink) {
+ void _handleError(error, _EventOutputSink<T> sink) {
sink._sendError(error);
}
@@ -116,7 +109,7 @@
_onData = handleData;
}
- void onError(void handleError(AsyncError error)) {
+ void onError(void handleError(error)) {
if (handleError == null) handleError = _nullErrorHandler;
_onError = handleError;
}
@@ -131,6 +124,19 @@
void resume();
void cancel();
+
+ Future asFuture([var futureValue]) {
+ _FutureImpl<T> result = new _FutureImpl<T>();
+
+ // Overwrite the onDone and onError handlers.
+ onDone(() { result._setValue(futureValue); });
+ onError((error) {
+ cancel();
+ result._setError(error);
+ });
+
+ return result;
+ }
}
@@ -140,15 +146,15 @@
class _ForwardingStreamSubscription<S, T>
extends _BaseStreamSubscription<T> implements _EventOutputSink<T> {
final _ForwardingStream<S, T> _stream;
- final bool _unsubscribeOnError;
+ final bool _cancelOnError;
StreamSubscription<S> _subscription;
_ForwardingStreamSubscription(this._stream,
void onData(T data),
- void onError(AsyncError error),
+ void onError(error),
void onDone(),
- this._unsubscribeOnError)
+ this._cancelOnError)
: super(onData, onError, onDone) {
// Don't unsubscribe on incoming error, only if we send an error forwards.
_subscription =
@@ -182,9 +188,9 @@
_onData(data);
}
- void _sendError(AsyncError error) {
+ void _sendError(error) {
_onError(error);
- if (_unsubscribeOnError) {
+ if (_cancelOnError) {
_subscription.cancel();
_subscription = null;
}
@@ -207,7 +213,7 @@
_stream._handleData(data, this);
}
- void _handleError(AsyncError error) {
+ void _handleError(error) {
_stream._handleError(error, this);
}
@@ -291,7 +297,7 @@
}
-typedef void _ErrorTransformation(AsyncError error);
+typedef void _ErrorTransformation(error);
typedef bool _ErrorTest(error);
/**
@@ -303,17 +309,17 @@
final _ErrorTest _test;
_HandleErrorStream(Stream<T> source,
- void transform(AsyncError event),
+ void transform(event),
bool test(error))
: this._transform = transform, this._test = test, super(source);
- void _handleError(AsyncError error, _EventOutputSink<T> sink) {
+ void _handleError(Object error, _EventOutputSink<T> sink) {
bool matches = true;
if (_test != null) {
try {
- matches = _test(error.error);
+ matches = _test(error);
} catch (e, s) {
- sink._sendError(_asyncError(e, s, error));
+ sink._sendError(_asyncError(e, s));
return;
}
}
@@ -321,7 +327,7 @@
try {
_transform(error);
} catch (e, s) {
- sink._sendError(_asyncError(e, s, error));
+ sink._sendError(_asyncError(e, s));
return;
}
} else {
@@ -463,7 +469,7 @@
// Stream transformations and event transformations.
typedef void _TransformDataHandler<S, T>(S data, EventSink<T> sink);
-typedef void _TransformErrorHandler<T>(AsyncError data, EventSink<T> sink);
+typedef void _TransformErrorHandler<T>(data, EventSink<T> sink);
typedef void _TransformDoneHandler<T>(EventSink<T> sink);
/** Default data handler forwards all data. */
@@ -472,7 +478,7 @@
}
/** Default error handler forwards all errors. */
-void _defaultHandleError(AsyncError error, EventSink sink) {
+void _defaultHandleError(error, EventSink sink) {
sink.addError(error);
}
@@ -500,7 +506,7 @@
final _TransformDoneHandler<T> _handleDone;
_StreamTransformerImpl(void handleData(S data, EventSink<T> sink),
- void handleError(AsyncError data, EventSink<T> sink),
+ void handleError(data, EventSink<T> sink),
void handleDone(EventSink<T> sink))
: this._handleData = (handleData == null ? _defaultHandleData
: handleData),
@@ -513,7 +519,7 @@
_handleData(data, sink);
}
- void handleError(AsyncError error, EventSink<T> sink) {
+ void handleError(error, EventSink<T> sink) {
_handleError(error, sink);
}
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 8a7fdb0..b321e41 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -46,7 +46,10 @@
* Runs the given [callback] asynchronously as soon as possible.
*/
static void run(void callback()) {
- schedule() {
+ // Optimizing a group of Timer.run callbacks to be executed in the
+ // same Timer callback.
+ _runCallbacks.add(callback);
+ if (_runCallbacks.length == 1) {
new Timer(const Duration(milliseconds: 0), () {
List runCallbacks = _runCallbacks;
// Create new list to make sure we don't call newly added callbacks in
@@ -63,17 +66,11 @@
_runCallbacks.addAll(
runCallbacks.sublist(i));
_runCallbacks.addAll(newCallbacks);
- if (!_runCallbacks.isEmpty) schedule();
throw;
}
}
});
}
-
- // Optimizing a group of Timer.run callbacks to be executed in the
- // same Timer callback.
- _runCallbacks.add(callback);
- if (_runCallbacks.length == 1) schedule();
}
/**
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 0bbd8f2..03287d7 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -7,6 +7,7 @@
import 'dart:_collection-dev';
part 'collections.dart';
+part 'iterable.dart';
part 'iterator.dart';
part 'maps.dart';
part 'queue.dart';
diff --git a/sdk/lib/collection/collection_sources.gypi b/sdk/lib/collection/collection_sources.gypi
index 84259ef..7fe56d8 100644
--- a/sdk/lib/collection/collection_sources.gypi
+++ b/sdk/lib/collection/collection_sources.gypi
@@ -10,6 +10,7 @@
'collections.dart',
'hash_map.dart',
'hash_set.dart',
+ 'iterable.dart',
'iterator.dart',
'linked_hash_map.dart',
'linked_hash_set.dart',
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 400ce90..2f00717 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -5,329 +5,6 @@
part of dart.collection;
/**
- * This class provides default implementations for Iterables (including Lists).
- *
- * Once Dart receives Mixins it will be replaced with mixin classes.
- */
-@deprecated
-class IterableMixinWorkaround {
- static bool contains(Iterable iterable, var element) {
- for (final e in iterable) {
- if (element == e) return true;
- }
- return false;
- }
-
- static void forEach(Iterable iterable, void f(o)) {
- for (final e in iterable) {
- f(e);
- }
- }
-
- static bool any(Iterable iterable, bool f(o)) {
- for (final e in iterable) {
- if (f(e)) return true;
- }
- return false;
- }
-
- static bool every(Iterable iterable, bool f(o)) {
- for (final e in iterable) {
- if (!f(e)) return false;
- }
- return true;
- }
-
- static dynamic reduce(Iterable iterable,
- dynamic combine(previousValue, element)) {
- Iterator iterator = iterable.iterator;
- if (!iterator.moveNext()) throw new StateError("No elements");
- var value = iterator.current;
- while (iterator.moveNext()) {
- value = combine(value, iterator.current);
- }
- return value;
- }
-
- static dynamic fold(Iterable iterable,
- dynamic initialValue,
- dynamic combine(dynamic previousValue, element)) {
- for (final element in iterable) {
- initialValue = combine(initialValue, element);
- }
- return initialValue;
- }
-
- /**
- * Removes elements matching [test] from [list].
- *
- * This is performed in two steps, to avoid exposing an inconsistent state
- * to the [test] function. First the elements to retain are found, and then
- * the original list is updated to contain those elements.
- */
- static void removeWhereList(List list, bool test(var element)) {
- List retained = [];
- int length = list.length;
- for (int i = 0; i < length; i++) {
- var element = list[i];
- if (!test(element)) {
- retained.add(element);
- }
- if (length != list.length) {
- throw new ConcurrentModificationError(list);
- }
- }
- if (retained.length == length) return;
- list.length = retained.length;
- for (int i = 0; i < retained.length; i++) {
- list[i] = retained[i];
- }
- }
-
- static bool isEmpty(Iterable iterable) {
- return !iterable.iterator.moveNext();
- }
-
- static dynamic first(Iterable iterable) {
- Iterator it = iterable.iterator;
- if (!it.moveNext()) {
- throw new StateError("No elements");
- }
- return it.current;
- }
-
- static dynamic last(Iterable iterable) {
- Iterator it = iterable.iterator;
- if (!it.moveNext()) {
- throw new StateError("No elements");
- }
- dynamic result;
- do {
- result = it.current;
- } while(it.moveNext());
- return result;
- }
-
- static dynamic single(Iterable iterable) {
- Iterator it = iterable.iterator;
- if (!it.moveNext()) throw new StateError("No elements");
- dynamic result = it.current;
- if (it.moveNext()) throw new StateError("More than one element");
- return result;
- }
-
- static dynamic firstWhere(Iterable iterable,
- bool test(dynamic value),
- dynamic orElse()) {
- for (dynamic element in iterable) {
- if (test(element)) return element;
- }
- if (orElse != null) return orElse();
- throw new StateError("No matching element");
- }
-
- static dynamic lastWhere(Iterable iterable,
- bool test(dynamic value),
- dynamic orElse()) {
- dynamic result = null;
- bool foundMatching = false;
- for (dynamic element in iterable) {
- if (test(element)) {
- result = element;
- foundMatching = true;
- }
- }
- if (foundMatching) return result;
- if (orElse != null) return orElse();
- throw new StateError("No matching element");
- }
-
- static dynamic lastWhereList(List list,
- bool test(dynamic value),
- dynamic orElse()) {
- // TODO(floitsch): check that arguments are of correct type?
- for (int i = list.length - 1; i >= 0; i--) {
- dynamic element = list[i];
- if (test(element)) return element;
- }
- if (orElse != null) return orElse();
- throw new StateError("No matching element");
- }
-
- static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) {
- dynamic result = null;
- bool foundMatching = false;
- for (dynamic element in iterable) {
- if (test(element)) {
- if (foundMatching) {
- throw new StateError("More than one matching element");
- }
- result = element;
- foundMatching = true;
- }
- }
- if (foundMatching) return result;
- throw new StateError("No matching element");
- }
-
- static dynamic elementAt(Iterable iterable, int index) {
- if (index is! int || index < 0) throw new RangeError.value(index);
- int remaining = index;
- for (dynamic element in iterable) {
- if (remaining == 0) return element;
- remaining--;
- }
- throw new RangeError.value(index);
- }
-
- static String join(Iterable iterable, [String separator]) {
- StringBuffer buffer = new StringBuffer();
- buffer.writeAll(iterable, separator);
- return buffer.toString();
- }
-
- static String joinList(List list, [String separator]) {
- if (list.isEmpty) return "";
- if (list.length == 1) return "${list[0]}";
- StringBuffer buffer = new StringBuffer();
- if (separator.isEmpty) {
- for (int i = 0; i < list.length; i++) {
- buffer.write(list[i]);
- }
- } else {
- buffer.write(list[0]);
- for (int i = 1; i < list.length; i++) {
- buffer.write(separator);
- buffer.write(list[i]);
- }
- }
- return buffer.toString();
- }
-
- static Iterable where(Iterable iterable, bool f(var element)) {
- return new WhereIterable(iterable, f);
- }
-
- static Iterable map(Iterable iterable, f(var element)) {
- return new MappedIterable(iterable, f);
- }
-
- static Iterable mapList(List list, f(var element)) {
- return new MappedListIterable(list, f);
- }
-
- static Iterable expand(Iterable iterable, Iterable f(var element)) {
- return new ExpandIterable(iterable, f);
- }
-
- static Iterable takeList(List list, int n) {
- // The generic type is currently lost. It will be fixed with mixins.
- return new SubListIterable(list, 0, n);
- }
-
- static Iterable takeWhile(Iterable iterable, bool test(var value)) {
- // The generic type is currently lost. It will be fixed with mixins.
- return new TakeWhileIterable(iterable, test);
- }
-
- static Iterable skipList(List list, int n) {
- // The generic type is currently lost. It will be fixed with mixins.
- return new SubListIterable(list, n, null);
- }
-
- static Iterable skipWhile(Iterable iterable, bool test(var value)) {
- // The generic type is currently lost. It will be fixed with mixins.
- return new SkipWhileIterable(iterable, test);
- }
-
- static Iterable reversedList(List list) {
- return new ReversedListIterable(list);
- }
-
- static void sortList(List list, int compare(a, b)) {
- if (compare == null) compare = Comparable.compare;
- Sort.sort(list, compare);
- }
-
- static int indexOfList(List list, var element, int start) {
- return Arrays.indexOf(list, element, start, list.length);
- }
-
- static int lastIndexOfList(List list, var element, int start) {
- if (start == null) start = list.length - 1;
- return Arrays.lastIndexOf(list, element, start);
- }
-
- static Iterable getRangeList(List list, int start, int end) {
- if (start < 0 || start > list.length) {
- throw new RangeError.range(start, 0, list.length);
- }
- if (end < start || end > list.length) {
- throw new RangeError.range(end, start, list.length);
- }
- // The generic type is currently lost. It will be fixed with mixins.
- return new SubListIterable(list, start, end);
- }
-
- static void setRangeList(List list, int start, int length,
- List from, int startFrom) {
- if (length == 0) return;
-
- if (length < 0) throw new ArgumentError(length);
- if (start < 0) throw new RangeError.value(start);
- if (start + length > list.length) {
- throw new RangeError.value(start + length);
- }
-
- Arrays.copy(from, startFrom, list, start, length);
- }
-
- static Map<int, dynamic> asMapList(List l) {
- return new ListMapView(l);
- }
-
- static bool setContainsAll(Set set, Iterable other) {
- for (var element in other) {
- if (!set.contains(element)) return false;
- }
- return true;
- }
-
- static Set setIntersection(Set set, Set other, Set result) {
- Set smaller;
- Set larger;
- if (set.length < other.length) {
- smaller = set;
- larger = other;
- } else {
- smaller = other;
- larger = set;
- }
- for (var element in smaller) {
- if (larger.contains(element)) {
- result.add(element);
- }
- }
- return result;
- }
-
- static Set setUnion(Set set, Set other, Set result) {
- result.addAll(set);
- result.addAll(other);
- return result;
- }
-
- static Set setDifference(Set set, Set other, Set result) {
- for (var element in set) {
- if (!other.contains(element)) {
- result.add(element);
- }
- }
- return result;
- }
-}
-
-/**
* An unmodifiable [List] view of another List.
*
* The source of the elements may be a [List] or any [Iterable] with
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index f658b52..c459f99 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -5,7 +5,7 @@
part of dart.collection;
/** Common parts of [HashSet] and [LinkedHashSet] implementations. */
-abstract class _HashSetBase<E> extends Iterable<E> implements Set<E> {
+abstract class _HashSetBase<E> extends IterableBase<E> implements Set<E> {
// Set.
bool containsAll(Iterable<E> other) {
for (E object in other) {
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
new file mode 100644
index 0000000..2ec143b
--- /dev/null
+++ b/sdk/lib/collection/iterable.dart
@@ -0,0 +1,384 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.collection;
+
+/**
+ * This [Iterable] mixin implements all [Iterable] members except `iterator`.
+ *
+ * All other methods are implemented in terms of `iterator`.
+ */
+abstract class IterableMixin<E> implements Iterable<E> {
+ Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+ Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
+
+ Iterable expand(Iterable f(E element)) =>
+ new ExpandIterable<E, dynamic>(this, f);
+
+ bool contains(E element) {
+ for (E e in this) {
+ if (e == element) return true;
+ }
+ return false;
+ }
+
+ void forEach(void f(E element)) {
+ for (E element in this) f(element);
+ }
+
+ E reduce(E combine(E value, E element)) {
+ Iterator<E> iterator = this.iterator;
+ if (!iterator.moveNext()) {
+ throw new StateError("No elements");
+ }
+ E value = iterator.current;
+ while (iterator.moveNext()) {
+ value = combine(value, iterator.current);
+ }
+ return value;
+ }
+
+ dynamic fold(var initialValue,
+ dynamic combine(var previousValue, E element)) {
+ var value = initialValue;
+ for (E element in this) value = combine(value, element);
+ return value;
+ }
+
+ bool every(bool f(E element)) {
+ for (E element in this) {
+ if (!f(element)) return false;
+ }
+ return true;
+ }
+
+ String join([String separator]) {
+ Iterator<E> iterator = this.iterator;
+ if (!iterator.moveNext()) return "";
+ StringBuffer buffer = new StringBuffer();
+ if (separator == null || separator == "") {
+ do {
+ buffer.write("${iterator.current}");
+ } while (iterator.moveNext());
+ } else {
+ buffer.write("${iterator.current}");
+ while (iterator.moveNext()) {
+ buffer.write(separator);
+ buffer.write("${iterator.current}");
+ }
+ }
+ return buffer.toString();
+ }
+
+ bool any(bool f(E element)) {
+ for (E element in this) {
+ if (f(element)) return true;
+ }
+ return false;
+ }
+
+ List<E> toList({ bool growable: true }) =>
+ new List<E>.from(this, growable: growable);
+
+ Set<E> toSet() => new Set<E>.from(this);
+
+ int get length {
+ int count = 0;
+ Iterator it = iterator;
+ while (it.moveNext()) {
+ count++;
+ }
+ return count;
+ }
+
+ bool get isEmpty => !iterator.moveNext();
+
+ Iterable<E> take(int n) {
+ return new TakeIterable<E>(this, n);
+ }
+
+ Iterable<E> takeWhile(bool test(E value)) {
+ return new TakeWhileIterable<E>(this, test);
+ }
+
+ Iterable<E> skip(int n) {
+ return new SkipIterable<E>(this, n);
+ }
+
+ Iterable<E> skipWhile(bool test(E value)) {
+ return new SkipWhileIterable<E>(this, test);
+ }
+
+ E get first {
+ Iterator it = iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ return it.current;
+ }
+
+ E get last {
+ Iterator it = iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ E result;
+ do {
+ result = it.current;
+ } while(it.moveNext());
+ return result;
+ }
+
+ E get single {
+ Iterator it = iterator;
+ if (!it.moveNext()) throw new StateError("No elements");
+ E result = it.current;
+ if (it.moveNext()) throw new StateError("More than one element");
+ return result;
+ }
+
+ E firstWhere(bool test(E value), { E orElse() }) {
+ // TODO(floitsch): check that arguments are of correct type?
+ for (E element in this) {
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ E lastWhere(bool test(E value), {E orElse()}) {
+ // TODO(floitsch): check that arguments are of correct type?
+ E result = null;
+ bool foundMatching = false;
+ for (E element in this) {
+ if (test(element)) {
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ E singleWhere(bool test(E value)) {
+ // TODO(floitsch): check that argument is of correct type?
+ E result = null;
+ bool foundMatching = false;
+ for (E element in this) {
+ if (test(element)) {
+ if (foundMatching) {
+ throw new StateError("More than one matching element");
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ throw new StateError("No matching element");
+ }
+
+ E elementAt(int index) {
+ if (index is! int || index < 0) throw new RangeError.value(index);
+ int remaining = index;
+ for (E element in this) {
+ if (remaining == 0) return element;
+ remaining--;
+ }
+ throw new RangeError.value(index);
+ }
+}
+
+/**
+ * Base class for implementing [Iterable].
+ *
+ * This class implements all methods of [Iterable] except [Iterable.iterator]
+ * in terms of `iterator`.
+ */
+abstract class IterableBase<E> implements Iterable<E> {
+ // TODO(lrn): Base this on IterableMixin if there ever becomes a way
+ // to combine const constructors and mixins.
+ const IterableBase();
+
+ Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+ Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
+
+ Iterable expand(Iterable f(E element)) =>
+ new ExpandIterable<E, dynamic>(this, f);
+
+ bool contains(E element) {
+ for (E e in this) {
+ if (e == element) return true;
+ }
+ return false;
+ }
+
+ void forEach(void f(E element)) {
+ for (E element in this) f(element);
+ }
+
+ E reduce(E combine(E value, E element)) {
+ Iterator<E> iterator = this.iterator;
+ if (!iterator.moveNext()) {
+ throw new StateError("No elements");
+ }
+ E value = iterator.current;
+ while (iterator.moveNext()) {
+ value = combine(value, iterator.current);
+ }
+ return value;
+ }
+
+ dynamic fold(var initialValue,
+ dynamic combine(var previousValue, E element)) {
+ var value = initialValue;
+ for (E element in this) value = combine(value, element);
+ return value;
+ }
+
+ bool every(bool f(E element)) {
+ for (E element in this) {
+ if (!f(element)) return false;
+ }
+ return true;
+ }
+
+ String join([String separator]) {
+ Iterator<E> iterator = this.iterator;
+ if (!iterator.moveNext()) return "";
+ StringBuffer buffer = new StringBuffer();
+ if (separator == null || separator == "") {
+ do {
+ buffer.write("${iterator.current}");
+ } while (iterator.moveNext());
+ } else {
+ buffer.write("${iterator.current}");
+ while (iterator.moveNext()) {
+ buffer.write(separator);
+ buffer.write("${iterator.current}");
+ }
+ }
+ return buffer.toString();
+ }
+
+ bool any(bool f(E element)) {
+ for (E element in this) {
+ if (f(element)) return true;
+ }
+ return false;
+ }
+
+ List<E> toList({ bool growable: true }) =>
+ new List<E>.from(this, growable: growable);
+
+ Set<E> toSet() => new Set<E>.from(this);
+
+ int get length {
+ int count = 0;
+ Iterator it = iterator;
+ while (it.moveNext()) {
+ count++;
+ }
+ return count;
+ }
+
+ bool get isEmpty => !iterator.moveNext();
+
+ Iterable<E> take(int n) {
+ return new TakeIterable<E>(this, n);
+ }
+
+ Iterable<E> takeWhile(bool test(E value)) {
+ return new TakeWhileIterable<E>(this, test);
+ }
+
+ Iterable<E> skip(int n) {
+ return new SkipIterable<E>(this, n);
+ }
+
+ Iterable<E> skipWhile(bool test(E value)) {
+ return new SkipWhileIterable<E>(this, test);
+ }
+
+ E get first {
+ Iterator it = iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ return it.current;
+ }
+
+ E get last {
+ Iterator it = iterator;
+ if (!it.moveNext()) {
+ throw new StateError("No elements");
+ }
+ E result;
+ do {
+ result = it.current;
+ } while(it.moveNext());
+ return result;
+ }
+
+ E get single {
+ Iterator it = iterator;
+ if (!it.moveNext()) throw new StateError("No elements");
+ E result = it.current;
+ if (it.moveNext()) throw new StateError("More than one element");
+ return result;
+ }
+
+ E firstWhere(bool test(E value), { E orElse() }) {
+ // TODO(floitsch): check that arguments are of correct type?
+ for (E element in this) {
+ if (test(element)) return element;
+ }
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ E lastWhere(bool test(E value), {E orElse()}) {
+ // TODO(floitsch): check that arguments are of correct type?
+ E result = null;
+ bool foundMatching = false;
+ for (E element in this) {
+ if (test(element)) {
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ if (orElse != null) return orElse();
+ throw new StateError("No matching element");
+ }
+
+ E singleWhere(bool test(E value)) {
+ // TODO(floitsch): check that argument is of correct type?
+ E result = null;
+ bool foundMatching = false;
+ for (E element in this) {
+ if (test(element)) {
+ if (foundMatching) {
+ throw new StateError("More than one matching element");
+ }
+ result = element;
+ foundMatching = true;
+ }
+ }
+ if (foundMatching) return result;
+ throw new StateError("No matching element");
+ }
+
+ E elementAt(int index) {
+ if (index is! int || index < 0) throw new RangeError.value(index);
+ int remaining = index;
+ for (E element in this) {
+ if (remaining == 0) return element;
+ remaining--;
+ }
+ throw new RangeError.value(index);
+ }
+}
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 354e59e..ccde096 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -174,6 +174,9 @@
Iterable map(f(E element)) => new MappedListIterable(this, f);
+ Iterable expand(Iterable f(E element)) =>
+ new ExpandIterable<E, dynamic>(this, f);
+
E reduce(E combine(E previousValue, E element)) {
if (length == 0) throw new StateError("No elements");
E value = this[0];
@@ -242,7 +245,7 @@
void remove(Object element) {
for (int i = 0; i < this.length; i++) {
if (this[i] == element) {
- this.setRange(i, this.length - i - 1, this, i + 1);
+ this.setRange(i, i + this.length - 1, this, i + 1);
this.length -= 1;
return;
}
@@ -298,14 +301,18 @@
return new ListMapView(this);
}
- List<E> sublist(int start, [int end]) {
- if (end == null) end = length;
+ void _rangeCheck(int start, int end) {
if (start < 0 || start > this.length) {
throw new RangeError.range(start, 0, this.length);
}
if (end < start || end > this.length) {
throw new RangeError.range(end, start, this.length);
}
+ }
+
+ List<E> sublist(int start, [int end]) {
+ if (end == null) end = length;
+ _rangeCheck(start, end);
int length = end - start;
List<E> result = new List<E>()..length = length;
for (int i = 0; i < length; i++) {
@@ -315,73 +322,62 @@
}
Iterable<E> getRange(int start, int end) {
- if (start < 0 || start > this.length) {
- throw new RangeError.range(start, 0, this.length);
- }
- if (end < start || end > this.length) {
- throw new RangeError.range(end, start, this.length);
- }
+ _rangeCheck(start, end);
return new SubListIterable(this, start, end);
}
- void insertRange(int start, int length, [E initialValue]) {
- if (start < 0 || start > this.length) {
- throw new RangeError.range(start, 0, this.length);
- }
- int oldLength = this.length;
- int moveLength = oldLength - start;
- this.length += length;
- if (moveLength > 0) {
- this.setRange(start + length, moveLength, this, start);
- }
- for (int i = 0; i < length; i++) {
- this[start + i] = initialValue;
- }
- }
-
- void removeRange(int start, int length) {
- if (start < 0 || start > this.length) {
- throw new RangeError.range(start, 0, this.length);
- }
- if (length < 0 || start + length > this.length) {
- throw new RangeError.range(length, 0, this.length - start);
- }
- int end = start + length;
- setRange(start, this.length - end, this, end);
+ void removeRange(int start, int end) {
+ _rangeCheck(start, end);
+ int length = end - start;
+ setRange(start, this.length - length, this, end);
this.length -= length;
}
- void clearRange(int start, int length, [E fill]) {
- for (int i = 0; i < length; i++) {
- this[start + i] = fill;
+ void fillRange(int start, int end, [E fill]) {
+ _rangeCheck(start, end);
+ for (int i = start; i < end; i++) {
+ this[i] = fill;
}
}
- void setRange(int start, int length, List<E> from, [int startFrom]) {
- if (start < 0 || start > this.length) {
- throw new RangeError.range(start, 0, this.length);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ _rangeCheck(start, end);
+ int length = end - start;
+ if (length == 0) return;
+
+ if (skipCount < 0) throw new ArgumentError(skipCount);
+
+ List otherList;
+ int otherStart;
+ // TODO(floitsch): Make this accept more.
+ if (iterable is List) {
+ otherList = iterable;
+ otherStart = skipCount;
+ } else {
+ otherList = iterable.skip(skipCount).toList(growable: false);
+ otherStart = 0;
}
- if (length < 0 || start + length > this.length) {
- throw new RangeError.range(length, 0, this.length - start);
+ if (otherStart + length > otherList.length) {
+ throw new StateError("Not enough elements");
}
- if (startFrom == null) {
- startFrom = 0;
- }
- if (startFrom < 0 || startFrom + length > from.length) {
- throw new RangeError.range(startFrom, 0, from.length - length);
- }
- if (startFrom < start) {
+ if (otherStart < start) {
// Copy backwards to ensure correct copy if [from] is this.
for (int i = length - 1; i >= 0; i--) {
- this[start + i] = from[startFrom + i];
+ this[start + i] = otherList[otherStart + i];
}
} else {
for (int i = 0; i < length; i++) {
- this[start + i] = from[startFrom + i];
+ this[start + i] = otherList[otherStart + i];
}
}
}
+ void replaceRange(int start, int end, Iterable<E> newContents) {
+ // TODO(floitsch): Optimize this.
+ removeRange(start, end);
+ insertAll(start, newContents);
+ }
+
int indexOf(E element, [int startIndex = 0]) {
if (startIndex >= this.length) {
return -1;
@@ -421,5 +417,58 @@
return -1;
}
+ void insert(int index, E element) {
+ if (index < 0 || index > length) {
+ throw new RangeError.range(index, 0, length);
+ }
+ if (index == this.length) {
+ add(element);
+ return;
+ }
+ // We are modifying the length just below the is-check. Without the check
+ // Array.copy could throw an exception, leaving the list in a bad state
+ // (with a length that has been increased, but without a new element).
+ if (index is! int) throw new ArgumentError(index);
+ this.length++;
+ setRange(index + 1, this.length, this, index);
+ this[index] = element;
+ }
+
+ E removeAt(int index) {
+ E result = this[index];
+ setRange(index, this.length - 1, this, index + 1);
+ length--;
+ return result;
+ }
+
+ void insertAll(int index, Iterable<E> iterable) {
+ if (index < 0 || index > length) {
+ throw new RangeError.range(index, 0, length);
+ }
+ // TODO(floitsch): we can probably detect more cases.
+ if (iterable is! List && iterable is! Set && iterable is! SubListIterable) {
+ iterable = iterable.toList();
+ }
+ int insertionLength = iterable.length;
+ // There might be errors after the length change, in which case the list
+ // will end up being modified but the operation not complete. Unless we
+ // always go through a "toList" we can't really avoid that.
+ this.length += insertionLength;
+ setRange(index + insertionLength, this.length, this, index);
+ setAll(index, iterable);
+ }
+
+ void setAll(int index, Iterable<E> iterable) {
+ if (iterable is List) {
+ setRange(index, index + iterable.length, iterable);
+ } else {
+ for (E element in iterable) {
+ this[index++] = element;
+ }
+ }
+ }
+
Iterable<E> get reversed => new ReversedListIterable(this);
+
+ String toString() => ToString.iterableToString(this);
}
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 85947d0..a66248e 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -160,7 +160,7 @@
*
* Can do [removeAll] and [retainAll] in linear time.
*/
-class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
+class DoubleLinkedQueue<E> extends IterableBase<E> implements Queue<E> {
_DoubleLinkedQueueEntrySentinel<E> _sentinel;
int _elementCount = 0;
@@ -354,7 +354,7 @@
* Operations like [removeAll] and [removeWhere] are very
* inefficient. If those are needed, use a [DoubleLinkedQueue] instead.
*/
-class ListQueue<E> extends Iterable<E> implements Queue<E>{
+class ListQueue<E> extends IterableBase<E> implements Queue<E> {
static const int _INITIAL_CAPACITY = 8;
List<E> _table;
int _head;
@@ -458,17 +458,17 @@
if (length + addCount >= _table.length) {
_preGrow(length + addCount);
// After preGrow, all elements are at the start of the list.
- _table.setRange(length, addCount, list, 0);
+ _table.setRange(length, length + addCount, list, 0);
_tail += addCount;
} else {
// Adding addCount elements won't reach _head.
int endSpace = _table.length - _tail;
if (addCount < endSpace) {
- _table.setRange(_tail, addCount, list, 0);
+ _table.setRange(_tail, _tail + addCount, list, 0);
_tail += addCount;
} else {
int preSpace = addCount - endSpace;
- _table.setRange(_tail, endSpace, list, 0);
+ _table.setRange(_tail, _tail + endSpace, list, 0);
_table.setRange(0, preSpace, list, endSpace);
_tail = preSpace;
}
@@ -653,7 +653,7 @@
List<E> newTable = new List<E>(_table.length * 2);
int split = _table.length - _head;
newTable.setRange(0, split, _table, _head);
- newTable.setRange(split, _head, _table, 0);
+ newTable.setRange(split, split + _head, _table, 0);
_head = 0;
_tail = _table.length;
_table = newTable;
@@ -668,7 +668,7 @@
} else {
int firstPartSize = _table.length - _head;
target.setRange(0, firstPartSize, _table, _head);
- target.setRange(firstPartSize, _tail, _table, 0);
+ target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
return _tail + firstPartSize;
}
}
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 3b83641..1461cc6 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -505,7 +505,7 @@
T _getValue(_SplayTreeNode node);
}
-class _SplayTreeKeyIterable<K> extends Iterable<K> {
+class _SplayTreeKeyIterable<K> extends IterableBase<K> {
_SplayTree<K> _tree;
_SplayTreeKeyIterable(this._tree);
int get length => _tree._count;
@@ -513,7 +513,7 @@
Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree);
}
-class _SplayTreeValueIterable<K, V> extends Iterable<V> {
+class _SplayTreeValueIterable<K, V> extends IterableBase<V> {
SplayTreeMap<K, V> _map;
_SplayTreeValueIterable(this._map);
int get length => _map._count;
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index df5da14..391000c 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -5,7 +5,8 @@
library dart.core;
import "dart:collection";
-import "dart:_collection-dev";
+import "dart:_collection-dev" hide Symbol;
+import "dart:_collection-dev" as _collection_dev;
part "bool.dart";
part "comparable.dart";
@@ -18,7 +19,7 @@
part "function.dart";
part "identical.dart";
part "int.dart";
-part "invocation_mirror.dart";
+part "invocation.dart";
part "iterable.dart";
part "iterator.dart";
part "list.dart";
diff --git a/sdk/lib/core/corelib_sources.gypi b/sdk/lib/core/corelib_sources.gypi
index 10ae786..9d6126fa 100644
--- a/sdk/lib/core/corelib_sources.gypi
+++ b/sdk/lib/core/corelib_sources.gypi
@@ -17,7 +17,7 @@
'function.dart',
'identical.dart',
'int.dart',
- 'invocation_mirror.dart',
+ 'invocation.dart',
'iterable.dart',
'iterator.dart',
'list.dart',
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 9902b82..31daa8f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -22,7 +22,7 @@
static const int FRIDAY = 5;
static const int SATURDAY = 6;
static const int SUNDAY = 7;
- static const int DAYS_IN_WEEK = 7;
+ static const int DAYS_PER_WEEK = 7;
// Month constants that are returned by the [month] getter.
static const int JANUARY = 1;
@@ -37,6 +37,7 @@
static const int OCTOBER = 10;
static const int NOVEMBER = 11;
static const int DECEMBER = 12;
+ static const int MONTHS_PER_YEAR = 12;
/**
* The milliseconds since 1970-01-01T00:00:00Z (UTC). This value is
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index 4653294..2ef7f74 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -21,13 +21,17 @@
* This includes giving the same errors if [function] isn't callable or
* if it expects different parameters.
*
- * Example: [: Function.apply(foo, [1,2,3], {"f": 4, "g": 5}) :] gives
- * exactly the same result as [: foo(1, 2, 3, f: 4, g: 5) :].
+ * Example: [:
+ * Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
+ * namedArguments[const Symbol("f")] = 4;
+ * namedArguments[const Symbol("g")] = 5;
+ * Function.apply(foo, [1,2,3], namedArguments); :]
+ * gives exactly the same result as [: foo(1, 2, 3, f: 4, g: 5) :].
*
* If [positionalArguments] is null, it's considered an empty list.
* If [namedArguments] is omitted or null, it is considered an empty map.
*/
external static apply(Function function,
List positionalArguments,
- [Map<String,dynamic> namedArguments]);
+ [Map<Symbol, dynamic> namedArguments]);
}
diff --git a/sdk/lib/core/invocation_mirror.dart b/sdk/lib/core/invocation.dart
similarity index 97%
rename from sdk/lib/core/invocation_mirror.dart
rename to sdk/lib/core/invocation.dart
index 3b5cda0..2e4dd90 100644
--- a/sdk/lib/core/invocation_mirror.dart
+++ b/sdk/lib/core/invocation.dart
@@ -11,7 +11,7 @@
* an object doesn't support the member invocation that was attempted
* on it.
*/
-abstract class InvocationMirror {
+abstract class Invocation {
/** The name of the invoked member. */
String get memberName;
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index d1583dc..9a0bf6f 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -48,7 +48,7 @@
* multiple times over the the returned [Iterable] will invoke the supplied
* function [f] multiple times on the same element.
*/
- Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+ Iterable map(f(E element));
/**
* Returns a lazy [Iterable] with all elements that satisfy the
@@ -60,8 +60,7 @@
* multiple times over the the returned [Iterable] will invoke the supplied
* function [f] multiple times on the same element.
*/
- Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
-
+ Iterable<E> where(bool f(E element));
/**
* Expand each element of this [Iterable] into zero or more elements.
@@ -72,28 +71,20 @@
* The returned [Iterable] is lazy, and will call [f] for each element
* of this every time it's iterated.
*/
- Iterable expand(Iterable f(E element)) =>
- new ExpandIterable<E, dynamic>(this, f);
+ Iterable expand(Iterable f(E element));
/**
* Check whether the collection contains an element equal to [element].
*/
- bool contains(E element) {
- for (E e in this) {
- if (e == element) return true;
- }
- return false;
- }
+ bool contains(E element);
/**
* Applies the function [f] to each element of this collection.
*/
- void forEach(void f(E element)) {
- for (E element in this) f(element);
- }
+ void forEach(void f(E element));
/**
- * Reduce a collection to a single value by iteratively combining elements
+ * Reduces a collection to a single value by iteratively combining elements
* of the collection using the provided function.
*
* Example of calculating the sum of an iterable:
@@ -101,21 +92,13 @@
* iterable.reduce((value, element) => value + element);
*
*/
- E reduce(E combine(E value, E element)) {
- Iterator<E> iterator = this.iterator;
- if (!iterator.moveNext()) {
- throw new StateError("No elements");
- }
- E value = iterator.current;
- while (iterator.moveNext()) {
- value = combine(value, iterator.current);
- }
- return value;
- }
+ E reduce(E combine(E value, E element));
/**
- * Reduce a collection to a single value by iteratively combining each element
- * of the collection with an existing value using the provided function.
+ * Reduces a collection to a single value by iteratively combining each
+ * element of the collection with an existing value using the provided
+ * function.
+ *
* Use [initialValue] as the initial value, and the function [combine] to
* create a new value from the previous one and an element.
*
@@ -125,25 +108,16 @@
*
*/
dynamic fold(var initialValue,
- dynamic combine(var previousValue, E element)) {
- var value = initialValue;
- for (E element in this) value = combine(value, element);
- return value;
- }
+ dynamic combine(var previousValue, E element));
/**
* Returns true if every elements of this collection satisify the
* predicate [f]. Returns false otherwise.
*/
- bool every(bool f(E element)) {
- for (E element in this) {
- if (!f(element)) return false;
- }
- return true;
- }
+ bool every(bool f(E element));
/**
- * Convert each element to a [String] and concatenate the strings.
+ * Converts each element to a [String] and concatenates the strings.
*
* Converts each element to a [String] by calling [Object.toString] on it.
* Then concatenates the strings, optionally separated by the [separator]
@@ -159,16 +133,20 @@
* Returns true if one element of this collection satisfies the
* predicate [f]. Returns false otherwise.
*/
- bool any(bool f(E element)) {
- for (E element in this) {
- if (f(element)) return true;
- }
- return false;
- }
+ bool any(bool f(E element));
- List<E> toList({ bool growable: true }) =>
- new List<E>.from(this, growable: growable);
- Set<E> toSet() => new Set<E>.from(this);
+ /**
+ * Creates a [List] containing the elements of this [Iterable].
+ *
+ * The elements will be in iteration order. The list is fixed-length
+ * if [growable] is false.
+ */
+ List<E> toList({ bool growable: true });
+
+ /**
+ * Creates a [Set] containing the elements of this [Iterable].
+ */
+ Set<E> toSet();
/**
* Returns the number of elements in [this].
@@ -176,19 +154,12 @@
* Counting all elements may be involve running through all elements and can
* therefore be slow.
*/
- int get length {
- int count = 0;
- Iterator it = iterator;
- while (it.moveNext()) {
- count++;
- }
- return count;
- }
+ int get length;
/**
* Returns true if there is no element in this collection.
*/
- bool get isEmpty => !iterator.moveNext();
+ bool get isEmpty;
/**
* Returns an [Iterable] with at most [n] elements.
@@ -196,9 +167,7 @@
* The returned [Iterable] may contain fewer than [n] elements, if [this]
* contains fewer than [n] elements.
*/
- Iterable<E> take(int n) {
- return new TakeIterable<E>(this, n);
- }
+ Iterable<E> take(int n);
/**
* Returns an [Iterable] that stops once [test] is not satisfied anymore.
@@ -209,9 +178,7 @@
* it discards [:e:] and moves into the finished state. That is, it will not
* ask or provide any more elements.
*/
- Iterable<E> takeWhile(bool test(E value)) {
- return new TakeWhileIterable<E>(this, test);
- }
+ Iterable<E> takeWhile(bool test(E value));
/**
* Returns an [Iterable] that skips the first [n] elements.
@@ -219,9 +186,7 @@
* If [this] has fewer than [n] elements, then the resulting [Iterable] will
* be empty.
*/
- Iterable<E> skip(int n) {
- return new SkipIterable<E>(this, n);
- }
+ Iterable<E> skip(int n);
/**
* Returns an [Iterable] that skips elements while [test] is satisfied.
@@ -232,9 +197,7 @@
* discarded. Once an element satisfies the [test] the iterator stops testing
* and uses every element unconditionally.
*/
- Iterable<E> skipWhile(bool test(E value)) {
- return new SkipWhileIterable<E>(this, test);
- }
+ Iterable<E> skipWhile(bool test(E value));
/**
* Returns the first element.
@@ -242,43 +205,21 @@
* If [this] is empty throws a [StateError]. Otherwise this method is
* equivalent to [:this.elementAt(0):]
*/
- E get first {
- Iterator it = iterator;
- if (!it.moveNext()) {
- throw new StateError("No elements");
- }
- return it.current;
- }
+ E get first;
/**
* Returns the last element.
*
* If [this] is empty throws a [StateError].
*/
- E get last {
- Iterator it = iterator;
- if (!it.moveNext()) {
- throw new StateError("No elements");
- }
- E result;
- do {
- result = it.current;
- } while(it.moveNext());
- return result;
- }
+ E get last;
/**
* Returns the single element in [this].
*
* If [this] is empty or has more than one element throws a [StateError].
*/
- E get single {
- Iterator it = iterator;
- if (!it.moveNext()) throw new StateError("No elements");
- E result = it.current;
- if (it.moveNext()) throw new StateError("More than one element");
- return result;
- }
+ E get single;
/**
* Returns the first element that satisfies the given predicate [f].
@@ -287,14 +228,7 @@
* returned. By default, when [orElse] is `null`, a [StateError] is
* thrown.
*/
- E firstWhere(bool test(E value), { E orElse() }) {
- // TODO(floitsch): check that arguments are of correct type?
- for (E element in this) {
- if (test(element)) return element;
- }
- if (orElse != null) return orElse();
- throw new StateError("No matching element");
- }
+ E firstWhere(bool test(E value), { E orElse() });
/**
* Returns the last element that satisfies the given predicate [f].
@@ -303,41 +237,13 @@
* returned. By default, when [orElse] is [:null:], a [StateError] is
* thrown.
*/
- E lastWhere(bool test(E value), {E orElse()}) {
- // TODO(floitsch): check that arguments are of correct type?
- E result = null;
- bool foundMatching = false;
- for (E element in this) {
- if (test(element)) {
- result = element;
- foundMatching = true;
- }
- }
- if (foundMatching) return result;
- if (orElse != null) return orElse();
- throw new StateError("No matching element");
- }
+ E lastWhere(bool test(E value), {E orElse()});
/**
* Returns the single element that satisfies [f]. If no or more than one
* element match then a [StateError] is thrown.
*/
- E singleWhere(bool test(E value)) {
- // TODO(floitsch): check that argument is of correct type?
- E result = null;
- bool foundMatching = false;
- for (E element in this) {
- if (test(element)) {
- if (foundMatching) {
- throw new StateError("More than one matching element");
- }
- result = element;
- foundMatching = true;
- }
- }
- if (foundMatching) return result;
- throw new StateError("No matching element");
- }
+ E singleWhere(bool test(E value));
/**
* Returns the [index]th element.
@@ -349,21 +255,13 @@
* function may simply return any element without any iteration if there are
* at least [index] elements in [this].
*/
- E elementAt(int index) {
- if (index is! int || index < 0) throw new RangeError.value(index);
- int remaining = index;
- for (E element in this) {
- if (remaining == 0) return element;
- remaining--;
- }
- throw new RangeError.value(index);
- }
+ E elementAt(int index);
}
typedef E _Generator<E>(int index);
-class _GeneratorIterable<E> extends Iterable<E> {
+class _GeneratorIterable<E> extends IterableBase<E> {
final int _count;
final _Generator<E> _generator;
_GeneratorIterable(this._count, this._generator);
@@ -395,7 +293,7 @@
/**
* An [Iterator] that allows moving backwards as well as forwards.
*/
-abstract class BidirectionalIterator<T> extends Iterator<T> {
+abstract class BidirectionalIterator<E> implements Iterator<E> {
/**
* Move back to the previous element.
*
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 27a857e..59d4cd1 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -189,6 +189,30 @@
void insert(int index, E element);
/**
+ * Inserts all elements of [iterable] at position [index] in the list.
+ *
+ * This increases the length of the list by the length of [iterable] and
+ * shifts all later elements towards the end of the list.
+ *
+ * It is an error if the [index] does not point inside the list or at the
+ * position after the last element.
+ */
+ void insertAll(int index, Iterable<E> iterable);
+
+ /**
+ * Overwrites elements of `this` with the elemenst of [iterable] starting
+ * at position [index] in the list.
+ *
+ * This operation does not increase the length of the list.
+ *
+ * It is an error if the [index] does not point inside the list or at the
+ * position after the last element.
+ *
+ * It is an error if the [iterable] is longer than [length] - [index].
+ */
+ void setAll(int index, Iterable<E> iterable);
+
+ /**
* Removes [value] from the list. Returns true if [value] was
* in the list. Returns false otherwise. The method has no effect
* if [value] value was not in the list.
@@ -263,40 +287,51 @@
Iterable<E> getRange(int start, int end);
/**
- * Copies [length] elements of [from], starting
- * at [startFrom], into the list, starting at [start].
- * If [length] is 0, this method does not do anything.
- * Throws an [ArgumentError] if [length] is negative.
- * Throws an [RangeError] if [start] or
- * [:start + length - 1:] are out of range for [:this:], or if
- * [startFrom] or [:startFrom + length - 1:] are out of range for [from].
+ * Copies the elements of [iterable], skipping the [skipCount] first elements
+ * into the range [start] - [end] (excluding) of `this`.
+ *
+ * If [start] equals [end] and represent a legal range, this method has
+ * no effect.
+ *
+ * It is an error if [start]..[end] is not a valid range pointing into the
+ * `this`.
+ *
+ * It is an error if the [iterable] does not have enough elements after
+ * skipping [skipCount] elements.
*/
- void setRange(int start, int length, List<E> from, [int startFrom]);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
/**
- * Removes [length] elements from the list, beginning at [start].
- * Throws an [UnsupportedError] if the list is
- * not extendable.
- * If [length] is 0, this method does not do anything.
- * Throws an [ArgumentError] if [length] is negative.
- * Throws an [RangeError] if [start] or
- * [:start + length: - 1] are out of range.
+ * Removes the elements in the range [start]..[end] (excluding).
+ *
+ * It is an error if [start]..[end] is not a valid range pointing into the
+ * `this`.
*/
- void removeRange(int start, int length);
+ void removeRange(int start, int end);
/**
- * Inserts a new range into the list, starting from [start] to
- * [:start + length - 1:]. The entries are filled with [fill].
- * Throws an [UnsupportedError] if the list is
- * not extendable.
- * If [length] is 0, this method does not do anything.
- * If [start] is the length of the list, this method inserts the
- * range at the end of the list.
- * Throws an [ArgumentError] if [length] is negative.
- * Throws an [RangeError] if [start] is negative or if
- * [start] is greater than the length of the list.
+ * Sets the elements in the range [start]..[end] (excluding) to the given
+ * [fillValue].
+ *
+ * It is an error if [start]..[end] is not a valid range pointing into the
+ * `this`.
*/
- void insertRange(int start, int length, [E fill]);
+ void fillRange(int start, int end, [E fillValue]);
+
+ /**
+ * Removes the elements in the range [start]..[end] (excluding) and replaces
+ * them with the contents of the [iterable].
+ *
+ * It is an error if [start]..[end] is not a valid range pointing into the
+ * `this`.
+ *
+ * Example:
+ *
+ * var list = [1, 2, 3, 4, 5];
+ * list.replaceRange(1, 3, [6, 7, 8, 9]);
+ * print(list); // [1, 6, 7, 8, 9, 4, 5]
+ */
+ void replaceRange(int start, int end, Iterable<E> iterable);
/**
* Returns an unmodifiable [Map] view of `this`.
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 74cc651..3b61927 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -50,14 +50,14 @@
/**
* [noSuchMethod] is invoked when users invoke a non-existant method
* on an object. The name of the method and the arguments of the
- * invocation are passed to [noSuchMethod] in an [InvocationMirror].
+ * invocation are passed to [noSuchMethod] in an [Invocation].
* If [noSuchMethod] returns a value, that value becomes the result of
* the original invocation.
*
* The default behavior of [noSuchMethod] is to throw a
* [noSuchMethodError].
*/
- external dynamic noSuchMethod(InvocationMirror invocation);
+ external dynamic noSuchMethod(Invocation invocation);
/**
* A representation of the runtime type of the object.
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 1a8fd15..ff8d4b3 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -8,7 +8,7 @@
* This class is the public interface of a set. A set is a collection
* without duplicates.
*/
-abstract class Set<E> extends Iterable<E> {
+abstract class Set<E> extends IterableBase<E> {
factory Set() => new HashSet<E>();
/**
diff --git a/sdk/lib/core/stacktrace.dart b/sdk/lib/core/stacktrace.dart
index a82a840..ef8cc4d 100644
--- a/sdk/lib/core/stacktrace.dart
+++ b/sdk/lib/core/stacktrace.dart
@@ -14,15 +14,14 @@
* them programmatically.
*/
abstract class StackTrace {
- // Returns a String object that contains the full stack trace starting from
- // the point where an exception has ocurred to the entry function which is
- // typically 'main'.
- // 'toString()' on a stack trace object essentially invokes this getter.
- external String get fullStackTrace;
-
- // Returns a String object that contains a stack trace starting from the
- // point where an exception has ocurred to the point where the exception
- // is caught.
- external String get stackTrace;
+ /**
+ * Returns a [String] representation of the stack trace.
+ *
+ * The string represents the full stack trace starting from
+ * the point where a throw ocurred to the top of the current call sequence.
+ *
+ * The exact format of the string representation is not final.
+ */
+ String toString();
}
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 36a2e60..ebcfe10 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -139,22 +139,6 @@
String operator +(String other);
/**
- * Returns a slice of this string from [startIndex] to [endIndex].
- *
- * If [startIndex] is omitted, it defaults to the start of the string.
- *
- * If [endIndex] is omitted, it defaults to the end of the string.
- *
- * If either index is negative, it's taken as a negative index from the
- * end of the string. Their effective value is computed by adding the
- * negative value to the [length] of the string.
- *
- * The effective indices, after must be non-negative, no greater than the
- * length of the string, and [endIndex] must not be less than [startIndex].
- */
- String slice([int startIndex, int endIndex]);
-
- /**
* Returns a substring of this string in the given range.
* [startIndex] is inclusive and [endIndex] is exclusive.
*/
@@ -267,7 +251,7 @@
/**
* The runes (integer Unicode code points) of a [String].
*/
-class Runes extends Iterable<int> {
+class Runes extends IterableBase<int> {
final String string;
Runes(this.string);
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index e2b686c..163307f 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -6,18 +6,13 @@
/// Opaque name used by mirrors, invocations and [Function.apply].
class Symbol {
-
/**
* Constructs a new Symbol.
*
* An [ArgumentError] is thrown if [name] starts with an underscore,
* or if [name] is not a [String]. An [ArgumentError] is thrown if
- * [name] is not an empty string and is not a valid identifier
- * optionally followed by [:'=':].
+ * [name] is not an empty string and is not a valid qualified
+ * identifier optionally followed by [:'=':].
*/
- external const Symbol(String name);
-
- external bool operator ==(other);
-
- external int get hashCode;
+ const factory Symbol(String name) = _collection_dev.Symbol;
}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index abb637f..17ea084 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -3,6 +3,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -510,6 +511,19 @@
@DocsEditable
+@DomName('AutocompleteErrorEvent')
+class AutocompleteErrorEvent extends Event native "*AutocompleteErrorEvent" {
+
+ @DomName('AutocompleteErrorEvent.reason')
+ @DocsEditable
+ final String reason;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('HTMLBRElement')
class BRElement extends Element native "*HTMLBRElement" {
@@ -557,77 +571,6 @@
@DocsEditable
-@DomName('BatteryManager')
-class BatteryManager extends EventTarget native "*BatteryManager" {
-
- @DomName('BatteryManager.chargingchangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
-
- @DomName('BatteryManager.chargingtimechangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
-
- @DomName('BatteryManager.dischargingtimechangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
-
- @DomName('BatteryManager.levelchangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
-
- @DomName('BatteryManager.charging')
- @DocsEditable
- final bool charging;
-
- @DomName('BatteryManager.chargingTime')
- @DocsEditable
- final num chargingTime;
-
- @DomName('BatteryManager.dischargingTime')
- @DocsEditable
- final num dischargingTime;
-
- @DomName('BatteryManager.level')
- @DocsEditable
- final num level;
-
- @JSName('addEventListener')
- @DomName('BatteryManager.addEventListener')
- @DocsEditable
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
-
- @DomName('BatteryManager.dispatchEvent')
- @DocsEditable
- bool dispatchEvent(Event event) native;
-
- @JSName('removeEventListener')
- @DomName('BatteryManager.removeEventListener')
- @DocsEditable
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
-
- @DomName('BatteryManager.onchargingchange')
- @DocsEditable
- Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.onchargingtimechange')
- @DocsEditable
- Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.ondischargingtimechange')
- @DocsEditable
- Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.onlevelchange')
- @DocsEditable
- Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
@DomName('BeforeLoadEvent')
class BeforeLoadEvent extends Event native "*BeforeLoadEvent" {
@@ -1087,6 +1030,15 @@
@DocsEditable
+@DomName('CanvasProxy')
+class CanvasProxy native "*CanvasProxy" {
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
/**
* A rendering context for a canvas element.
*
@@ -1109,6 +1061,10 @@
@DomName('CanvasRenderingContext2D')
class CanvasRenderingContext2D extends CanvasRenderingContext native "*CanvasRenderingContext2D" {
+ @DomName('CanvasRenderingContext2D.currentPath')
+ @DocsEditable
+ DomPath currentPath;
+
@DomName('CanvasRenderingContext2D.fillStyle')
@DocsEditable
@Creates('String|CanvasGradient|CanvasPattern')
@@ -1951,6 +1907,23 @@
@DocsEditable
+@DomName('CSSFontFaceLoadEvent')
+class CssFontFaceLoadEvent extends Event native "*CSSFontFaceLoadEvent" {
+
+ @DomName('CSSFontFaceLoadEvent.error')
+ @DocsEditable
+ final DomError error;
+
+ @DomName('CSSFontFaceLoadEvent.fontface')
+ @DocsEditable
+ final CssFontFaceRule fontface;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('CSSFontFaceRule')
class CssFontFaceRule extends CssRule native "*CSSFontFaceRule" {
@@ -2127,6 +2100,8 @@
static const int WEBKIT_KEYFRAME_RULE = 8;
+ static const int WEBKIT_REGION_RULE = 16;
+
@DomName('CSSRule.cssText')
@DocsEditable
String cssText;
@@ -5450,6 +5425,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+
+@DocsEditable
+@DomName('CustomElementConstructor')
+class CustomElementConstructor native "*CustomElementConstructor" {
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
// WARNING: Do not edit - generated code.
@@ -5807,6 +5791,31 @@
void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native;
}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('HTMLDialogElement')
+class DialogElement extends Element native "*HTMLDialogElement" {
+
+ @DomName('HTMLDialogElement.open')
+ @DocsEditable
+ bool open;
+
+ @DomName('HTMLDialogElement.close')
+ @DocsEditable
+ void close() native;
+
+ @DomName('HTMLDialogElement.show')
+ @DocsEditable
+ void show() native;
+
+ @DomName('HTMLDialogElement.showModal')
+ @DocsEditable
+ void showModal() native;
+}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6102,6 +6111,10 @@
@DocsEditable
final String domain;
+ @DomName('Document.fontloader')
+ @DocsEditable
+ final FontLoader fontloader;
+
@JSName('head')
/// Moved to [HtmlDocument].
@DomName('Document.head')
@@ -6228,12 +6241,12 @@
/// Deprecated: use new Element.tag(tagName) instead.
@DomName('Document.createElement')
@DocsEditable
- Element $dom_createElement(String tagName) native;
+ Element $dom_createElement(String localName_OR_tagName, [String typeExtension]) native;
@JSName('createElementNS')
@DomName('Document.createElementNS')
@DocsEditable
- Element $dom_createElementNS(String namespaceURI, String qualifiedName) native;
+ Element $dom_createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) native;
@JSName('createEvent')
@DomName('Document.createEvent')
@@ -6379,6 +6392,41 @@
@Experimental
void $dom_webkitExitPointerLock() native;
+ @JSName('webkitGetNamedFlows')
+ @DomName('Document.webkitGetNamedFlows')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ DomNamedFlowCollection getNamedFlows() native;
+
+ @DomName('Document.webkitRegister')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ CustomElementConstructor register(String name, [Map options]) {
+ if (?options) {
+ var options_1 = convertDartToNative_Dictionary(options);
+ return _register_1(name, options_1);
+ }
+ return _register_2(name);
+ }
+ @JSName('webkitRegister')
+ @DomName('Document.webkitRegister')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ CustomElementConstructor _register_1(name, options) native;
+ @JSName('webkitRegister')
+ @DomName('Document.webkitRegister')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ CustomElementConstructor _register_2(name) native;
+
@DomName('Document.onabort')
@DocsEditable
Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
@@ -6961,6 +7009,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
DomMimeType removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -6981,16 +7037,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<DomMimeType> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<DomMimeType> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [DomMimeType initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [DomMimeType fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<DomMimeType> getRange(int start, int end) =>
@@ -7027,6 +7087,27 @@
@DocsEditable
+@DomName('WebKitNamedFlowCollection')
+class DomNamedFlowCollection native "*WebKitNamedFlowCollection" {
+
+ @DomName('DOMNamedFlowCollection.length')
+ @DocsEditable
+ final int length;
+
+ @DomName('DOMNamedFlowCollection.item')
+ @DocsEditable
+ WebKitNamedFlow item(int index) native;
+
+ @DomName('DOMNamedFlowCollection.namedItem')
+ @DocsEditable
+ WebKitNamedFlow namedItem(String name) native;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('DOMParser')
class DomParser native "*DOMParser" {
@@ -7047,6 +7128,65 @@
@DocsEditable
+@DomName('Path')
+class DomPath native "*Path" {
+
+ @DomName('DOMPath.DOMPath')
+ @DocsEditable
+ factory DomPath([path_OR_text]) {
+ if (!?path_OR_text) {
+ return DomPath._create_1();
+ }
+ if ((path_OR_text is DomPath || path_OR_text == null)) {
+ return DomPath._create_2(path_OR_text);
+ }
+ if ((path_OR_text is String || path_OR_text == null)) {
+ return DomPath._create_3(path_OR_text);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+ static DomPath _create_1() => JS('DomPath', 'new Path()');
+ static DomPath _create_2(path_OR_text) => JS('DomPath', 'new Path(#)', path_OR_text);
+ static DomPath _create_3(path_OR_text) => JS('DomPath', 'new Path(#)', path_OR_text);
+
+ @DomName('DOMPath.arc')
+ @DocsEditable
+ void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
+
+ @DomName('DOMPath.arcTo')
+ @DocsEditable
+ void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+ @DomName('DOMPath.bezierCurveTo')
+ @DocsEditable
+ void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;
+
+ @DomName('DOMPath.closePath')
+ @DocsEditable
+ void closePath() native;
+
+ @DomName('DOMPath.lineTo')
+ @DocsEditable
+ void lineTo(num x, num y) native;
+
+ @DomName('DOMPath.moveTo')
+ @DocsEditable
+ void moveTo(num x, num y) native;
+
+ @DomName('DOMPath.quadraticCurveTo')
+ @DocsEditable
+ void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+ @DomName('DOMPath.rect')
+ @DocsEditable
+ void rect(num x, num y, num width, num height) native;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('Plugin')
class DomPlugin native "*Plugin" {
@@ -7223,6 +7363,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
DomPlugin removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7243,16 +7391,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<DomPlugin> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<DomPlugin> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [DomPlugin initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [DomPlugin fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<DomPlugin> getRange(int start, int end) =>
@@ -7633,6 +7785,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
String removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7653,16 +7813,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [String initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [String fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<String> getRange(int start, int end) =>
@@ -7897,8 +8061,16 @@
return _childElements.fold(initialValue, combine);
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
+ throw new UnimplementedError();
+ }
+
+ void replaceRange(int start, int end, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void fillRange(int start, int end, [Element fillValue]) {
throw new UnimplementedError();
}
@@ -7919,11 +8091,7 @@
_childElements.retainWhere(test);
}
- void removeRange(int start, int rangeLength) {
- throw new UnimplementedError();
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnimplementedError();
}
@@ -7956,6 +8124,14 @@
}
}
+ void insertAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
void clear() {
// It is unclear if we want to keep non element nodes?
_element.text = '';
@@ -8040,16 +8216,12 @@
throw new UnsupportedError('');
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError('');
}
- void removeRange(int start, int rangeLength) {
- throw new UnsupportedError('');
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnsupportedError('');
}
@@ -8915,6 +9087,14 @@
@Experimental
String pseudo;
+ @JSName('webkitRegionOverset')
+ @DomName('Element.webkitRegionOverset')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ final String regionOverset;
+
@JSName('webkitShadowRoot')
@DomName('Element.webkitShadowRoot')
@DocsEditable
@@ -9048,6 +9228,14 @@
@Experimental
ShadowRoot createShadowRoot() native;
+ @JSName('webkitGetRegionFlowRanges')
+ @DomName('Element.webkitGetRegionFlowRanges')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ List<Range> getRegionFlowRanges() native;
+
@JSName('webkitRequestFullScreen')
@DomName('Element.webkitRequestFullScreen')
@DocsEditable
@@ -10357,6 +10545,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
File removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -10377,16 +10573,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<File> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<File> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [File initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [File fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<File> getRange(int start, int end) =>
@@ -10841,6 +11041,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
num removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -10861,16 +11069,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [num initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [num fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<num> getRange(int start, int end) =>
@@ -11067,6 +11279,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
num removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -11087,16 +11307,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [num initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [num fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<num> getRange(int start, int end) =>
@@ -11151,6 +11375,69 @@
@DocsEditable
+@DomName('FontLoader')
+class FontLoader extends EventTarget native "*FontLoader" {
+
+ @DomName('FontLoader.errorEvent')
+ @DocsEditable
+ static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+ @DomName('FontLoader.loadEvent')
+ @DocsEditable
+ static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+ @DomName('FontLoader.loading')
+ @DocsEditable
+ final bool loading;
+
+ @JSName('addEventListener')
+ @DomName('FontLoader.addEventListener')
+ @DocsEditable
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+ @DomName('FontLoader.checkFont')
+ @DocsEditable
+ bool checkFont(String font, String text) native;
+
+ @DomName('FontLoader.dispatchEvent')
+ @DocsEditable
+ bool dispatchEvent(Event evt) native;
+
+ @DomName('FontLoader.loadFont')
+ @DocsEditable
+ void loadFont(Map params) {
+ var params_1 = convertDartToNative_Dictionary(params);
+ _loadFont_1(params_1);
+ return;
+ }
+ @JSName('loadFont')
+ @DomName('FontLoader.loadFont')
+ @DocsEditable
+ void _loadFont_1(params) native;
+
+ @DomName('FontLoader.notifyWhenFontsReady')
+ @DocsEditable
+ void notifyWhenFontsReady(VoidCallback callback) native;
+
+ @JSName('removeEventListener')
+ @DomName('FontLoader.removeEventListener')
+ @DocsEditable
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+ @DomName('FontLoader.onerror')
+ @DocsEditable
+ Stream<Event> get onError => errorEvent.forTarget(this);
+
+ @DomName('FontLoader.onload')
+ @DocsEditable
+ Stream<Event> get onLoad => loadEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -11233,6 +11520,10 @@
@DocsEditable
bool checkValidity() native;
+ @DomName('HTMLFormElement.requestAutocomplete')
+ @DocsEditable
+ void requestAutocomplete() native;
+
@DomName('HTMLFormElement.reset')
@DocsEditable
void reset() native;
@@ -11326,21 +11617,20 @@
int watchId;
var controller;
controller = new StreamController<Geoposition>(
- onSubscriptionStateChange: () {
- if (controller.hasListener) {
- assert(watchId == null);
- watchId = $dom_watchPosition(
- (position) {
- controller.add(_ensurePosition(position));
- },
- (error) {
- controller.addError(error);
- },
- options);
- } else {
- assert(watchId != null);
- $dom_clearWatch(watchId);
- }
+ onListen: () {
+ assert(watchId == null);
+ watchId = $dom_watchPosition(
+ (position) {
+ controller.add(_ensurePosition(position));
+ },
+ (error) {
+ controller.addError(error);
+ },
+ options);
+ },
+ onCancel: () {
+ assert(watchId != null);
+ $dom_clearWatch(watchId);
});
return controller.stream;
@@ -11713,6 +12003,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -11733,16 +12031,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -11928,6 +12230,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -11948,16 +12258,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -13966,6 +14280,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -13986,16 +14308,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -14192,6 +14518,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -14212,16 +14546,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -14418,6 +14756,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -14438,16 +14784,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -16673,14 +17023,6 @@
@DocsEditable
final String vendorSub;
- @JSName('webkitBattery')
- @DomName('Navigator.webkitBattery')
- @DocsEditable
- @SupportedBrowser(SupportedBrowser.CHROME)
- @SupportedBrowser(SupportedBrowser.SAFARI)
- @Experimental
- final BatteryManager battery;
-
@JSName('webkitPersistentStorage')
@DomName('Navigator.webkitPersistentStorage')
@DocsEditable
@@ -16705,6 +17047,10 @@
@DocsEditable
bool javaEnabled() native;
+ @DomName('Navigator.registerProtocolHandler')
+ @DocsEditable
+ void registerProtocolHandler(String scheme, String url, String title) native;
+
@JSName('webkitGetGamepads')
@DomName('Navigator.webkitGetGamepads')
@DocsEditable
@@ -16811,6 +17157,14 @@
}
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
Node removeLast() {
final result = last;
if (result != null) {
@@ -16881,23 +17235,28 @@
}
// FIXME: implement these.
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError(
"Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError(
- "Cannot insertRange on immutable List.");
- }
Iterable<Node> getRange(int start, int end) {
throw new UnimplementedError("NodeList.getRange");
}
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnimplementedError("NodeList.replaceRange");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnimplementedError("NodeList.fillRange");
+ }
+
List<Node> sublist(int start, [int end]) {
if (end == null) end == length;
return Lists.getRange(this, start, end, <Node>[]);
@@ -16997,7 +17356,7 @@
@Creates('Null')
var _model;
bool _hasLocalModel;
- StreamController<Node> _modelChangedStream;
+ Set<StreamController<Node>> _modelChangedStreams;
/**
* The data model which is inherited through the tree.
@@ -17014,7 +17373,7 @@
@Experimental
get model {
// If we have a change handler then we've cached the model locally.
- if (_modelChangedStream != null) {
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
return _model;
}
// Otherwise start looking up the tree.
@@ -17034,8 +17393,8 @@
_ModelTreeObserver.initialize();
if (changed) {
- if (_modelChangedStream != null) {
- _modelChangedStream.add(this);
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+ _modelChangedStreams.toList().forEach((stream) => stream.add(this));
}
// Propagate new model to all descendants.
_ModelTreeObserver.propagateModel(this, value, false);
@@ -17064,12 +17423,14 @@
* Get a stream of models, whenever the model changes.
*/
Stream<Node> get onModelChanged {
- if (_modelChangedStream == null) {
- // Ensure the model is cached locally to minimize change notifications.
- _model = model;
- _modelChangedStream = new StreamController.broadcast();
+ if (_modelChangedStreams == null) {
+ _modelChangedStreams = new Set<StreamController<Node>>();
}
- return _modelChangedStream.stream;
+ var controller;
+ controller = new StreamController(
+ onListen: () { _modelChangedStreams.add(controller); },
+ onCancel: () { _modelChangedStreams.remove(controller); });
+ return controller.stream;
}
/**
@@ -17428,6 +17789,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -17448,16 +17817,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -18070,6 +18443,138 @@
@DomName('Performance.now')
@DocsEditable
num now() native;
+
+ @JSName('webkitClearMarks')
+ @DomName('Performance.webkitClearMarks')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearMarks(String markName) native;
+
+ @JSName('webkitClearMeasures')
+ @DomName('Performance.webkitClearMeasures')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearMeasures(String measureName) native;
+
+ @JSName('webkitClearResourceTimings')
+ @DomName('Performance.webkitClearResourceTimings')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearResourceTimings() native;
+
+ @JSName('webkitGetEntries')
+ @DomName('Performance.webkitGetEntries')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntries() native;
+
+ @JSName('webkitGetEntriesByName')
+ @DomName('Performance.webkitGetEntriesByName')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntriesByName(String name, String entryType) native;
+
+ @JSName('webkitGetEntriesByType')
+ @DomName('Performance.webkitGetEntriesByType')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntriesByType(String entryType) native;
+
+ @JSName('webkitMark')
+ @DomName('Performance.webkitMark')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void mark(String markName) native;
+
+ @JSName('webkitMeasure')
+ @DomName('Performance.webkitMeasure')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void measure(String measureName, String startMark, String endMark) native;
+
+ @JSName('webkitSetResourceTimingBufferSize')
+ @DomName('Performance.webkitSetResourceTimingBufferSize')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void setResourceTimingBufferSize(int maxSize) native;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('PerformanceEntry')
+class PerformanceEntry native "*PerformanceEntry" {
+
+ @DomName('PerformanceEntry.duration')
+ @DocsEditable
+ final num duration;
+
+ @DomName('PerformanceEntry.entryType')
+ @DocsEditable
+ final String entryType;
+
+ @DomName('PerformanceEntry.name')
+ @DocsEditable
+ final String name;
+
+ @DomName('PerformanceEntry.startTime')
+ @DocsEditable
+ final num startTime;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('PerformanceEntryList')
+class PerformanceEntryList native "*PerformanceEntryList" {
+
+ @DomName('PerformanceEntryList.length')
+ @DocsEditable
+ final int length;
+
+ @DomName('PerformanceEntryList.item')
+ @DocsEditable
+ PerformanceEntry item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('PerformanceMark')
+class PerformanceMark extends PerformanceEntry native "*PerformanceMark" {
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('PerformanceMeasure')
+class PerformanceMeasure extends PerformanceEntry native "*PerformanceMeasure" {
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -18102,6 +18607,63 @@
@DocsEditable
+@DomName('PerformanceResourceTiming')
+class PerformanceResourceTiming extends PerformanceEntry native "*PerformanceResourceTiming" {
+
+ @DomName('PerformanceResourceTiming.connectEnd')
+ @DocsEditable
+ final num connectEnd;
+
+ @DomName('PerformanceResourceTiming.connectStart')
+ @DocsEditable
+ final num connectStart;
+
+ @DomName('PerformanceResourceTiming.domainLookupEnd')
+ @DocsEditable
+ final num domainLookupEnd;
+
+ @DomName('PerformanceResourceTiming.domainLookupStart')
+ @DocsEditable
+ final num domainLookupStart;
+
+ @DomName('PerformanceResourceTiming.fetchStart')
+ @DocsEditable
+ final num fetchStart;
+
+ @DomName('PerformanceResourceTiming.initiatorType')
+ @DocsEditable
+ final String initiatorType;
+
+ @DomName('PerformanceResourceTiming.redirectEnd')
+ @DocsEditable
+ final num redirectEnd;
+
+ @DomName('PerformanceResourceTiming.redirectStart')
+ @DocsEditable
+ final num redirectStart;
+
+ @DomName('PerformanceResourceTiming.requestStart')
+ @DocsEditable
+ final num requestStart;
+
+ @DomName('PerformanceResourceTiming.responseEnd')
+ @DocsEditable
+ final num responseEnd;
+
+ @DomName('PerformanceResourceTiming.responseStart')
+ @DocsEditable
+ final num responseStart;
+
+ @DomName('PerformanceResourceTiming.secureConnectionStart')
+ @DocsEditable
+ final num secureConnectionStart;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('PerformanceTiming')
class PerformanceTiming native "*PerformanceTiming" {
@@ -19772,6 +20334,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SourceBuffer removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -19792,16 +20362,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SourceBuffer> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SourceBuffer> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SourceBuffer initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SourceBuffer fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SourceBuffer> getRange(int start, int end) =>
@@ -20060,6 +20634,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechGrammar removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -20080,16 +20662,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechGrammar> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechGrammar> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechGrammar initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechGrammar fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechGrammar> getRange(int start, int end) =>
@@ -21511,6 +22097,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
TextTrackCue removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -21531,16 +22125,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<TextTrackCue> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<TextTrackCue> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [TextTrackCue initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [TextTrackCue fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<TextTrackCue> getRange(int start, int end) =>
@@ -21724,6 +22322,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
TextTrack removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -21744,16 +22350,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<TextTrack> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<TextTrack> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [TextTrack initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [TextTrack fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<TextTrack> getRange(int start, int end) =>
@@ -22163,6 +22773,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Touch removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -22183,16 +22801,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Touch> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Touch> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Touch initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Touch fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Touch> getRange(int start, int end) =>
@@ -22639,6 +23261,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -22659,16 +23289,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -22865,6 +23499,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -22885,16 +23527,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -23091,6 +23737,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -23111,16 +23765,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -23314,6 +23972,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -23334,16 +24000,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -23577,6 +24247,21 @@
@DocsEditable
+@DomName('WebKitCSSRegionRule')
+class WebKitCssRegionRule extends CssRule native "*WebKitCSSRegionRule" {
+
+ @DomName('WebKitCSSRegionRule.cssRules')
+ @DocsEditable
+ @Returns('_CssRuleList')
+ @Creates('_CssRuleList')
+ final List<CssRule> cssRules;
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
@DomName('WebKitNamedFlow')
class WebKitNamedFlow extends EventTarget native "*WebKitNamedFlow" {
@@ -25019,7 +25704,7 @@
const _BeforeUnloadEventStreamProvider(this._eventType);
Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
- var controller = new StreamController.broadcast();
+ var controller = new StreamController();
var stream = new _EventStream(e, _eventType, useCapture);
stream.listen((event) {
var wrapped = new _BeforeUnloadEvent(event);
@@ -25588,6 +26273,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Rect removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -25608,16 +26301,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Rect> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Rect initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Rect fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Rect> getRange(int start, int end) =>
@@ -25802,6 +26499,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
CssRule removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -25822,16 +26527,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<CssRule> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<CssRule> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [CssRule initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [CssRule fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<CssRule> getRange(int start, int end) =>
@@ -26007,6 +26716,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
_CSSValue removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -26027,16 +26744,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<_CSSValue> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<_CSSValue> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [_CSSValue initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [_CSSValue fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<_CSSValue> getRange(int start, int end) =>
@@ -26280,6 +27001,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Entry removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -26300,16 +27029,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Entry> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Entry> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Entry initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Entry fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Entry> getRange(int start, int end) =>
@@ -26485,6 +27218,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
_EntrySync removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -26505,16 +27246,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<_EntrySync> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<_EntrySync> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [_EntrySync initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [_EntrySync fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<_EntrySync> getRange(int start, int end) =>
@@ -26733,6 +27478,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Gamepad removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -26753,16 +27506,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Gamepad> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Gamepad> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Gamepad initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Gamepad fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Gamepad> getRange(int start, int end) =>
@@ -27001,6 +27758,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27021,16 +27786,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -27277,6 +28046,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechInputResult removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27297,16 +28074,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechInputResult> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechInputResult> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechInputResult initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechInputResult fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechInputResult> getRange(int start, int end) =>
@@ -27482,6 +28263,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechRecognitionResult removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27502,16 +28291,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechRecognitionResult> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechRecognitionResult> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechRecognitionResult initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechRecognitionResult fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechRecognitionResult> getRange(int start, int end) =>
@@ -27687,6 +28480,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
StyleSheet removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27707,16 +28508,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<StyleSheet> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<StyleSheet> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [StyleSheet initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [StyleSheet fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<StyleSheet> getRange(int start, int end) =>
@@ -28467,9 +29272,9 @@
bool get isBroadcast => true;
StreamSubscription<T> listen(void onData(T event),
- { void onError(AsyncError error),
- void onDone(),
- bool unsubscribeOnError}) {
+ { void onError(error),
+ void onDone(),
+ bool cancelOnError}) {
return new _EventStreamSubscription<T>(
this._target, this._eventType, onData, this._useCapture);
@@ -28511,7 +29316,7 @@
}
/// Has no effect.
- void onError(void handleError(AsyncError error)) {}
+ void onError(void handleError(error)) {}
/// Has no effect.
void onDone(void handleDone()) {}
@@ -28545,6 +29350,12 @@
_target.$dom_removeEventListener(_eventType, _onData, _useCapture);
}
}
+
+ Future asFuture([var futureValue]) {
+ // We just need a future that will never succeed or fail.
+ Completer completer = new Completer();
+ return completer.future;
+ }
}
@@ -28634,7 +29445,7 @@
static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
/** Controller to produce KeyEvents for the stream. */
- final StreamController _controller = new StreamController.broadcast();
+ final StreamController _controller = new StreamController();
static const _EVENT_TYPE = 'KeyEvent';
@@ -29855,14 +30666,14 @@
// Catch and report them a global exceptions.
try {
if (node._hasLocalModel != true && node._model != model &&
- node._modelChangedStream != null) {
+ node._modelChangedStreams != null &&
+ !node._modelChangedStreams.isEmpty) {
node._model = model;
- node._modelChangedStream.add(node);
+ node._modelChangedStreams.toList()
+ .forEach((controller) => controller.add(node));
}
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError(e, s).throwDelayed();
+ new Future.error(e, s);
}
for (var child = node.$dom_firstChild; child != null;
child = child.nextNode) {
@@ -30836,6 +31647,12 @@
void insert(int index, E element) => _list.insert(index, element);
+ void insertAll(int index, Iterable<E> iterable) =>
+ _list.insertAll(index, iterable);
+
+ void setAll(int index, Iterable<E> iterable) =>
+ _list.setAll(index, iterable);
+
E removeAt(int index) => _list.removeAt(index);
E removeLast() => _list.removeLast();
@@ -30844,14 +31661,18 @@
Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
- void setRange(int start, int length, List<E> from, [int startFrom]) {
- _list.setRange(start, length, from, startFrom);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ _list.setRange(start, end, iterable, skipCount);
}
- void removeRange(int start, int length) { _list.removeRange(start, length); }
+ void removeRange(int start, int end) { _list.removeRange(start, end); }
- void insertRange(int start, int length, [E fill]) {
- _list.insertRange(start, length, fill);
+ void replaceRange(int start, int end, Iterable<E> iterable) {
+ _list.replaceRange(start, end, iterable);
+ }
+
+ void fillRange(int start, int end, [E fillValue]) {
+ _list.fillRange(start, end, fillValue);
}
Map<int, E> asMap() => _list.asMap();
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 181104f..cb67dad 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -3,6 +3,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
@@ -616,6 +617,23 @@
@DocsEditable
+@DomName('AutocompleteErrorEvent')
+class AutocompleteErrorEvent extends Event {
+ AutocompleteErrorEvent.internal() : super.internal();
+
+ @DomName('AutocompleteErrorEvent.reason')
+ @DocsEditable
+ String get reason native "AutocompleteErrorEvent_reason_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('HTMLBRElement')
class BRElement extends _Element_Merged {
BRElement.internal() : super.internal();
@@ -683,79 +701,6 @@
@DocsEditable
-@DomName('BatteryManager')
-class BatteryManager extends EventTarget {
- BatteryManager.internal() : super.internal();
-
- @DomName('BatteryManager.chargingchangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
-
- @DomName('BatteryManager.chargingtimechangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
-
- @DomName('BatteryManager.dischargingtimechangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
-
- @DomName('BatteryManager.levelchangeEvent')
- @DocsEditable
- static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
-
- @DomName('BatteryManager.charging')
- @DocsEditable
- bool get charging native "BatteryManager_charging_Getter";
-
- @DomName('BatteryManager.chargingTime')
- @DocsEditable
- num get chargingTime native "BatteryManager_chargingTime_Getter";
-
- @DomName('BatteryManager.dischargingTime')
- @DocsEditable
- num get dischargingTime native "BatteryManager_dischargingTime_Getter";
-
- @DomName('BatteryManager.level')
- @DocsEditable
- num get level native "BatteryManager_level_Getter";
-
- @DomName('BatteryManager.addEventListener')
- @DocsEditable
- void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "BatteryManager_addEventListener_Callback";
-
- @DomName('BatteryManager.dispatchEvent')
- @DocsEditable
- bool dispatchEvent(Event event) native "BatteryManager_dispatchEvent_Callback";
-
- @DomName('BatteryManager.removeEventListener')
- @DocsEditable
- void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "BatteryManager_removeEventListener_Callback";
-
- @DomName('BatteryManager.onchargingchange')
- @DocsEditable
- Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.onchargingtimechange')
- @DocsEditable
- Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.ondischargingtimechange')
- @DocsEditable
- Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
-
- @DomName('BatteryManager.onlevelchange')
- @DocsEditable
- Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
-
-}
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
@DomName('BeforeLoadEvent')
class BeforeLoadEvent extends Event {
BeforeLoadEvent.internal() : super.internal();
@@ -1284,6 +1229,19 @@
@DocsEditable
+@DomName('CanvasProxy')
+class CanvasProxy extends NativeFieldWrapperClass1 {
+ CanvasProxy.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
/**
* A rendering context for a canvas element.
*
@@ -1309,6 +1267,14 @@
class CanvasRenderingContext2D extends CanvasRenderingContext {
CanvasRenderingContext2D.internal() : super.internal();
+ @DomName('CanvasRenderingContext2D.currentPath')
+ @DocsEditable
+ DomPath get currentPath native "CanvasRenderingContext2D_currentPath_Getter";
+
+ @DomName('CanvasRenderingContext2D.currentPath')
+ @DocsEditable
+ void set currentPath(DomPath value) native "CanvasRenderingContext2D_currentPath_Setter";
+
@DomName('CanvasRenderingContext2D.fillStyle')
@DocsEditable
dynamic get fillStyle native "CanvasRenderingContext2D_fillStyle_Getter";
@@ -2376,6 +2342,27 @@
@DocsEditable
+@DomName('CSSFontFaceLoadEvent')
+class CssFontFaceLoadEvent extends Event {
+ CssFontFaceLoadEvent.internal() : super.internal();
+
+ @DomName('CSSFontFaceLoadEvent.error')
+ @DocsEditable
+ DomError get error native "CSSFontFaceLoadEvent_error_Getter";
+
+ @DomName('CSSFontFaceLoadEvent.fontface')
+ @DocsEditable
+ CssFontFaceRule get fontface native "CSSFontFaceLoadEvent_fontface_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('CSSFontFaceRule')
class CssFontFaceRule extends CssRule {
CssFontFaceRule.internal() : super.internal();
@@ -2587,6 +2574,8 @@
static const int WEBKIT_KEYFRAME_RULE = 8;
+ static const int WEBKIT_REGION_RULE = 16;
+
@DomName('CSSRule.cssText')
@DocsEditable
String get cssText native "CSSRule_cssText_Getter";
@@ -5932,6 +5921,19 @@
// WARNING: Do not edit - generated code.
+@DocsEditable
+@DomName('CustomElementConstructor')
+class CustomElementConstructor extends NativeFieldWrapperClass1 {
+ CustomElementConstructor.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
@DomName('CustomEvent')
class CustomEvent extends Event {
factory CustomEvent(String type,
@@ -6472,6 +6474,39 @@
void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native "DeviceOrientationEvent_initDeviceOrientationEvent_Callback";
}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('HTMLDialogElement')
+class DialogElement extends _Element_Merged {
+ DialogElement.internal() : super.internal();
+
+ @DomName('HTMLDialogElement.open')
+ @DocsEditable
+ bool get open native "HTMLDialogElement_open_Getter";
+
+ @DomName('HTMLDialogElement.open')
+ @DocsEditable
+ void set open(bool value) native "HTMLDialogElement_open_Setter";
+
+ @DomName('HTMLDialogElement.close')
+ @DocsEditable
+ void close() native "HTMLDialogElement_close_Callback";
+
+ @DomName('HTMLDialogElement.show')
+ @DocsEditable
+ void show() native "HTMLDialogElement_show_Callback";
+
+ @DomName('HTMLDialogElement.showModal')
+ @DocsEditable
+ void showModal() native "HTMLDialogElement_showModal_Callback";
+
+}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6703,6 +6738,10 @@
@DocsEditable
String get domain native "Document_domain_Getter";
+ @DomName('Document.fontloader')
+ @DocsEditable
+ FontLoader get fontloader native "Document_fontloader_Getter";
+
/// Moved to [HtmlDocument].
@DomName('Document.head')
@DocsEditable
@@ -6817,14 +6856,41 @@
@DocsEditable
DocumentFragment createDocumentFragment() native "Document_createDocumentFragment_Callback";
- /// Deprecated: use new Element.tag(tagName) instead.
- @DomName('Document.createElement')
- @DocsEditable
- Element $dom_createElement(String tagName) native "Document_createElement_Callback";
+ Element $dom_createElement(String localName_OR_tagName, [String typeExtension]) {
+ if ((localName_OR_tagName is String || localName_OR_tagName == null) && !?typeExtension) {
+ return _createElement_1(localName_OR_tagName);
+ }
+ if ((localName_OR_tagName is String || localName_OR_tagName == null) && (typeExtension is String || typeExtension == null)) {
+ return _createElement_2(localName_OR_tagName, typeExtension);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
- @DomName('Document.createElementNS')
+ @DomName('Document._createElement_1')
@DocsEditable
- Element $dom_createElementNS(String namespaceURI, String qualifiedName) native "Document_createElementNS_Callback";
+ Element _createElement_1(localName_OR_tagName) native "Document__createElement_1_Callback";
+
+ @DomName('Document._createElement_2')
+ @DocsEditable
+ Element _createElement_2(localName_OR_tagName, typeExtension) native "Document__createElement_2_Callback";
+
+ Element $dom_createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
+ if ((namespaceURI is String || namespaceURI == null) && (qualifiedName is String || qualifiedName == null) && !?typeExtension) {
+ return _createElementNS_1(namespaceURI, qualifiedName);
+ }
+ if ((namespaceURI is String || namespaceURI == null) && (qualifiedName is String || qualifiedName == null) && (typeExtension is String || typeExtension == null)) {
+ return _createElementNS_2(namespaceURI, qualifiedName, typeExtension);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+
+ @DomName('Document._createElementNS_1')
+ @DocsEditable
+ Element _createElementNS_1(namespaceURI, qualifiedName) native "Document__createElementNS_1_Callback";
+
+ @DomName('Document._createElementNS_2')
+ @DocsEditable
+ Element _createElementNS_2(namespaceURI, qualifiedName, typeExtension) native "Document__createElementNS_2_Callback";
@DomName('Document.createEvent')
@DocsEditable
@@ -6944,6 +7010,20 @@
@Experimental
void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
+ @DomName('Document.webkitGetNamedFlows')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ DomNamedFlowCollection getNamedFlows() native "Document_webkitGetNamedFlows_Callback";
+
+ @DomName('Document.webkitRegister')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ CustomElementConstructor register(String name, [Map options]) native "Document_webkitRegister_Callback";
+
@DomName('Document.onabort')
@DocsEditable
Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
@@ -7532,6 +7612,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
DomMimeType removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7552,16 +7640,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<DomMimeType> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<DomMimeType> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [DomMimeType initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<DomMimeType> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [DomMimeType fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<DomMimeType> getRange(int start, int end) =>
@@ -7601,6 +7693,31 @@
@DocsEditable
+@DomName('WebKitNamedFlowCollection')
+class DomNamedFlowCollection extends NativeFieldWrapperClass1 {
+ DomNamedFlowCollection.internal();
+
+ @DomName('DOMNamedFlowCollection.length')
+ @DocsEditable
+ int get length native "DOMNamedFlowCollection_length_Getter";
+
+ @DomName('DOMNamedFlowCollection.item')
+ @DocsEditable
+ WebKitNamedFlow item(int index) native "DOMNamedFlowCollection_item_Callback";
+
+ @DomName('DOMNamedFlowCollection.namedItem')
+ @DocsEditable
+ WebKitNamedFlow namedItem(String name) native "DOMNamedFlowCollection_namedItem_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('DOMParser')
class DomParser extends NativeFieldWrapperClass1 {
DomParser.internal();
@@ -7627,6 +7744,75 @@
@DocsEditable
+@DomName('Path')
+class DomPath extends NativeFieldWrapperClass1 {
+ DomPath.internal();
+
+ @DomName('DOMPath.DOMPath')
+ @DocsEditable
+ factory DomPath([path_OR_text]) {
+ if (!?path_OR_text) {
+ return DomPath._create_1();
+ }
+ if ((path_OR_text is DomPath || path_OR_text == null)) {
+ return DomPath._create_2(path_OR_text);
+ }
+ if ((path_OR_text is String || path_OR_text == null)) {
+ return DomPath._create_3(path_OR_text);
+ }
+ throw new ArgumentError("Incorrect number or type of arguments");
+ }
+
+ @DocsEditable
+ static DomPath _create_1() native "DOMPath__create_1constructorCallback";
+
+ @DocsEditable
+ static DomPath _create_2(path_OR_text) native "DOMPath__create_2constructorCallback";
+
+ @DocsEditable
+ static DomPath _create_3(path_OR_text) native "DOMPath__create_3constructorCallback";
+
+ @DomName('DOMPath.arc')
+ @DocsEditable
+ void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "DOMPath_arc_Callback";
+
+ @DomName('DOMPath.arcTo')
+ @DocsEditable
+ void arcTo(num x1, num y1, num x2, num y2, num radius) native "DOMPath_arcTo_Callback";
+
+ @DomName('DOMPath.bezierCurveTo')
+ @DocsEditable
+ void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native "DOMPath_bezierCurveTo_Callback";
+
+ @DomName('DOMPath.closePath')
+ @DocsEditable
+ void closePath() native "DOMPath_closePath_Callback";
+
+ @DomName('DOMPath.lineTo')
+ @DocsEditable
+ void lineTo(num x, num y) native "DOMPath_lineTo_Callback";
+
+ @DomName('DOMPath.moveTo')
+ @DocsEditable
+ void moveTo(num x, num y) native "DOMPath_moveTo_Callback";
+
+ @DomName('DOMPath.quadraticCurveTo')
+ @DocsEditable
+ void quadraticCurveTo(num cpx, num cpy, num x, num y) native "DOMPath_quadraticCurveTo_Callback";
+
+ @DomName('DOMPath.rect')
+ @DocsEditable
+ void rect(num x, num y, num width, num height) native "DOMPath_rect_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('Plugin')
class DomPlugin extends NativeFieldWrapperClass1 {
DomPlugin.internal();
@@ -7808,6 +7994,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
DomPlugin removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7828,16 +8022,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<DomPlugin> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<DomPlugin> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [DomPlugin initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<DomPlugin> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [DomPlugin fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<DomPlugin> getRange(int start, int end) =>
@@ -8236,6 +8434,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
String removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -8256,16 +8462,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [String initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [String fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<String> getRange(int start, int end) =>
@@ -8521,8 +8731,16 @@
return _childElements.fold(initialValue, combine);
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
+ throw new UnimplementedError();
+ }
+
+ void replaceRange(int start, int end, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void fillRange(int start, int end, [Element fillValue]) {
throw new UnimplementedError();
}
@@ -8543,11 +8761,7 @@
_childElements.retainWhere(test);
}
- void removeRange(int start, int rangeLength) {
- throw new UnimplementedError();
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnimplementedError();
}
@@ -8580,6 +8794,14 @@
}
}
+ void insertAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
void clear() {
// It is unclear if we want to keep non element nodes?
_element.text = '';
@@ -8664,16 +8886,12 @@
throw new UnsupportedError('');
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError('');
}
- void removeRange(int start, int rangeLength) {
- throw new UnsupportedError('');
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnsupportedError('');
}
@@ -9383,6 +9601,13 @@
@Experimental
void set pseudo(String value) native "Element_webkitPseudo_Setter";
+ @DomName('Element.webkitRegionOverset')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ String get regionOverset native "Element_webkitRegionOverset_Getter";
+
@DomName('Element.webkitShadowRoot')
@DocsEditable
@SupportedBrowser(SupportedBrowser.CHROME)
@@ -9523,6 +9748,13 @@
@Experimental
ShadowRoot createShadowRoot() native "Element_webkitCreateShadowRoot_Callback";
+ @DomName('Element.webkitGetRegionFlowRanges')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ List<Range> getRegionFlowRanges() native "Element_webkitGetRegionFlowRanges_Callback";
+
@DomName('Element.webkitMatchesSelector')
@DocsEditable
@Experimental()
@@ -10907,6 +11139,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
File removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -10927,16 +11167,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<File> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<File> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [File initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<File> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [File fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<File> getRange(int start, int end) =>
@@ -11421,6 +11665,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
num removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -11441,16 +11693,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [num initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [num fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<num> getRange(int start, int end) =>
@@ -11664,6 +11920,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
num removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -11684,16 +11948,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [num initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<num> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [num fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<num> getRange(int start, int end) =>
@@ -11761,6 +12029,63 @@
@DocsEditable
+@DomName('FontLoader')
+class FontLoader extends EventTarget {
+ FontLoader.internal() : super.internal();
+
+ @DomName('FontLoader.errorEvent')
+ @DocsEditable
+ static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+ @DomName('FontLoader.loadEvent')
+ @DocsEditable
+ static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+ @DomName('FontLoader.loading')
+ @DocsEditable
+ bool get loading native "FontLoader_loading_Getter";
+
+ @DomName('FontLoader.addEventListener')
+ @DocsEditable
+ void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "FontLoader_addEventListener_Callback";
+
+ @DomName('FontLoader.checkFont')
+ @DocsEditable
+ bool checkFont(String font, String text) native "FontLoader_checkFont_Callback";
+
+ @DomName('FontLoader.dispatchEvent')
+ @DocsEditable
+ bool dispatchEvent(Event evt) native "FontLoader_dispatchEvent_Callback";
+
+ @DomName('FontLoader.loadFont')
+ @DocsEditable
+ void loadFont(Map params) native "FontLoader_loadFont_Callback";
+
+ @DomName('FontLoader.notifyWhenFontsReady')
+ @DocsEditable
+ void notifyWhenFontsReady(VoidCallback callback) native "FontLoader_notifyWhenFontsReady_Callback";
+
+ @DomName('FontLoader.removeEventListener')
+ @DocsEditable
+ void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "FontLoader_removeEventListener_Callback";
+
+ @DomName('FontLoader.onerror')
+ @DocsEditable
+ Stream<Event> get onError => errorEvent.forTarget(this);
+
+ @DomName('FontLoader.onload')
+ @DocsEditable
+ Stream<Event> get onLoad => loadEvent.forTarget(this);
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('FormData')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -11877,6 +12202,10 @@
@DocsEditable
bool checkValidity() native "HTMLFormElement_checkValidity_Callback";
+ @DomName('HTMLFormElement.requestAutocomplete')
+ @DocsEditable
+ void requestAutocomplete() native "HTMLFormElement_requestAutocomplete_Callback";
+
@DomName('HTMLFormElement.reset')
@DocsEditable
void reset() native "HTMLFormElement_reset_Callback";
@@ -11975,21 +12304,20 @@
int watchId;
var controller;
controller = new StreamController<Geoposition>(
- onSubscriptionStateChange: () {
- if (controller.hasListener) {
- assert(watchId == null);
- watchId = $dom_watchPosition(
- (position) {
- controller.add(_ensurePosition(position));
- },
- (error) {
- controller.addError(error);
- },
- options);
- } else {
- assert(watchId != null);
- $dom_clearWatch(watchId);
- }
+ onListen: () {
+ assert(watchId == null);
+ watchId = $dom_watchPosition(
+ (position) {
+ controller.add(_ensurePosition(position));
+ },
+ (error) {
+ controller.addError(error);
+ },
+ options);
+ },
+ onCancel: () {
+ assert(watchId != null);
+ $dom_clearWatch(watchId);
});
return controller.stream;
@@ -12356,6 +12684,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -12376,16 +12712,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -12573,6 +12913,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -12593,16 +12941,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -14946,6 +15298,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -14966,16 +15326,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -15189,6 +15553,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -15209,16 +15581,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -15432,6 +15808,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -15452,16 +15836,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -17979,13 +18367,6 @@
@DocsEditable
String get vendorSub native "Navigator_vendorSub_Getter";
- @DomName('Navigator.webkitBattery')
- @DocsEditable
- @SupportedBrowser(SupportedBrowser.CHROME)
- @SupportedBrowser(SupportedBrowser.SAFARI)
- @Experimental
- BatteryManager get battery native "Navigator_webkitBattery_Getter";
-
@DomName('Navigator.webkitPersistentStorage')
@DocsEditable
@SupportedBrowser(SupportedBrowser.CHROME)
@@ -18008,6 +18389,10 @@
@DocsEditable
bool javaEnabled() native "Navigator_javaEnabled_Callback";
+ @DomName('Navigator.registerProtocolHandler')
+ @DocsEditable
+ void registerProtocolHandler(String scheme, String url, String title) native "Navigator_registerProtocolHandler_Callback";
+
@DomName('Navigator.webkitGetGamepads')
@DocsEditable
@SupportedBrowser(SupportedBrowser.CHROME)
@@ -18119,6 +18504,14 @@
}
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
Node removeLast() {
final result = last;
if (result != null) {
@@ -18189,23 +18582,28 @@
}
// FIXME: implement these.
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError(
"Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError(
- "Cannot insertRange on immutable List.");
- }
Iterable<Node> getRange(int start, int end) {
throw new UnimplementedError("NodeList.getRange");
}
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnimplementedError("NodeList.replaceRange");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnimplementedError("NodeList.fillRange");
+ }
+
List<Node> sublist(int start, [int end]) {
if (end == null) end == length;
return Lists.getRange(this, start, end, <Node>[]);
@@ -18304,7 +18702,7 @@
// notifications.
var _model;
bool _hasLocalModel;
- StreamController<Node> _modelChangedStream;
+ Set<StreamController<Node>> _modelChangedStreams;
/**
* The data model which is inherited through the tree.
@@ -18321,7 +18719,7 @@
@Experimental
get model {
// If we have a change handler then we've cached the model locally.
- if (_modelChangedStream != null) {
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
return _model;
}
// Otherwise start looking up the tree.
@@ -18341,8 +18739,8 @@
_ModelTreeObserver.initialize();
if (changed) {
- if (_modelChangedStream != null) {
- _modelChangedStream.add(this);
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+ _modelChangedStreams.toList().forEach((stream) => stream.add(this));
}
// Propagate new model to all descendants.
_ModelTreeObserver.propagateModel(this, value, false);
@@ -18371,12 +18769,14 @@
* Get a stream of models, whenever the model changes.
*/
Stream<Node> get onModelChanged {
- if (_modelChangedStream == null) {
- // Ensure the model is cached locally to minimize change notifications.
- _model = model;
- _modelChangedStream = new StreamController.broadcast();
+ if (_modelChangedStreams == null) {
+ _modelChangedStreams = new Set<StreamController<Node>>();
}
- return _modelChangedStream.stream;
+ var controller;
+ controller = new StreamController(
+ onListen: () { _modelChangedStreams.add(controller); },
+ onCancel: () { _modelChangedStreams.remove(controller); });
+ return controller.stream;
}
/**
@@ -18734,6 +19134,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -18754,16 +19162,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -19500,6 +19912,145 @@
@DocsEditable
num now() native "Performance_now_Callback";
+ @DomName('Performance.webkitClearMarks')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearMarks(String markName) native "Performance_webkitClearMarks_Callback";
+
+ @DomName('Performance.webkitClearMeasures')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearMeasures(String measureName) native "Performance_webkitClearMeasures_Callback";
+
+ @DomName('Performance.webkitClearResourceTimings')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void clearResourceTimings() native "Performance_webkitClearResourceTimings_Callback";
+
+ @DomName('Performance.webkitGetEntries')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntries() native "Performance_webkitGetEntries_Callback";
+
+ @DomName('Performance.webkitGetEntriesByName')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntriesByName(String name, String entryType) native "Performance_webkitGetEntriesByName_Callback";
+
+ @DomName('Performance.webkitGetEntriesByType')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ PerformanceEntryList getEntriesByType(String entryType) native "Performance_webkitGetEntriesByType_Callback";
+
+ @DomName('Performance.webkitMark')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void mark(String markName) native "Performance_webkitMark_Callback";
+
+ @DomName('Performance.webkitMeasure')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void measure(String measureName, String startMark, String endMark) native "Performance_webkitMeasure_Callback";
+
+ @DomName('Performance.webkitSetResourceTimingBufferSize')
+ @DocsEditable
+ @SupportedBrowser(SupportedBrowser.CHROME)
+ @SupportedBrowser(SupportedBrowser.SAFARI)
+ @Experimental
+ void setResourceTimingBufferSize(int maxSize) native "Performance_webkitSetResourceTimingBufferSize_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('PerformanceEntry')
+class PerformanceEntry extends NativeFieldWrapperClass1 {
+ PerformanceEntry.internal();
+
+ @DomName('PerformanceEntry.duration')
+ @DocsEditable
+ num get duration native "PerformanceEntry_duration_Getter";
+
+ @DomName('PerformanceEntry.entryType')
+ @DocsEditable
+ String get entryType native "PerformanceEntry_entryType_Getter";
+
+ @DomName('PerformanceEntry.name')
+ @DocsEditable
+ String get name native "PerformanceEntry_name_Getter";
+
+ @DomName('PerformanceEntry.startTime')
+ @DocsEditable
+ num get startTime native "PerformanceEntry_startTime_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('PerformanceEntryList')
+class PerformanceEntryList extends NativeFieldWrapperClass1 {
+ PerformanceEntryList.internal();
+
+ @DomName('PerformanceEntryList.length')
+ @DocsEditable
+ int get length native "PerformanceEntryList_length_Getter";
+
+ @DomName('PerformanceEntryList.item')
+ @DocsEditable
+ PerformanceEntry item(int index) native "PerformanceEntryList_item_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('PerformanceMark')
+class PerformanceMark extends PerformanceEntry {
+ PerformanceMark.internal() : super.internal();
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('PerformanceMeasure')
+class PerformanceMeasure extends PerformanceEntry {
+ PerformanceMeasure.internal() : super.internal();
+
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -19538,6 +20089,67 @@
@DocsEditable
+@DomName('PerformanceResourceTiming')
+class PerformanceResourceTiming extends PerformanceEntry {
+ PerformanceResourceTiming.internal() : super.internal();
+
+ @DomName('PerformanceResourceTiming.connectEnd')
+ @DocsEditable
+ num get connectEnd native "PerformanceResourceTiming_connectEnd_Getter";
+
+ @DomName('PerformanceResourceTiming.connectStart')
+ @DocsEditable
+ num get connectStart native "PerformanceResourceTiming_connectStart_Getter";
+
+ @DomName('PerformanceResourceTiming.domainLookupEnd')
+ @DocsEditable
+ num get domainLookupEnd native "PerformanceResourceTiming_domainLookupEnd_Getter";
+
+ @DomName('PerformanceResourceTiming.domainLookupStart')
+ @DocsEditable
+ num get domainLookupStart native "PerformanceResourceTiming_domainLookupStart_Getter";
+
+ @DomName('PerformanceResourceTiming.fetchStart')
+ @DocsEditable
+ num get fetchStart native "PerformanceResourceTiming_fetchStart_Getter";
+
+ @DomName('PerformanceResourceTiming.initiatorType')
+ @DocsEditable
+ String get initiatorType native "PerformanceResourceTiming_initiatorType_Getter";
+
+ @DomName('PerformanceResourceTiming.redirectEnd')
+ @DocsEditable
+ num get redirectEnd native "PerformanceResourceTiming_redirectEnd_Getter";
+
+ @DomName('PerformanceResourceTiming.redirectStart')
+ @DocsEditable
+ num get redirectStart native "PerformanceResourceTiming_redirectStart_Getter";
+
+ @DomName('PerformanceResourceTiming.requestStart')
+ @DocsEditable
+ num get requestStart native "PerformanceResourceTiming_requestStart_Getter";
+
+ @DomName('PerformanceResourceTiming.responseEnd')
+ @DocsEditable
+ num get responseEnd native "PerformanceResourceTiming_responseEnd_Getter";
+
+ @DomName('PerformanceResourceTiming.responseStart')
+ @DocsEditable
+ num get responseStart native "PerformanceResourceTiming_responseStart_Getter";
+
+ @DomName('PerformanceResourceTiming.secureConnectionStart')
+ @DocsEditable
+ num get secureConnectionStart native "PerformanceResourceTiming_secureConnectionStart_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('PerformanceTiming')
class PerformanceTiming extends NativeFieldWrapperClass1 {
PerformanceTiming.internal();
@@ -21361,6 +21973,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SourceBuffer removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -21381,16 +22001,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SourceBuffer> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SourceBuffer> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SourceBuffer initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SourceBuffer> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SourceBuffer fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SourceBuffer> getRange(int start, int end) =>
@@ -21687,6 +22311,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechGrammar removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -21707,16 +22339,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechGrammar> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechGrammar> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechGrammar initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechGrammar> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechGrammar fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechGrammar> getRange(int start, int end) =>
@@ -23428,6 +24064,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
TextTrackCue removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -23448,16 +24092,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<TextTrackCue> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<TextTrackCue> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [TextTrackCue initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<TextTrackCue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [TextTrackCue fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<TextTrackCue> getRange(int start, int end) =>
@@ -23645,6 +24293,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
TextTrack removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -23665,16 +24321,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<TextTrack> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<TextTrack> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [TextTrack initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<TextTrack> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [TextTrack fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<TextTrack> getRange(int start, int end) =>
@@ -24079,6 +24739,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Touch removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -24099,16 +24767,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Touch> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Touch> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Touch initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Touch> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Touch fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Touch> getRange(int start, int end) =>
@@ -24596,6 +25268,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -24616,16 +25296,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -24839,6 +25523,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -24859,16 +25551,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -25082,6 +25778,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -25102,16 +25806,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -25323,6 +26031,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
int removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -25343,16 +26059,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [int initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<int> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [int fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<int> getRange(int start, int end) =>
@@ -25638,6 +26358,23 @@
@DocsEditable
+@DomName('WebKitCSSRegionRule')
+class WebKitCssRegionRule extends CssRule {
+ WebKitCssRegionRule.internal() : super.internal();
+
+ @DomName('WebKitCSSRegionRule.cssRules')
+ @DocsEditable
+ List<CssRule> get cssRules native "WebKitCSSRegionRule_cssRules_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
@DomName('WebKitNamedFlow')
class WebKitNamedFlow extends EventTarget {
WebKitNamedFlow.internal() : super.internal();
@@ -26809,7 +27546,7 @@
const _BeforeUnloadEventStreamProvider(this._eventType);
Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
- var controller = new StreamController.broadcast();
+ var controller = new StreamController();
var stream = new _EventStream(e, _eventType, useCapture);
stream.listen((event) {
var wrapped = new _BeforeUnloadEvent(event);
@@ -27429,6 +28166,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Rect removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27449,16 +28194,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Rect> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Rect initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Rect> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Rect fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Rect> getRange(int start, int end) =>
@@ -27651,6 +28400,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
CssRule removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27671,16 +28428,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<CssRule> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<CssRule> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [CssRule initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<CssRule> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [CssRule fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<CssRule> getRange(int start, int end) =>
@@ -27860,6 +28621,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
_CSSValue removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -27880,16 +28649,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<_CSSValue> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<_CSSValue> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [_CSSValue initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<_CSSValue> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [_CSSValue fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<_CSSValue> getRange(int start, int end) =>
@@ -28305,6 +29078,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Entry removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -28325,16 +29106,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Entry> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Entry> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Entry initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Entry> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Entry fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Entry> getRange(int start, int end) =>
@@ -28514,6 +29299,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
_EntrySync removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -28534,16 +29327,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<_EntrySync> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<_EntrySync> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [_EntrySync initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<_EntrySync> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [_EntrySync fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<_EntrySync> getRange(int start, int end) =>
@@ -28784,6 +29581,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Gamepad removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -28804,16 +29609,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Gamepad> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Gamepad> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Gamepad initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Gamepad> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Gamepad fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Gamepad> getRange(int start, int end) =>
@@ -29084,6 +29893,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Node removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -29104,16 +29921,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Node> getRange(int start, int end) =>
@@ -29378,6 +30199,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechInputResult removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -29398,16 +30227,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechInputResult> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechInputResult> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechInputResult initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechInputResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechInputResult fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechInputResult> getRange(int start, int end) =>
@@ -29587,6 +30420,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
SpeechRecognitionResult removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -29607,16 +30448,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<SpeechRecognitionResult> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<SpeechRecognitionResult> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [SpeechRecognitionResult initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<SpeechRecognitionResult> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [SpeechRecognitionResult fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<SpeechRecognitionResult> getRange(int start, int end) =>
@@ -29796,6 +30641,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
StyleSheet removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -29816,16 +30669,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<StyleSheet> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<StyleSheet> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [StyleSheet initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<StyleSheet> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [StyleSheet fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<StyleSheet> getRange(int start, int end) =>
@@ -30604,9 +31461,9 @@
bool get isBroadcast => true;
StreamSubscription<T> listen(void onData(T event),
- { void onError(AsyncError error),
- void onDone(),
- bool unsubscribeOnError}) {
+ { void onError(error),
+ void onDone(),
+ bool cancelOnError}) {
return new _EventStreamSubscription<T>(
this._target, this._eventType, onData, this._useCapture);
@@ -30648,7 +31505,7 @@
}
/// Has no effect.
- void onError(void handleError(AsyncError error)) {}
+ void onError(void handleError(error)) {}
/// Has no effect.
void onDone(void handleDone()) {}
@@ -30682,6 +31539,12 @@
_target.$dom_removeEventListener(_eventType, _onData, _useCapture);
}
}
+
+ Future asFuture([var futureValue]) {
+ // We just need a future that will never succeed or fail.
+ Completer completer = new Completer();
+ return completer.future;
+ }
}
@@ -30771,7 +31634,7 @@
static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
/** Controller to produce KeyEvents for the stream. */
- final StreamController _controller = new StreamController.broadcast();
+ final StreamController _controller = new StreamController();
static const _EVENT_TYPE = 'KeyEvent';
@@ -31992,14 +32855,14 @@
// Catch and report them a global exceptions.
try {
if (node._hasLocalModel != true && node._model != model &&
- node._modelChangedStream != null) {
+ node._modelChangedStreams != null &&
+ !node._modelChangedStreams.isEmpty) {
node._model = model;
- node._modelChangedStream.add(node);
+ node._modelChangedStreams.toList()
+ .forEach((controller) => controller.add(node));
}
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError(e, s).throwDelayed();
+ new Future.error(e, s);
}
for (var child = node.$dom_firstChild; child != null;
child = child.nextNode) {
@@ -32391,6 +33254,12 @@
void insert(int index, E element) => _list.insert(index, element);
+ void insertAll(int index, Iterable<E> iterable) =>
+ _list.insertAll(index, iterable);
+
+ void setAll(int index, Iterable<E> iterable) =>
+ _list.setAll(index, iterable);
+
E removeAt(int index) => _list.removeAt(index);
E removeLast() => _list.removeLast();
@@ -32399,14 +33268,18 @@
Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
- void setRange(int start, int length, List<E> from, [int startFrom]) {
- _list.setRange(start, length, from, startFrom);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ _list.setRange(start, end, iterable, skipCount);
}
- void removeRange(int start, int length) { _list.removeRange(start, length); }
+ void removeRange(int start, int end) { _list.removeRange(start, end); }
- void insertRange(int start, int length, [E fill]) {
- _list.insertRange(start, length, fill);
+ void replaceRange(int start, int end, Iterable<E> iterable) {
+ _list.replaceRange(start, end, iterable);
+ }
+
+ void fillRange(int start, int end, [E fillValue]) {
+ _list.fillRange(start, end, fillValue);
}
Map<int, E> asMap() => _list.asMap();
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index bb253e6..0efe3d5 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -46,7 +46,7 @@
throw new ArgumentError("Invalid list length");
}
- removeRange(newLength, len - newLength);
+ removeRange(newLength, len);
}
String join([String separator = ""]) => _filtered.join(separator);
@@ -71,18 +71,23 @@
throw new UnsupportedError('TODO(jacobr): should we impl?');
}
- void setRange(int start, int rangeLength, List from, [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
throw new UnimplementedError();
}
- void removeRange(int start, int rangeLength) {
- _filtered.sublist(start, start + rangeLength).forEach((el) => el.remove());
+ void fillRange(int start, int end, [Element fillValue]) {
+ throw new UnimplementedError();
}
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void replaceRange(int start, int end, Iterable<Element> iterable) {
throw new UnimplementedError();
}
+ void removeRange(int start, int end) {
+ _filtered.sublist(start, end).forEach((el) => el.remove());
+ }
+
void clear() {
// Currently, ElementList#clear clears even non-element nodes, so we follow
// that behavior.
@@ -105,6 +110,10 @@
_childNodes.insert(index, value);
}
+ void insertAll(int index, Iterable<Element> iterable) {
+ _childNodes.insertAll(index, iterable);
+ }
+
Element removeAt(int index) {
final result = this[index];
result.remove();
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index a6d84a6..cdd2742 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -143,7 +143,7 @@
try {
return _completeRequest($dom_delete());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -152,7 +152,7 @@
try {
return _completeRequest($dom_update(value));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -367,7 +367,7 @@
{int version, void onUpgradeNeeded(VersionChangeEvent),
void onBlocked(Event)}) {
if ((version == null) != (onUpgradeNeeded == null)) {
- return new Future.immediateError(new ArgumentError(
+ return new Future.error(new ArgumentError(
'version and onUpgradeNeeded must be specified together'));
}
try {
@@ -386,7 +386,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -401,7 +401,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -414,7 +414,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -492,7 +492,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -503,7 +503,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -514,7 +514,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -714,7 +714,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -723,7 +723,7 @@
try {
return _completeRequest($dom_clear());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -732,7 +732,7 @@
try {
return _completeRequest($dom_delete(key_OR_keyRange));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -747,7 +747,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -762,7 +762,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -773,7 +773,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index 6fad318..87c0ebe 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -45,7 +45,7 @@
try {
return _completeRequest($dom_delete());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -54,7 +54,7 @@
try {
return _completeRequest($dom_update(value));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -261,7 +261,7 @@
{int version, void onUpgradeNeeded(VersionChangeEvent),
void onBlocked(Event)}) {
if ((version == null) != (onUpgradeNeeded == null)) {
- return new Future.immediateError(new ArgumentError(
+ return new Future.error(new ArgumentError(
'version and onUpgradeNeeded must be specified together'));
}
try {
@@ -280,7 +280,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -295,7 +295,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -308,7 +308,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -388,7 +388,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -399,7 +399,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -410,7 +410,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -749,7 +749,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -758,7 +758,7 @@
try {
return _completeRequest($dom_clear());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -767,7 +767,7 @@
try {
return _completeRequest($dom_delete(key_OR_keyRange));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -782,7 +782,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -797,7 +797,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -808,7 +808,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/sdk/lib/io/buffer_list.dart b/sdk/lib/io/buffer_list.dart
index 25a4fdd..72dc92f 100644
--- a/sdk/lib/io/buffer_list.dart
+++ b/sdk/lib/io/buffer_list.dart
@@ -94,19 +94,15 @@
while (remaining > 0) {
int bytesInFirst = _buffers.first.length - _index;
if (bytesInFirst <= remaining) {
- result.setRange(count - remaining,
- bytesInFirst,
- _buffers.first,
- _index);
+ int startIndex = count - remaining;
+ int endIndex = startIndex + bytesInFirst;
+ result.setRange(startIndex, endIndex, _buffers.first, _index);
_buffers.removeFirst();
_index = 0;
_length -= bytesInFirst;
remaining -= bytesInFirst;
} else {
- result.setRange(count - remaining,
- remaining,
- _buffers.first,
- _index);
+ result.setRange(count - remaining, count, _buffers.first, _index);
_index = remaining;
_length -= remaining;
remaining = 0;
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index f4d6907..9350ad6 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -58,26 +58,36 @@
// Object for holding a buffer and an offset.
-class _BufferAndOffset {
- _BufferAndOffset(List this.buffer, int this.offset);
+class _BufferAndStart {
+ _BufferAndStart(List this.buffer, int this.start);
List buffer;
- int offset;
+ int start;
}
// Ensure that the input List can be serialized through a native port.
// Only builtin Lists can be serialized through. If user-defined Lists
// get here, the contents is copied to a Uint8List. This has the added
// benefit that it is faster to access from the C code as well.
-_BufferAndOffset _ensureFastAndSerializableBuffer(
- List buffer, int offset, int bytes) {
+_BufferAndStart _ensureFastAndSerializableBuffer(
+ List buffer, int start, int end) {
if (buffer is Uint8List ||
buffer is Int8List ||
+ buffer is Uint16List ||
+ buffer is Int16List ||
+ buffer is Uint32List ||
+ buffer is Int32List ||
+ buffer is Uint64List ||
+ buffer is Int64List ||
+ buffer is ByteData ||
+ buffer is Float32List ||
+ buffer is Float64List ||
_BufferUtils._isBuiltinList(buffer)) {
- return new _BufferAndOffset(buffer, offset);
+ return new _BufferAndStart(buffer, start);
}
- var newBuffer = new Uint8List(bytes);
- int j = offset;
- for (int i = 0; i < bytes; i++) {
+ int length = end - start;
+ var newBuffer = new Uint8List(length);
+ int j = start;
+ for (int i = 0; i < length; i++) {
int value = buffer[j];
if (value is! int) {
throw new ArgumentError("List element is not an integer at index $j");
@@ -85,7 +95,7 @@
newBuffer[i] = value;
j++;
}
- return new _BufferAndOffset(newBuffer, 0);
+ return new _BufferAndStart(newBuffer, 0);
}
diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart
index cb7d705..4a4001d 100644
--- a/sdk/lib/io/data_transformer.dart
+++ b/sdk/lib/io/data_transformer.dart
@@ -51,7 +51,8 @@
}
} catch (e, s) {
_closed = true;
- sink.addError(new AsyncError(e, s));
+ // TODO(floitsch): we are losing the stack trace.
+ sink.addError(e);
sink.close();
}
}
@@ -65,7 +66,8 @@
sink.add(out);
}
} catch (e, s) {
- sink.addError(new AsyncError(e, s));
+ // TODO(floitsch): we are losing the stack trace.
+ sink.addError(e);
_closed = true;
}
if (!_closed) _filter.end();
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 6b6cc38..3aaf219 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -64,14 +64,14 @@
} else {
future = future.then((index) {
if (index != notFound) {
- return new Future.immediate(index);
+ return new Future.value(index);
}
return dirsToCreate[i].exists().then((e) => e ? i : notFound);
});
}
}
if (future == null) {
- return new Future.immediate(notFound);
+ return new Future.value(notFound);
} else {
return future;
}
@@ -100,7 +100,7 @@
}
}
if (future == null) {
- return new Future.immediate(this);
+ return new Future.value(this);
} else {
return future.then((_) => this);
}
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 4ebaa70..20110af 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -205,8 +205,8 @@
* has an [:encoding:] property which can be changed after the
* [IOSink] has been created.
*/
- IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
- Encoding encoding: Encoding.UTF_8});
+ IOSink openWrite({FileMode mode: FileMode.WRITE,
+ Encoding encoding: Encoding.UTF_8});
/**
* Read the entire file contents as a list of bytes. Returns a
@@ -368,20 +368,26 @@
List<int> readSync(int bytes);
/**
- * Reads into an existing List<int> from the file. A maximum of [bytes] bytes
- * is read into [buffer], starting at position [offset] in the buffer.
+ * Reads into an existing List<int> from the file. If [start] is present, the
+ * bytes will be filled into [buffer] from at index [start], otherwise index
+ * 0. If [end] is present, the [end] - [start] bytes will be read into
+ * [buffer], otherwise up to [buffer.length]. If [end] == [start] nothing
+ * happends.
+ *
* Returns a [:Future<int>:] that completes with the number of bytes read.
*/
- Future<int> readList(List<int> buffer, int offset, int bytes);
+ Future<int> readInto(List<int> buffer, [int start, int end]);
/**
- * Synchronously reads from a file into [buffer]. A maximum of [bytes] bytes
- * is read into [buffer], starting at position [offset] in the buffer.
- * Returns the number of bytes read.
+ * Synchronously reads into an existing List<int> from the file. If [start] is
+ * present, the bytes will be filled into [buffer] from at index [start],
+ * otherwise index 0. If [end] is present, the [end] - [start] bytes will be
+ * read into [buffer], otherwise up to [buffer.length]. If [end] == [start]
+ * nothing happends.
*
* Throws a [FileIOException] if the operation fails.
*/
- int readListSync(List<int> buffer, int offset, int bytes);
+ int readIntoSync(List<int> buffer, [int start, int end]);
/**
* Writes a single byte to the file. Returns a
@@ -399,21 +405,24 @@
int writeByteSync(int value);
/**
- * Writes from a List<int> to the file. [bytes] bytes are written from
- * [buffer], starting at position [offset] in the buffer. Returns a
- * [:Future<RandomAccessFile>:] that completes with this
- * RandomAccessFile when the write completes.
+ * Writes from a [List<int>] to the file. It will read the buffer from index
+ * [start] to index [end]. If [start] is omitted, it'll start from index 0.
+ * If [end] is omitted, it will write to end of [buffer].
+ *
+ * Returns a [:Future<RandomAccessFile>:] that completes with this
+ * [RandomAccessFile] when the write completes.
*/
- Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes);
+ Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]);
/**
- * Synchronously writes a List<int> to the file. [bytes] bytes are
- * written from [buffer], starting at position [offset] in the
- * buffer. Returns the number of bytes successfully written.
+ * Synchronously writes from a [List<int>] to the file. It will read the
+ * buffer from index [start] to index [end]. If [start] is omitted, it'll
+ * start from index 0. If [end] is omitted, it will write to the end of
+ * [buffer].
*
* Throws a [FileIOException] if the operation fails.
*/
- int writeListSync(List<int> buffer, int offset, int bytes);
+ void writeFromSync(List<int> buffer, [int start, int end]);
/**
* Writes a string to the file using the given [Encoding]. Returns a
@@ -425,13 +434,12 @@
/**
* Synchronously writes a single string to the file using the given
- * [Encoding]. Returns the number of characters successfully
- * written.
+ * [Encoding].
*
* Throws a [FileIOException] if the operation fails.
*/
- int writeStringSync(String string,
- {Encoding encoding: Encoding.UTF_8});
+ void writeStringSync(String string,
+ {Encoding encoding: Encoding.UTF_8});
/**
* Gets the current byte position in the file. Returns a
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 65f7adf..a5ae2f5 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -36,19 +36,24 @@
}
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
void _setupController() {
_controller = new StreamController<List<int>>(
- onSubscriptionStateChange: _onSubscriptionStateChange,
- onPauseStateChange: _onPauseStateChange);
+ onListen: _start,
+ onPause: () => _paused = true,
+ onResume: _resume,
+ onCancel: () {
+ _unsubscribed = true;
+ _closeFile();
+ });
}
Future _closeFile() {
@@ -58,7 +63,7 @@
_openedFile = null;
return closeFuture;
} else {
- return new Future.immediate(null);
+ return new Future.value();
}
}
@@ -106,7 +111,7 @@
if (_path != null) {
openFuture = new File(_path).open(mode: FileMode.READ);
} else {
- openFuture = new Future.immediate(_File._openStdioSync(0));
+ openFuture = new Future.value(_File._openStdioSync(0));
}
openFuture
.then((RandomAccessFile opened) {
@@ -128,23 +133,6 @@
// Resume reading unless we are already done.
if (_openedFile != null) _readBlock();
}
-
- void _onSubscriptionStateChange() {
- if (_controller.hasListener) {
- _start();
- } else {
- _unsubscribed = true;
- _closeFile();
- }
- }
-
- void _onPauseStateChange() {
- if (_controller.isPaused) {
- _paused = true;
- } else {
- _resume();
- }
- }
}
class _FileStreamConsumer extends StreamConsumer<List<int>> {
@@ -158,11 +146,7 @@
_FileStreamConsumer.fromStdio(int fd) {
assert(1 <= fd && fd <= 2);
- _openFuture = new Future.immediate(_File._openStdioSync(fd));
- }
-
- Future<File> consume(Stream<List<int>> stream) {
- return addStream(stream).then((_) => close());
+ _openFuture = new Future.value(_File._openStdioSync(fd));
}
Future<File> addStream(Stream<List<int>> stream) {
@@ -172,7 +156,7 @@
_subscription = stream.listen(
(d) {
_subscription.pause();
- openedFile.writeList(d, 0, d.length)
+ openedFile.writeFrom(d, 0, d.length)
.then((_) => _subscription.resume())
.catchError((e) {
openedFile.close();
@@ -186,7 +170,7 @@
openedFile.close();
completer.completeError(e);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
})
.catchError((e) {
completer.completeError(e);
@@ -476,15 +460,15 @@
return new _FileStream(_path);
}
- IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
- Encoding encoding: Encoding.UTF_8}) {
+ IOSink openWrite({FileMode mode: FileMode.WRITE,
+ Encoding encoding: Encoding.UTF_8}) {
if (mode != FileMode.WRITE &&
mode != FileMode.APPEND) {
throw new FileIOException(
"Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
}
var consumer = new _FileStreamConsumer(this, mode);
- return new IOSink<File>(consumer, encoding: encoding);
+ return new IOSink(consumer, encoding: encoding);
}
Future<List<int>> readAsBytes() {
@@ -501,7 +485,7 @@
onError: (e) {
completer.completeError(e);
},
- unsubscribeOnError: true);
+ cancelOnError: true);
return completer.future;
}
@@ -556,18 +540,18 @@
Future<File> writeAsBytes(List<int> bytes,
{FileMode mode: FileMode.WRITE}) {
try {
- IOSink<File> sink = openWrite(mode: mode);
+ IOSink sink = openWrite(mode: mode);
sink.add(bytes);
sink.close();
return sink.done.then((_) => this);;
} catch (e) {
- return new Future.immediateError(e);
+ return new Future.error(e);
}
}
void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE}) {
RandomAccessFile opened = openSync(mode: mode);
- opened.writeListSync(bytes, 0, bytes.length);
+ opened.writeFromSync(bytes, 0, bytes.length);
opened.closeSync();
}
@@ -715,57 +699,59 @@
return result;
}
- Future<int> readList(List<int> buffer, int offset, int bytes) {
+ Future<int> readInto(List<int> buffer, [int start, int end]) {
_ensureFileService();
- Completer<int> completer = new Completer<int>();
- if (buffer is !List || offset is !int || bytes is !int) {
- // Complete asynchronously so the user has a chance to setup
- // handlers without getting exceptions when registering the
- // then handler.
- Timer.run(() {
- completer.completeError(new FileIOException(
- "Invalid arguments to readList for file '$_path'"));
- });
- return completer.future;
+ if (buffer is !List ||
+ (start != null && start is !int) ||
+ (end != null && end is !int)) {
+ return new Future.error(new FileIOException(
+ "Invalid arguments to readInto for file '$_path'"));
};
+ Completer<int> completer = new Completer<int>();
if (closed) return _completeWithClosedException(completer);
List request = new List(3);
+ if (start == null) start = 0;
+ if (end == null) end = buffer.length;
request[0] = _READ_LIST_REQUEST;
request[1] = _id;
- request[2] = bytes;
+ request[2] = end - start;
return _fileService.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
- "readList failed for file '$_path'");
+ "readInto failed for file '$_path'");
}
var read = response[1];
var data = response[2];
- buffer.setRange(offset, read, data);
+ buffer.setRange(start, start + read, data);
return read;
});
}
- static void _checkReadWriteListArguments(int length, int offset, int bytes) {
- if (offset < 0) throw new RangeError.value(offset);
- if (bytes < 0) throw new RangeError.value(bytes);
- if ((offset + bytes) > length) {
- throw new RangeError.value(offset + bytes);
+ static void _checkReadWriteListArguments(int length, int start, int end) {
+ if (start < 0) throw new RangeError.value(start);
+ if (end < start) throw new RangeError.value(end);
+ if (end > length) {
+ throw new RangeError.value(end);
}
}
- external static _readList(int id, List<int> buffer, int offset, int bytes);
+ external static _readInto(int id, List<int> buffer, int start, int end);
- int readListSync(List<int> buffer, int offset, int bytes) {
+ int readIntoSync(List<int> buffer, [int start, int end]) {
_checkNotClosed();
- if (buffer is !List || offset is !int || bytes is !int) {
+ if (buffer is !List ||
+ (start != null && start is !int) ||
+ (end != null && end is !int)) {
throw new FileIOException(
- "Invalid arguments to readList for file '$_path'");
+ "Invalid arguments to readInto for file '$_path'");
}
- if (bytes == 0) return 0;
- _checkReadWriteListArguments(buffer.length, offset, bytes);
- var result = _readList(_id, buffer, offset, bytes);
+ if (start == null) start = 0;
+ if (end == null) end = buffer.length;
+ if (end == start) return 0;
+ _checkReadWriteListArguments(buffer.length, start, end);
+ var result = _readInto(_id, buffer, start, end);
if (result is OSError) {
- throw new FileIOException("readList failed for file '$_path'",
+ throw new FileIOException("readInto failed for file '$_path'",
result);
}
return result;
@@ -814,65 +800,63 @@
return result;
}
- Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) {
+ Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) {
_ensureFileService();
- Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
- if (buffer is !List || offset is !int || bytes is !int) {
- // Complete asynchronously so the user has a chance to setup
- // handlers without getting exceptions when registering the
- // then handler.
- Timer.run(() {
- completer.completeError(new FileIOException(
- "Invalid arguments to writeList for file '$_path'"));
- });
- return completer.future;
+ if ((buffer is !List && buffer is !ByteData) ||
+ (start != null && start is !int) ||
+ (end != null && end is !int)) {
+ return new Future.error(new FileIOException(
+ "Invalid arguments to writeFrom for file '$_path'"));
}
+ Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
+
if (closed) return _completeWithClosedException(completer);
- _BufferAndOffset result;
+ _BufferAndStart result;
try {
- result = _ensureFastAndSerializableBuffer(buffer, offset, bytes);
+ result = _ensureFastAndSerializableBuffer(buffer, start, end);
} catch (e) {
- // Complete asynchronously so the user has a chance to setup
- // handlers without getting exceptions when registering the
- // then handler.
- Timer.run(() => completer.completeError(e));
- return completer.future;
+ return new Future.error(e);
}
List request = new List(5);
request[0] = _WRITE_LIST_REQUEST;
request[1] = _id;
request[2] = result.buffer;
- request[3] = result.offset;
- request[4] = bytes;
+ request[3] = result.start;
+ request[4] = end - (start - result.start);
return _fileService.call(request).then((response) {
if (_isErrorResponse(response)) {
throw _exceptionFromResponse(response,
- "writeList failed for file '$_path'");
+ "writeFrom failed for file '$_path'");
}
return this;
});
}
- external static _writeList(int id, List<int> buffer, int offset, int bytes);
+ external static _writeFrom(int id, List<int> buffer, int start, int end);
- int writeListSync(List<int> buffer, int offset, int bytes) {
+ void writeFromSync(List<int> buffer, [int start, int end]) {
_checkNotClosed();
- if (buffer is !List || offset is !int || bytes is !int) {
+ if (buffer is !List ||
+ (start != null && start is !int) ||
+ (end != null && end is !int)) {
throw new FileIOException(
- "Invalid arguments to writeList for file '$_path'");
+ "Invalid arguments to writeFrom for file '$_path'");
}
- if (bytes == 0) return 0;
- _checkReadWriteListArguments(buffer.length, offset, bytes);
- _BufferAndOffset bufferAndOffset =
- _ensureFastAndSerializableBuffer(buffer, offset, bytes);
- var result =
- _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
+ if (start == null) start = 0;
+ if (end == null) end = buffer.length;
+ if (end == start) return;
+ _checkReadWriteListArguments(buffer.length, start, end);
+ _BufferAndStart bufferAndStart =
+ _ensureFastAndSerializableBuffer(buffer, start, end);
+ var result = _writeFrom(_id,
+ bufferAndStart.buffer,
+ bufferAndStart.start,
+ end - (start - bufferAndStart.start));
if (result is OSError) {
- throw new FileIOException("writeList failed for file '$_path'", result);
+ throw new FileIOException("writeFrom failed for file '$_path'", result);
}
- return result;
}
Future<RandomAccessFile> writeString(String string,
@@ -886,16 +870,16 @@
return completer.future;
}
var data = _encodeString(string, encoding);
- return writeList(data, 0, data.length);
+ return writeFrom(data, 0, data.length);
}
- int writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) {
+ void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) {
if (encoding is! Encoding) {
throw new FileIOException(
"Invalid encoding in writeStringSync: $encoding");
}
var data = _encodeString(string, encoding);
- return writeListSync(data, 0, data.length);
+ writeFromSync(data, 0, data.length);
}
Future<int> position() {
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 72fd67c..21830f2 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -509,6 +509,11 @@
}
/**
+ * Gets the mime-type, without any parameters.
+ */
+ String get mimeType;
+
+ /**
* Gets the primary type.
*/
String get primaryType;
@@ -703,7 +708,7 @@
* If an unsupported encoding is used an exception will be thrown if
* using one of the write methods taking a string.
*/
-abstract class HttpResponse implements IOSink<HttpResponse> {
+abstract class HttpResponse implements IOSink {
// TODO(ajohnsen): Add documentation of how to pipe a file to the response.
/**
* Gets and sets the content length of the response. If the size of
@@ -926,12 +931,12 @@
*
* The following environment variables are taken into account:
*
- * * http_proxy
- * * https_proxy
- * * no_proxy
- * * HTTP_PROXY
- * * HTTPS_PROXY
- * * NO_PROXY
+ * http_proxy
+ * https_proxy
+ * no_proxy
+ * HTTP_PROXY
+ * HTTPS_PROXY
+ * NO_PROXY
*
* [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for
* http:// urls. Use the format [:hostname:port:]. If no port is used a
@@ -963,6 +968,12 @@
* return HttpClient.findProxyFromEnvironment(
* url, {"http_proxy": ..., "no_proxy": ...});
* }
+ *
+ * If a proxy requires authentication it is possible to configure
+ * the username and password as well. Use the format
+ * [:username:password@hostname:port:] to include the username and
+ * password. Alternatively the API [addProxyCredentials] can be used
+ * to set credentials for proxies which require authentication.
*/
static String findProxyFromEnvironment(Uri url,
{Map<String, String> environment}) {
@@ -970,6 +981,34 @@
}
/**
+ * Sets the function to be called when a proxy is requesting
+ * authentication. Information on the proxy in use and the security
+ * realm for the authentication are passed in the arguments [host],
+ * [port] and [realm].
+ *
+ * The function returns a [Future] which should complete when the
+ * authentication has been resolved. If credentials cannot be
+ * provided the [Future] should complete with [false]. If
+ * credentials are available the function should add these using
+ * [addProxyCredentials] before completing the [Future] with the value
+ * [true].
+ *
+ * If the [Future] completes with [true] the request will be retried
+ * using the updated credentials. Otherwise response processing will
+ * continue normally.
+ */
+ set authenticateProxy(
+ Future<bool> f(String host, int port, String scheme, String realm));
+
+ /**
+ * Add credentials to be used for authorizing HTTP proxies.
+ */
+ void addProxyCredentials(String host,
+ int port,
+ String realm,
+ HttpClientCredentials credentials);
+
+ /**
* Shutdown the HTTP client. If [force] is [:false:] (the default)
* the [:HttpClient:] will be kept alive until all active
* connections are done. If [force] is [:true:] any active
@@ -1012,8 +1051,7 @@
* If an unsupported encoding is used an exception will be thrown if
* using one of the write methods taking a string.
*/
-abstract class HttpClientRequest
- implements IOSink<HttpClientResponse> {
+abstract class HttpClientRequest implements IOSink {
/**
* Gets and sets the content length of the request. If the size of
* the request is not known in advance set content length to -1,
diff --git a/sdk/lib/io/http_body_impl.dart b/sdk/lib/io/http_body_impl.dart
index 4bd9f81..214daa3 100644
--- a/sdk/lib/io/http_body_impl.dart
+++ b/sdk/lib/io/http_body_impl.dart
@@ -47,22 +47,25 @@
.then((list) {
dynamic content = list.readBytes();
String type = "binary";
- String mimeType = headers.contentType.toString();
+ ContentType contentType = headers.contentType;
+ if (contentType == null) {
+ return new _HttpBody(null, type, content);
+ }
String asText(Encoding defaultEncoding) {
var encoding;
- var charset = headers.contentType.charset;
+ var charset = contentType.charset;
if (charset != null) encoding = Encoding.fromName(charset);
if (encoding == null) encoding = defaultEncoding;
return _decodeString(content, encoding);
}
- switch (headers.contentType.primaryType) {
+ switch (contentType.primaryType) {
case "text":
type = "text";
content = asText(Encoding.ASCII);
break;
case "application":
- switch (headers.contentType.subType) {
+ switch (contentType.subType) {
case "json":
content = JSON.parse(asText(Encoding.UTF_8));
type = "json";
@@ -76,7 +79,7 @@
default:
break;
}
- return new _HttpBody(mimeType, type, content);
+ return new _HttpBody(contentType.mimeType, type, content);
});
}
}
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 261f1cd..919761a 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -48,7 +48,7 @@
if (values != null) {
int index = values.indexOf(value);
if (index != -1) {
- values.removeRange(index, 1);
+ values.removeRange(index, index + 1);
}
if (values.length == 0) _headers.remove(name);
}
@@ -632,6 +632,8 @@
}
}
+ String get mimeType => '$primaryType/$subType';
+
String get primaryType => _primaryType;
String get subType => _subType;
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index cea3e11..6477f3a 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -35,13 +35,13 @@
}
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
// Is completed once all data have been received.
@@ -106,13 +106,13 @@
}
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _incoming.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
Map<String, String> get queryParameters {
@@ -215,7 +215,7 @@
if (followLoops != true) {
for (var redirect in redirects) {
if (redirect.location == url) {
- return new Future.immediateError(
+ return new Future.error(
new RedirectLoopException(redirects));
}
}
@@ -231,9 +231,9 @@
}
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
var stream = _incoming;
if (headers.value(HttpHeaders.CONTENT_ENCODING) == "gzip") {
stream = stream.transform(new ZLibInflater());
@@ -241,7 +241,7 @@
return stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
Future<Socket> detachSocket() {
@@ -251,6 +251,13 @@
HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
+ bool get _shouldAuthenticateProxy {
+ // Only try to authenticate if there is a challenge in the response.
+ List<String> challenge = headers[HttpHeaders.PROXY_AUTHENTICATE];
+ return statusCode == HttpStatus.PROXY_AUTHENTICATION_REQUIRED &&
+ challenge != null && challenge.length == 1;
+ }
+
bool get _shouldAuthenticate {
// Only try to authenticate if there is a challenge in the response.
List<String> challenge = headers[HttpHeaders.WWW_AUTHENTICATE];
@@ -275,7 +282,7 @@
// Fall through to here to perform normal response handling if
// there is no sensible authorization handling.
- return new Future.immediate(this);
+ return new Future.value(this);
}
List<String> challenge = headers[HttpHeaders.WWW_AUTHENTICATE];
@@ -315,8 +322,56 @@
}
});
}
+
// No credentials were found and the callback was not set.
- return new Future.immediate(this);
+ return new Future.value(this);
+ }
+
+ Future<HttpClientResponse> _authenticateProxy() {
+ Future<HttpClientResponse> retryWithProxyCredentials(_ProxyCredentials cr) {
+ return fold(null, (x, y) {}).then((_) {
+ return _httpClient._openUrlFromRequest(_httpRequest.method,
+ _httpRequest.uri,
+ _httpRequest)
+ .then((request) => request.close());
+ });
+ }
+
+ List<String> challenge = headers[HttpHeaders.PROXY_AUTHENTICATE];
+ assert(challenge != null || challenge.length == 1);
+ _HeaderValue header =
+ new _HeaderValue.fromString(challenge[0], parameterSeparator: ",");
+ _AuthenticationScheme scheme =
+ new _AuthenticationScheme.fromString(header.value);
+ String realm = header.parameters["realm"];
+
+ // See if any credentials are available.
+ var proxy = _httpRequest._proxy;
+
+ var cr = _httpClient._findProxyCredentials(proxy);
+ if (cr != null) {
+ return retryWithProxyCredentials(cr);
+ }
+
+ // Ask for more credentials if none found.
+ if (_httpClient._authenticateProxy != null) {
+ Future authComplete = _httpClient._authenticateProxy(proxy.host,
+ proxy.port,
+ "basic",
+ realm);
+ return authComplete.then((credsAvailable) {
+ if (credsAvailable) {
+ var cr = _httpClient._findProxyCredentials(proxy);
+ return retryWithProxyCredentials(cr);
+ } else {
+ // No credentials available, complete with original response.
+ return this;
+ }
+ });
+ }
+
+ // No credentials were found and the callback was not set.
+ return new Future.value(this);
}
}
@@ -326,16 +381,21 @@
// requests and in error handling.
bool _ignoreBody = false;
bool _headersWritten = false;
+ bool _asGZip = false;
- IOSink _ioSink;
+ IOSink _headersSink;
+ IOSink _dataSink;
+
final _HttpOutgoing _outgoing;
final _HttpHeaders headers;
_HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing)
: _outgoing = outgoing,
- _ioSink = new IOSink(outgoing, encoding: Encoding.ASCII),
- headers = new _HttpHeaders(protocolVersion);
+ _headersSink = new IOSink(outgoing, encoding: Encoding.ASCII),
+ headers = new _HttpHeaders(protocolVersion) {
+ _dataSink = new IOSink(new _HttpOutboundConsumer(this));
+ }
int get contentLength => headers.contentLength;
void set contentLength(int contentLength) {
@@ -362,93 +422,44 @@
}
void write(Object obj) {
- _writeHeaders();
- // This comment is copied from runtime/lib/string_buffer_patch.dart.
- // TODO(srdjan): The following four lines could be replaced by
- // '$obj', but apparently this is too slow on the Dart VM.
- String string;
- if (obj is String) {
- string = obj;
- } else {
- string = obj.toString();
- if (string is! String) {
- throw new ArgumentError('toString() did not return a string');
- }
- }
- if (string.isEmpty) return;
- _ioSink.write(string);
+ _dataSink.write(obj);
}
void writeAll(Iterable objects, [String separator = ""]) {
- bool isFirst = true;
- for (Object obj in objects) {
- if (isFirst) {
- isFirst = false;
- } else {
- if (!separator.isEmpty) write(separator);
- }
- write(obj);
- }
+ _dataSink.writeAll(objects, separator);
}
void writeln([Object obj = ""]) {
- write(obj);
- write("\n");
+ _dataSink.writeln(obj);
}
void writeCharCode(int charCode) {
- write(new String.fromCharCode(charCode));
+ _dataSink.writeCharCode(charCode);
}
void add(List<int> data) {
- _writeHeaders();
if (data.length == 0) return;
- _ioSink.add(data);
+ _dataSink.add(data);
}
- void addError(AsyncError error) {
- _writeHeaders();
- _ioSink.addError(error);
- }
-
- Future<T> consume(Stream<List<int>> stream) {
- _writeHeaders();
- return _ioSink.consume(stream);
+ void addError(error) {
+ _dataSink.addError(error);
}
Future<T> addStream(Stream<List<int>> stream) {
- _writeHeaders();
- return _ioSink.writeStream(stream).then((_) => this);
- }
-
- Future<T> writeStream(Stream<List<int>> stream) {
- return addStream(stream);
+ return _dataSink.addStream(stream);
}
Future close() {
- // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and
- // persistentConnection is not guaranteed to be in sync.
- if (!_headersWritten && !_ignoreBody && headers.contentLength == -1) {
- // If no body was written, _ignoreBody is false (it's not a HEAD
- // request) and the content-length is unspecified, set contentLength to 0.
- headers.chunkedTransferEncoding = false;
- headers.contentLength = 0;
- }
- _writeHeaders();
- return _ioSink.close();
+ return _dataSink.close();
}
- Future<T> get done {
- _writeHeaders();
- return _ioSink.done;
- }
+ Future<T> get done => _dataSink.done;
void _writeHeaders() {
if (_headersWritten) return;
_headersWritten = true;
- _ioSink.encoding = Encoding.ASCII;
headers._synchronize(); // Be sure the 'chunked' option is updated.
- bool asGZip = false;
bool isServerSide = this is _HttpResponse;
if (isServerSide && headers.chunkedTransferEncoding) {
var response = this;
@@ -461,30 +472,50 @@
.any((encoding) => encoding.trim().toLowerCase() == "gzip") &&
contentEncoding == null) {
headers.set(HttpHeaders.CONTENT_ENCODING, "gzip");
- asGZip = true;
+ _asGZip = true;
}
}
_writeHeader();
- _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip));
- _ioSink.encoding = encoding;
}
- Future _consume(IOSink ioSink, Stream<List<int>> stream, bool asGZip) {
+ Future _addStream(Stream<List<int>> stream) {
+ _writeHeaders();
int contentLength = headers.contentLength;
if (_ignoreBody) {
- ioSink.close();
- return stream.fold(null, (x, y) {}).then((_) => this);
+ stream.fold(null, (x, y) {}).catchError((_) {});
+ return _headersSink.close();
}
stream = stream.transform(new _BufferTransformer());
if (headers.chunkedTransferEncoding) {
- if (asGZip) {
+ if (_asGZip) {
stream = stream.transform(new ZLibDeflater(gzip: true, level: 6));
}
stream = stream.transform(new _ChunkedTransformer());
} else if (contentLength >= 0) {
stream = stream.transform(new _ContentLengthValidator(contentLength));
}
- return stream.pipe(ioSink).then((_) => this);
+ return _headersSink.addStream(stream);
+ }
+
+ Future _close() {
+ // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and
+ // persistentConnection is not guaranteed to be in sync.
+ if (!_headersWritten) {
+ if (!_ignoreBody && headers.contentLength == -1) {
+ // If no body was written, _ignoreBody is false (it's not a HEAD
+ // request) and the content-length is unspecified, set contentLength to
+ // 0.
+ headers.chunkedTransferEncoding = false;
+ headers.contentLength = 0;
+ } else if (!_ignoreBody && headers.contentLength > 0) {
+ _headersSink.close().catchError((_) {});
+ return new Future.error(new HttpException(
+ "No content while contentLength was specified to be greater "
+ " than 0: ${headers.contentLength}."));
+ }
+ }
+ _writeHeaders();
+ return _headersSink.close();
}
void _writeHeader(); // TODO(ajohnsen): Better name.
@@ -492,21 +523,82 @@
class _HttpOutboundConsumer implements StreamConsumer {
- Function _consume;
- IOSink _ioSink;
- bool _asGZip;
- _HttpOutboundConsumer(IOSink this._ioSink,
- Function this._consume,
- bool this._asGZip);
+ final _HttpOutboundMessage _outbound;
+ StreamController _controller;
+ StreamSubscription _subscription;
+ Completer _closeCompleter = new Completer();
+ Completer _completer;
- Future consume(var stream) => _consume(_ioSink, stream, _asGZip);
+ _HttpOutboundConsumer(_HttpOutboundMessage this._outbound);
+
+ void _onPause() {
+ if (_controller.isPaused) {
+ _subscription.pause();
+ } else {
+ _subscription.resume();
+ }
+ }
+
+ void _onListen() {
+ if (!_controller.hasListener && _subscription != null) {
+ _subscription.cancel();
+ }
+ }
+
+ _ensureController() {
+ if (_controller != null) return;
+ _controller = new StreamController(onPause: _onPause,
+ onResume: _onPause,
+ onListen: _onListen,
+ onCancel: _onListen);
+ _outbound._addStream(_controller.stream)
+ .then((_) {
+ _done();
+ _closeCompleter.complete(_outbound);
+ },
+ onError: (error) {
+ if (!_done(error)) {
+ _closeCompleter.completeError(error);
+ }
+ });
+ }
+
+ bool _done([error]) {
+ if (_completer == null) return false;
+ var tmp = _completer;
+ _completer = null;
+ if (error != null) {
+ tmp.completeError(error);
+ } else {
+ tmp.complete(_outbound);
+ }
+ return true;
+ }
Future addStream(var stream) {
- throw new UnimplementedError("_HttpOutboundConsumer.addStream");
+ _ensureController();
+ _completer = new Completer();
+ _subscription = stream.listen(
+ (data) {
+ _controller.add(data);
+ },
+ onDone: () {
+ _done();
+ },
+ onError: (error) {
+ _done(error);
+ },
+ cancelOnError: true);
+ return _completer.future;
}
Future close() {
- throw new UnimplementedError("_HttpOutboundConsumer.close");
+ Future closeOutbound() {
+ return _outbound._close().then((_) => _outbound);
+ }
+ if (_controller == null) return closeOutbound();
+ _controller.close();
+ return _closeCompleter.future.then((_) => closeOutbound());
}
}
@@ -574,8 +666,8 @@
// Close connection so the socket is 'free'.
close();
done.catchError((_) {
- // Catch any error on done, as they automatically will be propegated to
- // the websocket.
+ // Catch any error on done, as they automatically will be
+ // propagated to the websocket.
});
return future;
}
@@ -632,7 +724,7 @@
// Write headers.
headers._write(buffer);
writeCRLF();
- _ioSink.add(buffer.readBytes());
+ _headersSink.add(buffer.readBytes());
}
String _findReasonPhrase(int statusCode) {
@@ -705,7 +797,7 @@
final Completer<HttpClientResponse> _responseCompleter
= new Completer<HttpClientResponse>();
- final bool _usingProxy;
+ final _Proxy _proxy;
Future<HttpClientResponse> _response;
@@ -719,7 +811,7 @@
_HttpClientRequest(_HttpOutgoing outgoing,
Uri this.uri,
String this.method,
- bool this._usingProxy,
+ _Proxy this._proxy,
_HttpClient this._httpClient,
_HttpClientConnection this._httpClientConnection)
: super("1.1", outgoing) {
@@ -731,17 +823,13 @@
Future<HttpClientResponse> get done {
if (_response == null) {
- _response = Future.wait([_responseCompleter.future, super.done])
+ _response = Future.wait([_responseCompleter.future,
+ super.done])
.then((list) => list[0]);
}
return _response;
}
- Future<HttpClientResponse> consume(Stream<List<int>> stream) {
- super.consume(stream);
- return done;
- }
-
Future<HttpClientResponse> close() {
super.close();
return done;
@@ -774,13 +862,15 @@
} else {
// End with exception, too many redirects.
future = response.fold(null, (x, y) {})
- .then((_) => new Future.immediateError(
+ .then((_) => new Future.error(
new RedirectLimitExceededException(response.redirects)));
}
+ } else if (response._shouldAuthenticateProxy) {
+ future = response._authenticateProxy();
} else if (response._shouldAuthenticate) {
future = response._authenticate();
} else {
- future = new Future<HttpClientResponse>.immediate(response);
+ future = new Future<HttpClientResponse>.value(response);
}
future.then(
(v) => _responseCompleter.complete(v),
@@ -789,7 +879,7 @@
});
}
- void _onError(AsyncError error) {
+ void _onError(error) {
_responseCompleter.completeError(error);
}
@@ -802,7 +892,7 @@
writeSP();
// Send the path for direct connections and the whole URL for
// proxy connections.
- if (!_usingProxy) {
+ if (_proxy.isDirect) {
String path = uri.path;
if (path.length == 0) path = "/";
if (uri.query != "") {
@@ -837,7 +927,7 @@
// Write headers.
headers._write(buffer);
writeCRLF();
- _ioSink.add(buffer.readBytes());
+ _headersSink.add(buffer.readBytes());
}
}
@@ -863,7 +953,7 @@
header.add(hexDigits[length]);
} else {
while (length > 0) {
- header.insertRange(0, 1, hexDigits[length % 16]);
+ header.insert(0, hexDigits[length % 16]);
length = length >> 4;
}
}
@@ -888,11 +978,11 @@
void handleData(List<int> data, EventSink<List<int>> sink) {
_bytesWritten += data.length;
if (_bytesWritten > expectedContentLength) {
- sink.addError(new AsyncError(new HttpException(
+ sink.addError(new HttpException(
"Content size exceeds specified contentLength. "
"$_bytesWritten bytes written while expected "
"$expectedContentLength. "
- "[${new String.fromCharCodes(data)}]")));
+ "[${new String.fromCharCodes(data)}]"));
sink.close();
} else {
sink.add(data);
@@ -901,10 +991,10 @@
void handleDone(EventSink<List<int>> sink) {
if (_bytesWritten < expectedContentLength) {
- sink.addError(new AsyncError(new HttpException(
+ sink.addError(new HttpException(
"Content size below specified contentLength. "
" $_bytesWritten bytes written while expected "
- "$expectedContentLength.")));
+ "$expectedContentLength."));
}
sink.close();
}
@@ -913,29 +1003,25 @@
// Extends StreamConsumer as this is an internal type, only used to pipe to.
class _HttpOutgoing implements StreamConsumer<List<int>> {
- Function _onStream;
- final Completer _consumeCompleter = new Completer();
+ final Completer _doneCompleter = new Completer();
+ final StreamConsumer _consumer;
- Future onStream(Future callback(Stream<List<int>> stream)) {
- _onStream = callback;
- return _consumeCompleter.future;
- }
-
- Future consume(Stream<List<int>> stream) {
- _onStream(stream)
- .then((_) => _consumeCompleter.complete(),
- onError: _consumeCompleter.completeError);
- // Use .then to ensure a Future branch.
- return _consumeCompleter.future.then((_) => this);
- }
+ _HttpOutgoing(StreamConsumer this._consumer);
Future addStream(Stream<List<int>> stream) {
- throw new UnimplementedError("_HttpOutgoing.addStream");
+ return _consumer.addStream(stream)
+ .catchError((error) {
+ _doneCompleter.completeError(error);
+ throw error;
+ });
}
Future close() {
- throw new UnimplementedError("_HttpOutgoing.close");
+ _doneCompleter.complete(_consumer);
+ return new Future.value();
}
+
+ Future get done => _doneCompleter.future;
}
@@ -954,7 +1040,6 @@
_HttpClient this._httpClient)
: _httpParser = new _HttpParser.responseParser() {
_socket.pipe(_httpParser);
- _socket.done.catchError((e) { destroy(); });
// Set up handlers on the parser here, so we are sure to get 'onDone' from
// the parser.
@@ -980,23 +1065,35 @@
});
}
- _HttpClientRequest send(Uri uri, int port, String method, bool isDirect) {
+ _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
// Start with pausing the parser.
_subscription.pause();
- var outgoing = new _HttpOutgoing();
+ var outgoing = new _HttpOutgoing(_socket);
// Create new request object, wrapping the outgoing connection.
var request = new _HttpClientRequest(outgoing,
uri,
method,
- !isDirect,
+ proxy,
_httpClient,
this);
request.headers.host = uri.domain;
request.headers.port = port;
request.headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
+ if (proxy.isAuthenticated) {
+ // If the proxy configuration contains user information use that
+ // for proxy basic authorization.
+ String auth = CryptoUtils.bytesToBase64(
+ _encodeString("${proxy.username}:${proxy.password}"));
+ request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth");
+ } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) {
+ var cr = _httpClient._findProxyCredentials(proxy);
+ if (cr != null) {
+ cr.authorize(request);
+ }
+ }
if (uri.userInfo != null && !uri.userInfo.isEmpty) {
// If the URL contains user information use that for basic
- // authorization
+ // authorization.
String auth =
CryptoUtils.bytesToBase64(_encodeString(uri.userInfo));
request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
@@ -1010,56 +1107,52 @@
// Start sending the request (lazy, delayed until the user provides
// data).
_httpParser.responseToMethod = method;
- _streamFuture = outgoing.onStream((stream) {
- return _socket.writeStream(stream)
- .then((s) {
- // Request sent, set up response completer.
- _nextResponseCompleter = new Completer();
+ _streamFuture = outgoing.done
+ .then((s) {
+ // Request sent, set up response completer.
+ _nextResponseCompleter = new Completer();
- // Listen for response.
- _nextResponseCompleter.future
- .then((incoming) {
- incoming.dataDone.then((_) {
- if (incoming.headers.persistentConnection &&
- request.persistentConnection) {
- // Return connection, now we are done.
- _httpClient._returnConnection(this);
- _subscription.resume();
- } else {
- destroy();
- }
- });
- request._onIncoming(incoming);
- })
- // If we see a state error, we failed to get the 'first'
- // element.
- // Transform the error to a HttpParserException, for
- // consistency.
- .catchError((error) {
- throw new HttpParserException(
- "Connection closed before data was received");
- }, test: (error) => error is StateError)
- .catchError((error) {
- // We are done with the socket.
+ // Listen for response.
+ _nextResponseCompleter.future
+ .then((incoming) {
+ incoming.dataDone.then((_) {
+ if (incoming.headers.persistentConnection &&
+ request.persistentConnection) {
+ // Return connection, now we are done.
+ _httpClient._returnConnection(this);
+ _subscription.resume();
+ } else {
destroy();
- request._onError(error);
- });
+ }
+ });
+ request._onIncoming(incoming);
+ })
+ // If we see a state error, we failed to get the 'first'
+ // element.
+ // Transform the error to a HttpParserException, for
+ // consistency.
+ .catchError((error) {
+ throw new HttpParserException(
+ "Connection closed before data was received");
+ }, test: (error) => error is StateError)
+ .catchError((error) {
+ // We are done with the socket.
+ destroy();
+ request._onError(error);
+ });
- // Resume the parser now we have a handler.
- _subscription.resume();
- return s;
- }, onError: (e) {
- destroy();
- throw e;
- });
- });
+ // Resume the parser now we have a handler.
+ _subscription.resume();
+ return s;
+ }, onError: (e) {
+ destroy();
+ });
return request;
}
Future<Socket> detachSocket() {
- return _streamFuture
- .then((_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()),
- onError: (_) {});
+ return _streamFuture.then(
+ (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()));
}
void destroy() {
@@ -1071,8 +1164,7 @@
_httpClient._connectionClosed(this);
_streamFuture
// TODO(ajohnsen): Add timeout.
- .then((_) => _socket.destroy(),
- onError: (_) {});
+ .then((_) => _socket.destroy());
}
HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket);
@@ -1095,7 +1187,9 @@
final Set<_HttpClientConnection> _activeConnections
= new Set<_HttpClientConnection>();
final List<_Credentials> _credentials = [];
+ final List<_ProxyCredentials> _proxyCredentials = [];
Function _authenticate;
+ Function _authenticateProxy;
Function _findProxy = HttpClient.findProxyFromEnvironment;
Future<HttpClientRequest> open(String method,
@@ -1163,6 +1257,18 @@
_credentials.add(new _Credentials(url, realm, cr));
}
+ set authenticateProxy(
+ Future<bool> f(String host, int port, String scheme, String realm)) {
+ _authenticateProxy = f;
+ }
+
+ void addProxyCredentials(String host,
+ int port,
+ String realm,
+ HttpClientCredentials cr) {
+ _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
+ }
+
set findProxy(String f(Uri uri)) => _findProxy = f;
Future<HttpClientRequest> _openUrl(String method, Uri uri) {
@@ -1188,7 +1294,7 @@
try {
proxyConf = new _ProxyConfiguration(_findProxy(uri));
} catch (error, stackTrace) {
- return new Future.immediateError(error, stackTrace);
+ return new Future.error(error, stackTrace);
}
}
return _getConnection(uri.domain, port, proxyConf, isSecure)
@@ -1196,7 +1302,7 @@
return info.connection.send(uri,
port,
method.toUpperCase(),
- info.proxy.isDirect);
+ info.proxy);
});
}
@@ -1208,7 +1314,7 @@
request.followRedirects = previous.followRedirects;
// Allow same number of redirects.
request.maxRedirects = previous.maxRedirects;
- // Copy headers
+ // Copy headers.
for (var header in previous.headers._headers.keys) {
if (request.headers[header] == null) {
request.headers.set(header, previous.headers[header]);
@@ -1229,7 +1335,7 @@
}
// TODO(ajohnsen): Listen for socket close events.
if (!_idleConnections.containsKey(connection.key)) {
- _idleConnections[connection.key] = new Set();
+ _idleConnections[connection.key] = new LinkedHashSet();
}
_idleConnections[connection.key].add(connection);
}
@@ -1254,7 +1360,7 @@
Iterator<_Proxy> proxies = proxyConf.proxies.iterator;
Future<_ConnnectionInfo> connect(error) {
- if (!proxies.moveNext()) return new Future.immediateError(error);
+ if (!proxies.moveNext()) return new Future.error(error);
_Proxy proxy = proxies.current;
String host = proxy.isDirect ? uriHost: proxy.host;
int port = proxy.isDirect ? uriPort: proxy.port;
@@ -1266,7 +1372,7 @@
_idleConnections.remove(key);
}
_activeConnections.add(connection);
- return new Future.immediate(new _ConnnectionInfo(connection, proxy));
+ return new Future.value(new _ConnnectionInfo(connection, proxy));
}
return (isSecure && proxy.isDirect
? SecureSocket.connect(host,
@@ -1280,7 +1386,7 @@
return new _ConnnectionInfo(connection, proxy);
}, onError: (error) {
// Continue with next proxy.
- return connect(error.error);
+ return connect(error);
});
}
return connect(new HttpException("No proxies given"));
@@ -1300,6 +1406,16 @@
return cr;
}
+ _ProxyCredentials _findProxyCredentials(_Proxy proxy) {
+ // Look for credentials.
+ var it = _proxyCredentials.iterator;
+ while (it.moveNext()) {
+ if (it.current.applies(proxy, _AuthenticationScheme.BASIC)) {
+ return it.current;
+ }
+ }
+ }
+
void _removeCredentials(_Credentials cr) {
int index = _credentials.indexOf(cr);
if (index != -1) {
@@ -1377,39 +1493,35 @@
_HttpConnection(Socket this._socket, _HttpServer this._httpServer)
: _httpParser = new _HttpParser.requestParser() {
_socket.pipe(_httpParser);
- _socket.done.catchError((e) => destroy());
_subscription = _httpParser.listen(
(incoming) {
// Only handle one incoming request at the time. Keep the
// stream paused until the request has been send.
_subscription.pause();
_state = _ACTIVE;
- var outgoing = new _HttpOutgoing();
+ var outgoing = new _HttpOutgoing(_socket);
var response = new _HttpResponse(incoming.headers.protocolVersion,
outgoing);
var request = new _HttpRequest(response, incoming, _httpServer, this);
- outgoing.onStream((stream) {
- return _streamFuture = _socket.writeStream(stream)
- .then((_) {
- if (_state == _DETACHED) return;
- if (response.persistentConnection &&
- request.persistentConnection &&
- incoming.fullBodyRead) {
- _state = _IDLE;
- // Resume the subscription for incoming requests as the
- // request is now processed.
- _subscription.resume();
- } else {
- // Close socket, keep-alive not used or body sent before
- // received data was handled.
- destroy();
- }
- })
- .catchError((e) {
+ _streamFuture = outgoing.done
+ .then((_) {
+ if (_state == _DETACHED) return;
+ if (response.persistentConnection &&
+ request.persistentConnection &&
+ incoming.fullBodyRead) {
+ _state = _IDLE;
+ // Resume the subscription for incoming requests as the
+ // request is now processed.
+ _subscription.resume();
+ } else {
+ // Close socket, keep-alive not used or body sent before
+ // received data was handled.
destroy();
- throw e;
- });
- });
+ }
+ })
+ .catchError((e) {
+ destroy();
+ });
response._ignoreBody = request.method == "HEAD";
response._httpRequest = request;
_httpServer._handleRequest(request);
@@ -1482,9 +1594,9 @@
: _closeServer = false;
StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
_serverSocket.listen(
(Socket socket) {
socket.setOption(SocketOption.TCP_NODELAY, true);
@@ -1497,7 +1609,7 @@
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
void close() {
@@ -1528,7 +1640,7 @@
_controller.add(request);
}
- void _handleError(AsyncError error) {
+ void _handleError(error) {
if (!closed) _controller.addError(error);
}
@@ -1591,13 +1703,30 @@
proxy = proxy.trim();
if (!proxy.isEmpty) {
if (proxy.startsWith(PROXY_PREFIX)) {
+ String username;
+ String password;
+ // Skip the "PROXY " prefix.
+ proxy = proxy.substring(PROXY_PREFIX.length).trim();
+ // Look for proxy authentication.
+ int at = proxy.indexOf("@");
+ if (at != -1) {
+ String userinfo = proxy.substring(0, at).trim();
+ proxy = proxy.substring(at + 1).trim();
+ int colon = userinfo.indexOf(":");
+ if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
+ throw new HttpException(
+ "Invalid proxy configuration $configuration");
+ }
+ username = userinfo.substring(0, colon).trim();
+ password = userinfo.substring(colon + 1).trim();
+ }
+ // Look for proxy host and port.
int colon = proxy.indexOf(":");
if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
throw new HttpException(
"Invalid proxy configuration $configuration");
}
- // Skip the "PROXY " prefix.
- String host = proxy.substring(PROXY_PREFIX.length, colon).trim();
+ String host = proxy.substring(0, colon).trim();
String portString = proxy.substring(colon + 1).trim();
int port;
try {
@@ -1607,7 +1736,7 @@
"Invalid proxy configuration $configuration, "
"invalid port '$portString'");
}
- proxies.add(new _Proxy(host, port));
+ proxies.add(new _Proxy(host, port, username, password));
} else if (proxy.trim() == DIRECT_PREFIX) {
proxies.add(new _Proxy.direct());
} else {
@@ -1625,11 +1754,17 @@
class _Proxy {
- const _Proxy(this.host, this.port) : isDirect = false;
- const _Proxy.direct() : host = null, port = null, isDirect = true;
+ const _Proxy(
+ this.host, this.port, this.username, this.password) : isDirect = false;
+ const _Proxy.direct() : host = null, port = null,
+ username = null, password = null, isDirect = true;
+
+ bool get isAuthenticated => username != null;
final String host;
final int port;
+ final String username;
+ final String password;
final bool isDirect;
}
@@ -1662,13 +1797,13 @@
_DetachedSocket(this._socket, this._incoming);
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _incoming.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
Encoding get encoding => _socket.encoding;
@@ -1689,20 +1824,12 @@
void add(List<int> bytes) => _socket.add(bytes);
- void addError(AsyncError error) => _socket.addError(error);
-
- Future<Socket> consume(Stream<List<int>> stream) {
- return _socket.consume(stream);
- }
+ void addError(error) => _socket.addError(error);
Future<Socket> addStream(Stream<List<int>> stream) {
return _socket.addStream(stream);
}
- Future<Socket> writeStream(Stream<List<int>> stream) {
- return _socket.writeStream(stream);
- }
-
void destroy() => _socket.destroy();
Future close() => _socket.close();
@@ -1776,9 +1903,30 @@
}
+class _ProxyCredentials {
+ _ProxyCredentials(this.host, this.port, this.realm, this.credentials);
+
+ _AuthenticationScheme get scheme => credentials.scheme;
+
+ bool applies(_Proxy proxy, _AuthenticationScheme scheme) {
+ return proxy.host == host && proxy.port == port;
+ }
+
+ void authorize(HttpClientRequest request) {
+ credentials.authorizeProxy(this, request);
+ }
+
+ String host;
+ int port;
+ String realm;
+ _HttpClientCredentials credentials;
+}
+
+
abstract class _HttpClientCredentials implements HttpClientCredentials {
_AuthenticationScheme get scheme;
void authorize(_Credentials credentials, HttpClientRequest request);
+ void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request);
}
@@ -1790,7 +1938,7 @@
_AuthenticationScheme get scheme => _AuthenticationScheme.BASIC;
- void authorize(_Credentials _, HttpClientRequest request) {
+ String authorization() {
// There is no mentioning of username/password encoding in RFC
// 2617. However there is an open draft for adding an additional
// accept-charset parameter to the WWW-Authenticate and
@@ -1799,7 +1947,15 @@
// now always use UTF-8 encoding.
String auth =
CryptoUtils.bytesToBase64(_encodeString("$username:$password"));
- request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+ return "Basic $auth";
+ }
+
+ void authorize(_Credentials _, HttpClientRequest request) {
+ request.headers.set(HttpHeaders.AUTHORIZATION, authorization());
+ }
+
+ void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) {
+ request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization());
}
String username;
@@ -1820,6 +1976,12 @@
throw new UnsupportedError("Digest authentication not yet supported");
}
+ void authorizeProxy(_ProxyCredentials credentials,
+ HttpClientRequest request) {
+ // TODO(sgjesse): Implement!!!
+ throw new UnsupportedError("Digest authentication not yet supported");
+ }
+
String username;
String password;
}
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index dd55494..3c04684 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -106,8 +106,10 @@
List<int> this.carryOverData,
Completer oldResumeCompleter) {
controller = new StreamController<List<int>>(
- onSubscriptionStateChange: onSubscriptionStateChange,
- onPauseStateChange: onPauseStateChange);
+ onListen: resume,
+ onPause: pause,
+ onResume: resume,
+ onCancel: () => subscription.cancel());
if (subscription == null) {
// Socket was already closed.
if (carryOverData != null) controller.add(carryOverData);
@@ -123,14 +125,14 @@
}
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return controller.stream.listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
void resume() {
@@ -156,22 +158,6 @@
subscription.pause(resumeCompleter.future);
}
}
-
- void onPauseStateChange() {
- if (controller.isPaused) {
- pause();
- } else {
- resume();
- }
- }
-
- void onSubscriptionStateChange() {
- if (controller.hasListener) {
- resume();
- } else {
- subscription.cancel();
- }
- }
}
@@ -209,23 +195,25 @@
_HttpParser._(this._requestParser) {
_controller = new StreamController<_HttpIncoming>(
- onSubscriptionStateChange: _updateParsePauseState,
- onPauseStateChange: _updateParsePauseState);
+ onListen: _updateParsePauseState,
+ onPause: _updateParsePauseState,
+ onResume: _updateParsePauseState,
+ onCancel: _updateParsePauseState);
_reset();
}
StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
- Future<_HttpParser> consume(Stream<List<int>> stream) {
+ Future<_HttpParser> addStream(Stream<List<int>> stream) {
// Listen to the stream and handle data accordingly. When a
// _HttpIncoming is created, _dataPause, _dataResume, _dataDone is
// given to provide a way of controlling the parser.
@@ -236,18 +224,14 @@
_onData,
onError: _onError,
onDone: () {
- _onDone();
completer.complete(this);
});
return completer.future;
}
- Future<_HttpParser> addStream(Stream<List<int>> stream) {
- throw new UnimplementedError("_HttpParser.addStream");
- }
-
Future<_HttpParser> close() {
- throw new UnimplementedError("_HttpParser.close");
+ _onDone();
+ return new Future.value(this);
}
// From RFC 2616.
@@ -685,7 +669,7 @@
}
} catch (e, s) {
_state = _State.FAILURE;
- error(new AsyncError(e, s));
+ error(e, s);
}
_parserCalled = false;
@@ -717,9 +701,8 @@
!(_state == _State.START && !_requestParser) &&
!(_state == _State.BODY && !_chunked && _transferLength == -1)) {
_bodyController.addError(
- new AsyncError(
- new HttpParserException(
- "Connection closed while receiving data")));
+ new HttpParserException(
+ "Connection closed while receiving data"));
}
_closeIncoming();
_controller.close();
@@ -728,10 +711,8 @@
// If the connection is idle the HTTP stream is closed.
if (_state == _State.START) {
if (!_requestParser) {
- error(
- new AsyncError(
- new HttpParserException(
- "Connection closed before full header was received")));
+ error(new HttpParserException(
+ "Connection closed before full header was received"));
}
_controller.close();
return;
@@ -746,10 +727,8 @@
_state = _State.FAILURE;
// Report the error through the error callback if any. Otherwise
// throw the error.
- error(
- new AsyncError(
- new HttpParserException(
- "Connection closed before full header was received")));
+ error(new HttpParserException(
+ "Connection closed before full header was received"));
_controller.close();
return;
}
@@ -760,10 +739,8 @@
_state = _State.FAILURE;
// Report the error through the error callback if any. Otherwise
// throw the error.
- error(
- new AsyncError(
- new HttpParserException(
- "Connection closed before full body was received")));
+ error(new HttpParserException(
+ "Connection closed before full body was received"));
}
_controller.close();
}
@@ -882,8 +859,10 @@
assert(_incoming == null);
assert(_bodyController == null);
_bodyController = new StreamController<List<int>>(
- onSubscriptionStateChange: _bodySubscriptionStateChange,
- onPauseStateChange: _updateParsePauseState);
+ onListen: _bodySubscriptionStateChange,
+ onPause: _updateParsePauseState,
+ onResume: _updateParsePauseState,
+ onCancel: _bodySubscriptionStateChange);
_incoming = new _HttpIncoming(
_headers, transferLength, _bodyController.stream);
_pauseParsing(); // Needed to handle detaching - don't start on the body!
@@ -935,10 +914,10 @@
}
}
- void error(error) {
+ void error(error, [stackTrace]) {
if (_socketSubscription != null) _socketSubscription.cancel();
_state = _State.FAILURE;
- _controller.addError(error);
+ _controller.addError(error, stackTrace);
_controller.close();
}
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index ecaf427..ac08c0a 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -14,6 +14,7 @@
import 'dart:async';
import 'dart:collection' show Queue,
+ LinkedHashSet,
DoubleLinkedQueue,
DoubleLinkedQueueEntry;
import 'dart:crypto';
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index df3a7da..8001905 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -7,16 +7,14 @@
/**
* Helper class to wrap a [StreamConsumer<List<int>>] and provide
* utility functions for writing to the StreamConsumer directly. The
- * [IOSink] buffers the input given by [write], [writeAll], [writeln],
- * [writeCharCode] and [add] and will delay a [consume] or
- * [writeStream] until the buffer is flushed.
+ * [IOSink] buffers the input given by all [StringSink] methods and will delay
+ * a [addStream] until the buffer is flushed.
*
- * When the [IOSink] is bound to a stream (through either [consume]
- * or [writeStream]) any call to the [IOSink] will throw a
- * [StateError].
+ * When the [IOSink] is bound to a stream (through [addStream]) any call
+ * to the [IOSink] will throw a [StateError]. When the [addStream] compeltes,
+ * the [IOSink] will again be open for all calls.
*/
-abstract class IOSink<T>
- implements StreamConsumer<List<int>>, StringSink, EventSink<List<int>> {
+abstract class IOSink implements StreamSink<List<int>>, StringSink {
factory IOSink(StreamConsumer<List<int>> target,
{Encoding encoding: Encoding.UTF_8})
=> new _IOSinkImpl(target, encoding);
@@ -35,53 +33,40 @@
/**
* Writes an error to the consumer.
*/
- void addError(AsyncError error);
-
- /**
- * Provide functionality for piping to the [IOSink].
- */
- Future<T> consume(Stream<List<int>> stream);
+ void addError(error);
/**
* Adds all elements of the given [stream] to `this`.
*/
- Future<T> addStream(Stream<List<int>> stream);
-
- /**
- * Like [consume], but will not close the target when done.
- *
- * *Deprecated*: use [addStream] instead.
- */
- Future<T> writeStream(Stream<List<int>> stream);
+ Future addStream(Stream<List<int>> stream);
/**
* Close the target.
*/
- // TODO(floitsch): Currently the future cannot be typed because it has
- // hardcoded type Future<HttpClientResponse> in subclass HttpClientRequest.
Future close();
/**
- * Get future that will complete when all data has been written to
- * the IOSink and it has been closed.
+ * Get a future that will complete when all synchronous have completed, or an
+ * error happened. This future is identical to the future returned from close.
*/
- Future<T> get done;
+ Future get done;
}
-class _IOSinkImpl<T> implements IOSink<T> {
+class _IOSinkImpl implements IOSink {
final StreamConsumer<List<int>> _target;
-
- Completer _writeStreamCompleter;
+ Completer _doneCompleter = new Completer();
+ Future _doneFuture;
StreamController<List<int>> _controllerInstance;
- Future<T> _pipeFuture;
- StreamSubscription<List<int>> _bindSubscription;
- bool _paused = true;
+ Completer _controllerCompleter;
+ Encoding _encoding;
+ bool _isClosed = false;
+ bool _isBound = false;
bool _encodingMutable = true;
- _IOSinkImpl(StreamConsumer<List<int>> this._target, this._encoding);
-
- Encoding _encoding;
+ _IOSinkImpl(StreamConsumer<List<int>> this._target, this._encoding) {
+ _doneFuture = _doneCompleter.future;
+ }
Encoding get encoding => _encoding;
@@ -135,139 +120,103 @@
}
void add(List<int> data) {
- if (_isBound) {
- throw new StateError("IOSink is already bound to a stream");
- }
_controller.add(data);
}
- void addError(AsyncError error) {
- if (_isBound) {
- throw new StateError("IOSink is already bound to a stream");
- }
+ void addError(error) {
_controller.addError(error);
}
- Future<T> consume(Stream<List<int>> stream) {
+ Future addStream(Stream<List<int>> stream) {
if (_isBound) {
throw new StateError("IOSink is already bound to a stream");
}
- return _fillFromStream(stream);
- }
-
- Future<T> writeStream(Stream<List<int>> stream) {
- return addStream(stream);
- }
-
- Future<T> addStream(Stream<List<int>> stream) {
- if (_isBound) {
- throw new StateError("IOSink is already bound to a stream");
+ _isBound = true;
+ // Wait for any sync operations to complete.
+ Future targetAddStream() {
+ return _target.addStream(stream)
+ .whenComplete(() {
+ _isBound = false;
+ });
}
- return _fillFromStream(stream, unbind: true);
+ if (_controllerInstance == null) return targetAddStream();
+ var future = _controllerCompleter.future;
+ _controllerInstance.close();
+ return future.then((_) => targetAddStream());
}
Future close() {
if (_isBound) {
- throw new StateError("IOSink is already bound to a stream");
+ throw new StateError("IOSink is bound to a stream");
}
- _controller.close();
- return _pipeFuture;
+ if (!_isClosed) {
+ _isClosed = true;
+ if (_controllerInstance != null) {
+ _controllerInstance.close();
+ } else {
+ _closeTarget();
+ }
+ }
+ return done;
}
- Future<T> get done {
- _controller;
- return _pipeFuture;
+ void _closeTarget() {
+ _target.close()
+ .then((value) => _completeDone(value: value),
+ onError: (error) => _completeDone(error: error));
}
- void _completeWriteStreamCompleter([error]) {
- if (_writeStreamCompleter == null) return;
- var tmp = _writeStreamCompleter;
- _writeStreamCompleter = null;
+ Future get done => _doneFuture;
+
+ void _completeDone({value, error}) {
+ if (_doneCompleter == null) return;
+ var tmp = _doneCompleter;
+ _doneCompleter = null;
if (error == null) {
- _bindSubscription = null;
- tmp.complete();
+ tmp.complete(value);
} else {
tmp.completeError(error);
}
}
StreamController<List<int>> get _controller {
+ if (_isBound) {
+ throw new StateError("IOSink is bound to a stream");
+ }
+ if (_isClosed) {
+ throw new StateError("IOSink is closed");
+ }
if (_controllerInstance == null) {
- _controllerInstance = new StreamController<List<int>>(
- onPauseStateChange: _onPauseStateChange,
- onSubscriptionStateChange: _onSubscriptionStateChange);
- var future = _controller.stream.pipe(_target);
- future.then((_) => _completeWriteStreamCompleter(),
- onError: (error) => _completeWriteStreamCompleter(error));
- _pipeFuture = future.then((value) => value);
+ _controllerInstance = new StreamController<List<int>>();
+ _controllerCompleter = new Completer();
+ _target.addStream(_controller.stream)
+ .then(
+ (_) {
+ if (_isBound) {
+ // A new stream takes over - forward values to that stream.
+ var completer = _controllerCompleter;
+ _controllerCompleter = null;
+ _controllerInstance = null;
+ completer.complete();
+ } else {
+ // No new stream, .close was called. Close _target.
+ _closeTarget();
+ }
+ },
+ onError: (error) {
+ if (_isBound) {
+ // A new stream takes over - forward errors to that stream.
+ var completer = _controllerCompleter;
+ _controllerCompleter = null;
+ _controllerInstance = null;
+ completer.completeError(error);
+ } else {
+ // No new stream. No need to close target, as it have already
+ // failed.
+ _completeDone(error: error);
+ }
+ });
}
return _controllerInstance;
}
-
- bool get _isBound => _bindSubscription != null;
-
- void _onPauseStateChange() {
- _paused = _controller.isPaused;
- if (_controller.isPaused) {
- _pause();
- } else {
- _resume();
- }
- }
-
- void _pause() {
- if (_bindSubscription != null) {
- try {
- // The subscription can be canceled at this point.
- _bindSubscription.pause();
- } catch (e) {
- }
- }
- }
-
- void _resume() {
- if (_bindSubscription != null) {
- try {
- // The subscription can be canceled at this point.
- _bindSubscription.resume();
- } catch (e) {
- }
- }
- }
-
- void _onSubscriptionStateChange() {
- if (_controller.hasListener) {
- _paused = false;
- _resume();
- } else {
- if (_bindSubscription != null) {
- _bindSubscription.cancel();
- _bindSubscription = null;
- }
- }
- }
-
- Future<T> _fillFromStream(Stream<List<int>> stream, {unbind: false}) {
- _controller;
- assert(_writeStreamCompleter == null);
- if (unbind) {
- _writeStreamCompleter = new Completer<T>();
- }
- _bindSubscription = stream.listen(
- _controller.add,
- onDone: () {
- if (unbind) {
- _completeWriteStreamCompleter();
- } else {
- _controller.close();
- }
- },
- onError: _controller.addError);
- if (_paused) _pause();
- if (unbind) {
- return _writeStreamCompleter.future;
- } else {
- return _pipeFuture;
- }
- }
}
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 347ae1f..d36d779 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -130,7 +130,7 @@
Future<bool> exists() {
// TODO(whesse): Replace with asynchronous version.
- return new Future.immediate(existsSync());
+ return new Future.value(existsSync());
}
bool existsSync() => FileSystemEntity.isLinkSync(path);
@@ -205,7 +205,7 @@
Future<String> target() {
// TODO(whesse): Replace with asynchronous version.
- return new Future.of(targetSync);
+ return new Future.sync(targetSync);
}
String targetSync() {
diff --git a/sdk/lib/io/mime_multipart_parser.dart b/sdk/lib/io/mime_multipart_parser.dart
index cd12c20..e757c75 100644
--- a/sdk/lib/io/mime_multipart_parser.dart
+++ b/sdk/lib/io/mime_multipart_parser.dart
@@ -49,7 +49,7 @@
_boundary[1] = _CharCode.LF;
_boundary[2] = _CharCode.DASH;
_boundary[3] = _CharCode.DASH;
- _boundary.setRange(4, charCodes.length, charCodes);
+ _boundary.setRange(4, 4 + charCodes.length, charCodes);
_state = _START;
_headerField = new StringBuffer();
_headerValue = new StringBuffer();
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 1c9fddb..fc2a4aa 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -115,7 +115,7 @@
* Throws an [UnsupportedError] if the process is
* non-interactive.
*/
- IOSink<Process> get stdin;
+ IOSink get stdin;
/**
* Returns a [:Future:] which completes with the exit code of the process
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index 166b0f2..851b58d 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -64,14 +64,14 @@
}
StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _socket.map((rawSocket) => new SecureSocket._(rawSocket))
.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
/**
@@ -107,8 +107,10 @@
bool this.requireClientCertificate) {
_socket = serverSocket;
_controller = new StreamController<RawSecureSocket>(
- onPauseStateChange: _onPauseStateChange,
- onSubscriptionStateChange: _onSubscriptionStateChange);
+ onListen: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange,
+ onCancel: _onSubscriptionStateChange);
}
/**
@@ -157,13 +159,13 @@
}
StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
/**
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 197e87d..bff54c8 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -245,8 +245,10 @@
bool this.sendClientCertificate,
bool this.onBadCertificate(X509Certificate certificate)) {
_controller = new StreamController<RawSocketEvent>(
- onPauseStateChange: _onPauseStateChange,
- onSubscriptionStateChange: _onSubscriptionStateChange);
+ onListen: _onSubscriptionStateChange,
+ onPause: _onPauseStateChange,
+ onResume: _onPauseStateChange,
+ onCancel: _onSubscriptionStateChange);
_stream = _controller.stream;
// Throw an ArgumentError if any field is invalid. After this, all
// errors will be reported through the future or the stream.
@@ -261,7 +263,7 @@
if (socket == null) {
futureSocket = RawSocket.connect(host, requestedPort);
} else {
- futureSocket = new Future.immediate(socket);
+ futureSocket = new Future.value(socket);
}
futureSocket.then((rawSocket) {
rawSocket.writeEventsEnabled = false;
@@ -288,9 +290,9 @@
}
StreamSubscription listen(void onData(RawSocketEvent data),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
if (_writeEventsEnabled) {
_writeEventsEnabled = false;
_controller.add(RawSocketEvent.WRITE);
@@ -298,7 +300,7 @@
return _stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
void _verifyFields() {
@@ -464,17 +466,21 @@
// up handlers to flush the pipeline when possible.
int write(List<int> data, [int offset, int bytes]) {
if (_closedWrite) {
- _controller.addError(new AsyncError(new SocketIOException(
- "Writing to a closed socket")));
+ _controller.addError(new SocketIOException("Writing to a closed socket"));
return 0;
}
if (_status != CONNECTED) return 0;
+
+ if (offset == null) offset = 0;
+ if (bytes == null) bytes = data.length - offset;
+
var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
if (bytes > buffer.free) {
bytes = buffer.free;
}
if (bytes > 0) {
- buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
+ int startIndex = buffer.start + buffer.length;
+ buffer.data.setRange(startIndex, startIndex + bytes, data, offset);
buffer.length += bytes;
}
_writeEncryptedData(); // Tries to flush all pipeline stages.
@@ -562,17 +568,14 @@
_reportError(e, 'Error on underlying RawSocket');
}
- void _reportError(error, String message) {
+ void _reportError(e, String message) {
// TODO(whesse): Call _reportError from all internal functions that throw.
- var e;
- if (error is AsyncError) {
- e = error;
- } else if (error is SocketIOException) {
- e = new SocketIOException('$message (${error.message})', error.osError);
- } else if (error is OSError) {
- e = new SocketIOException(message, error);
+ if (e is SocketIOException) {
+ e = new SocketIOException('$message (${e.message})', e.osError);
+ } else if (e is OSError) {
+ e = new SocketIOException(message, e);
} else {
- e = new SocketIOException('$message (${error.toString()})', null);
+ e = new SocketIOException('$message (${e.toString()})', null);
}
if (_connectPending) {
_handshakeComplete.completeError(e);
@@ -660,9 +663,8 @@
List<int> data = _socket.read(encrypted.free);
if (data != null) {
int bytes = data.length;
- encrypted.data.setRange(encrypted.start + encrypted.length,
- bytes,
- data);
+ int startIndex = encrypted.start + encrypted.length;
+ encrypted.data.setRange(startIndex, startIndex + bytes, data);
encrypted.length += bytes;
progress = true;
}
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index ac3444c..48c8640 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -212,8 +212,7 @@
* both a [Stream] and a [IOSink] interface, making it ideal for
* using together with other [Stream]s.
*/
-abstract class Socket implements Stream<List<int>>,
- IOSink<Socket> {
+abstract class Socket implements Stream<List<int>>, IOSink {
/**
* Creats a new socket connection to the host and port and returns a [Future]
* that will complete with either a [Socket] once connected or an error
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 5cad1f0..afa7ea0 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -16,14 +16,14 @@
_StdStream(Stream<List<int>> this._stream);
StreamSubscription<List<int>> listen(void onData(List<int> event),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _stream.listen(
onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
}
@@ -40,11 +40,9 @@
void writeln([object = "" ]) => _sink.writeln(object);
void writeAll(objects, [sep = ""]) => _sink.writeAll(objects, sep);
void add(List<int> data) => _sink.add(data);
- void addError(AsyncError error) => _sink.addError(error);
+ void addError(error) => _sink.addError(error);
void writeCharCode(int charCode) => _sink.writeCharCode(charCode);
- Future consume(Stream<List<int>> stream) => _sink.consume(stream);
Future addStream(Stream<List<int>> stream) => _sink.addStream(stream);
- Future writeStream(Stream<List<int>> stream) => _sink.writeStream(stream);
Future close() => _sink.close();
Future get done => _sink.done;
}
diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart
index 4a70f44..3332879 100644
--- a/sdk/lib/io/string_transformer.dart
+++ b/sdk/lib/io/string_transformer.dart
@@ -315,9 +315,7 @@
void handleData(String data, EventSink<List<int>> sink) {
var bytes = _encode(data);
if (bytes == null) {
- sink.addError(
- new AsyncError(
- new FormatException("Invalid character for encoding")));
+ sink.addError(new FormatException("Invalid character for encoding"));
sink.close();
} else {
sink.add(bytes);
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index bd21220..c7d9e10 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -37,7 +37,7 @@
* which is supplied through the [:handleData:]. As the protocol is processed,
* it'll output frame data as either a List<int> or String.
*
- * Important infomation about usage: Be sure you use unsubscribeOnError, so the
+ * Important infomation about usage: Be sure you use cancelOnError, so the
* socket will be closed when the processer encounter an error. Not using it
* will lead to undefined behaviour.
*/
@@ -385,7 +385,7 @@
response.contentLength = 0;
response.close();
});
- return new Future.immediateError(
+ return new Future.error(
new WebSocketException("Invalid WebSocket upgrade request"));
}
@@ -547,7 +547,7 @@
_controller.close();
if (_writeClosed) _socket.destroy();
},
- unsubscribeOnError: true);
+ cancelOnError: true);
_socket.done
.catchError((error) {
@@ -564,13 +564,13 @@
}
StreamSubscription listen(void onData(message),
- {void onError(AsyncError error),
+ {void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
int get readyState => _readyState;
@@ -671,7 +671,7 @@
if (mask) {
header[1] |= 1 << 7;
var maskBytes = _IOCrypto.getRandomBytes(4);
- header.setRange(index, 4, maskBytes);
+ header.setRange(index, index + 4, maskBytes);
index += 4;
if (data != null) {
var list = new Uint8List(data.length);
diff --git a/sdk/lib/isolate/isolate_stream.dart b/sdk/lib/isolate/isolate_stream.dart
index 37db4e5..0f0f63f 100644
--- a/sdk/lib/isolate/isolate_stream.dart
+++ b/sdk/lib/isolate/isolate_stream.dart
@@ -77,13 +77,13 @@
}
StreamSubscription listen(void onData(event),
- { void onError(AsyncError error),
+ { void onError(error),
void onDone(),
- bool unsubscribeOnError}) {
+ bool cancelOnError}) {
return _controller.stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
}
@@ -114,7 +114,7 @@
*/
void add(dynamic message);
- void addError(AsyncError errorEvent);
+ void addError(errorEvent);
/** Closing multiple times is allowed. */
void close();
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 9813a0d..b5b971a 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -34,7 +34,8 @@
* An immutable map from from library names to mirrors for all
* libraries known to this mirror system.
*/
- Map<String, LibraryMirror> get libraries;
+ // TODO(ahe): [libraries] should be Map<Uri, LibraryMirror>.
+ Map<Symbol, LibraryMirror> get libraries;
/**
* A mirror on the isolate associated with this [MirrorSystem].
@@ -51,6 +52,8 @@
* A mirror on the [:void:] type.
*/
TypeMirror get voidType;
+
+ external static String getName(Symbol symbol);
}
/**
@@ -115,7 +118,7 @@
* entity, such as 'method' for a method [:void method() {...}:] or
* 'mylibrary' for a [:#library('mylibrary');:] declaration.
*/
- String get simpleName;
+ Symbol get simpleName;
/**
* The fully-qualified name for this Dart language entity.
@@ -128,7 +131,7 @@
* this is a gray area due to lack of clarity over whether library
* names are unique.
*/
- String get qualifiedName;
+ Symbol get qualifiedName;
/**
* A mirror on the owner of this function. This is the declaration
@@ -174,16 +177,16 @@
abstract class ObjectMirror implements Mirror {
/**
* Invokes the named function and returns a mirror on the result.
- * The arguments must be instances of [InstanceMirror], [num],
- * [String] or [bool].
+ * The arguments must be instances of [InstanceMirror], [num],
+ * [String], or [bool].
*/
/* TODO(turnidge): Properly document.
* TODO(turnidge): Handle ambiguous names.
* TODO(turnidge): Handle optional & named arguments.
*/
- Future<InstanceMirror> invokeAsync(String memberName,
+ Future<InstanceMirror> invokeAsync(Symbol memberName,
List<Object> positionalArguments,
- [Map<String,Object> namedArguments]);
+ [Map<Symbol, Object> namedArguments]);
/**
* Invokes a getter and returns a mirror on the result. The getter
@@ -191,17 +194,17 @@
* method.
*/
/* TODO(turnidge): Handle ambiguous names.*/
- Future<InstanceMirror> getFieldAsync(String fieldName);
+ Future<InstanceMirror> getFieldAsync(Symbol fieldName);
/**
* Invokes a setter and returns a mirror on the result. The setter
* may be either the implicit setter for a non-final field or a
* user-defined setter method.
- * The argument must be an instance of either [InstanceMirror], [num],
- * [String] or [bool].
+ * The argument must be an instance of either [InstanceMirror], [num],
+ * [String], or [bool].
*/
/* TODO(turnidge): Handle ambiguous names.*/
- Future<InstanceMirror> setFieldAsync(String fieldName, Object value);
+ Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value);
}
/**
@@ -259,17 +262,17 @@
/**
* Executes the closure.
- * The arguments must be instances of [InstanceMirror], [num],
- * [String] or [bool].
+ * The arguments must be instances of [InstanceMirror], [num],
+ * [String], or [bool].
*/
Future<InstanceMirror> applyAsync(List<Object> positionalArguments,
- [Map<String,Object> namedArguments]);
+ [Map<Symbol, Object> namedArguments]);
/**
* Looks up the value of a name in the scope of the closure. The
* result is a mirror on that value.
*/
- Future<InstanceMirror> findInContext(String name);
+ Future<InstanceMirror> findInContext(Symbol name);
}
/**
@@ -284,6 +287,7 @@
* TODO(turnidge): Document where this url comes from. Will this
* value be sensible?
*/
+ // TODO(ahe): Change type to [Uri], rename to "uri"?
String get url;
/**
@@ -293,41 +297,41 @@
* The members of a library are its top-level classes,
* functions, variables, getters, and setters.
*/
- Map<String, Mirror> get members;
+ Map<Symbol, Mirror> get members;
/**
* An immutable map from names to mirrors for all class
* declarations in this library.
*/
- Map<String, ClassMirror> get classes;
+ Map<Symbol, ClassMirror> get classes;
/**
* An immutable map from names to mirrors for all function, getter,
* and setter declarations in this library.
*/
- Map<String, MethodMirror> get functions;
+ Map<Symbol, MethodMirror> get functions;
/**
* An immutable map from names to mirrors for all getter
* declarations in this library.
*/
- Map<String, MethodMirror> get getters;
+ Map<Symbol, MethodMirror> get getters;
/**
* An immutable map from names to mirrors for all setter
* declarations in this library.
*/
- Map<String, MethodMirror> get setters;
+ Map<Symbol, MethodMirror> get setters;
/**
* An immutable map from names to mirrors for all variable
* declarations in this library.
*/
- Map<String, VariableMirror> get variables;
+ Map<Symbol, VariableMirror> get variables;
}
/**
- * A [TypeMirror] reflects a Dart language class, typedef
+ * A [TypeMirror] reflects a Dart language class, typedef,
* or type variable.
*/
abstract class TypeMirror implements DeclarationMirror {
@@ -360,38 +364,38 @@
*
* This does not include inherited members.
*/
- Map<String, Mirror> get members;
+ Map<Symbol, Mirror> get members;
/**
* An immutable map from names to mirrors for all method,
* declarations for this type. This does not include getters and
* setters.
*/
- Map<String, MethodMirror> get methods;
+ Map<Symbol, MethodMirror> get methods;
/**
* An immutable map from names to mirrors for all getter
* declarations for this type.
*/
- Map<String, MethodMirror> get getters;
+ Map<Symbol, MethodMirror> get getters;
/**
* An immutable map from names to mirrors for all setter
* declarations for this type.
*/
- Map<String, MethodMirror> get setters;
+ Map<Symbol, MethodMirror> get setters;
/**
* An immutable map from names to mirrors for all variable
* declarations for this type.
*/
- Map<String, VariableMirror> get variables;
+ Map<Symbol, VariableMirror> get variables;
/**
* An immutable map from names to mirrors for all constructor
* declarations for this type.
*/
- Map<String, MethodMirror> get constructors;
+ Map<Symbol, MethodMirror> get constructors;
/**
* An immutable map from names to mirrors for all type variables for
@@ -399,7 +403,7 @@
*
* This map preserves the order of declaration of the type variables.
*/
- Map<String, TypeVariableMirror> get typeVariables;
+ Map<Symbol, TypeVariableMirror> get typeVariables;
/**
* An immutable map from names to mirrors for all type arguments for
@@ -407,7 +411,7 @@
*
* This map preserves the order of declaration of the type variables.
*/
- Map<String, TypeMirror> get typeArguments;
+ Map<Symbol, TypeMirror> get typeArguments;
/**
* Is this the original declaration of this type?
@@ -433,12 +437,13 @@
/**
* Invokes the named constructor and returns a mirror on the result.
- * The arguments must be instances of [InstanceMirror], [num],
+ * The arguments must be instances of [InstanceMirror], [num],
+ * [String], or [bool].
*/
/* TODO(turnidge): Properly document.*/
- Future<InstanceMirror> newInstanceAsync(String constructorName,
+ Future<InstanceMirror> newInstanceAsync(Symbol constructorName,
List<Object> positionalArguments,
- [Map<String,Object> namedArguments]);
+ [Map<Symbol, Object> namedArguments]);
/**
* Does this mirror represent a class?
@@ -569,7 +574,7 @@
* For example, [:'bar':] is the constructor name for constructor
* [:Foo.bar:] of type [:Foo:].
*/
- String get constructorName;
+ Symbol get constructorName;
/**
* Is the reflectee a const constructor?
@@ -641,10 +646,8 @@
/**
* A mirror on the default value for this parameter, if it exists.
- *
- * TODO(turnidge): String may not be a good representation of this
- * at runtime.
*/
+ // TODO(ahe): This should return an InstanceMirror.
String get defaultValue;
}
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 570e29c..999864a 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
@@ -3147,6 +3148,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Length removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -3167,16 +3176,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Length> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Length> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Length initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Length fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Length> getRange(int start, int end) =>
@@ -3779,6 +3792,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Number removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -3799,16 +3820,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Number> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Number> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Number initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Number fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Number> getRange(int start, int end) =>
@@ -4642,6 +4667,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
PathSeg removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -4662,16 +4695,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<PathSeg> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<PathSeg> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [PathSeg initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [PathSeg fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<PathSeg> getRange(int start, int end) =>
@@ -5535,6 +5572,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
String removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -5555,16 +5600,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [String initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [String fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<String> getRange(int start, int end) =>
@@ -6701,6 +6750,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Transform removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -6721,16 +6778,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Transform> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Transform> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Transform initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Transform fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Transform> getRange(int start, int end) =>
@@ -7228,6 +7289,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
ElementInstance removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7248,16 +7317,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<ElementInstance> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<ElementInstance> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [ElementInstance initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [ElementInstance fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<ElementInstance> getRange(int start, int end) =>
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index e9532a9..64d8154 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
@@ -3408,6 +3409,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Length removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -3428,16 +3437,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Length> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Length> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Length initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Length> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Length fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Length> getRange(int start, int end) =>
@@ -4117,6 +4130,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Number removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -4137,16 +4158,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Number> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Number> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Number initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Number> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Number fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Number> getRange(int start, int end) =>
@@ -5253,6 +5278,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
PathSeg removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -5273,16 +5306,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<PathSeg> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<PathSeg> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [PathSeg initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<PathSeg> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [PathSeg fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<PathSeg> getRange(int start, int end) =>
@@ -6243,6 +6280,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
String removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -6263,16 +6308,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [String initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<String> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [String fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<String> getRange(int start, int end) =>
@@ -7498,6 +7547,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Transform removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -7518,16 +7575,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Transform> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Transform> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Transform initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Transform> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Transform fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Transform> getRange(int start, int end) =>
@@ -8079,6 +8140,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
ElementInstance removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -8099,16 +8168,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<ElementInstance> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<ElementInstance> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [ElementInstance initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<ElementInstance> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [ElementInstance fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<ElementInstance> getRange(int start, int end) =>
diff --git a/sdk/lib/utf/utf.dart b/sdk/lib/utf/utf.dart
index 1c8c95c..940ce68 100644
--- a/sdk/lib/utf/utf.dart
+++ b/sdk/lib/utf/utf.dart
@@ -4,6 +4,7 @@
library dart.utf;
import "dart:async";
+import "dart:collection";
part "utf_stream.dart";
part "utf8.dart";
part "utf16.dart";
@@ -197,7 +198,7 @@
*/
// TODO(floitsch): Consider removing the extend and switch to implements since
// that's cheaper to allocate.
-class _ListRange extends Iterable {
+class _ListRange extends IterableBase {
final List _source;
final int _offset;
final int _length;
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index 9794a81..3518bbb 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -190,7 +190,7 @@
*/
// TODO(floitsch): Consider removing the extend and switch to implements since
// that's cheaper to allocate.
-class IterableUtf16Decoder extends Iterable<int> {
+class IterableUtf16Decoder extends IterableBase<int> {
final _CodeUnitsProvider codeunitsProvider;
final int replacementCodepoint;
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index 5ddf7a7..acd465c 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.dart
@@ -184,7 +184,7 @@
*/
// TODO(floitsch): Consider removing the extend and switch to implements since
// that's cheaper to allocate.
-class IterableUtf32Decoder extends Iterable<int> {
+class IterableUtf32Decoder extends IterableBase<int> {
final Utf32BytesDecoderProvider codeunitsProvider;
IterableUtf32Decoder._(this.codeunitsProvider);
diff --git a/sdk/lib/utf/utf8.dart b/sdk/lib/utf/utf8.dart
index 893cf0f..7543865 100644
--- a/sdk/lib/utf/utf8.dart
+++ b/sdk/lib/utf/utf8.dart
@@ -90,7 +90,7 @@
int insertAt = 0;
for (int value in source) {
if (value < 0 || value > UNICODE_VALID_RANGE_MAX) {
- encoded.setRange(insertAt, 3, [0xef, 0xbf, 0xbd]);
+ encoded.setRange(insertAt, insertAt + 3, [0xef, 0xbf, 0xbd]);
insertAt += 3;
} else if (value <= _UTF8_ONE_BYTE_MAX) {
encoded[insertAt] = value;
@@ -131,7 +131,7 @@
*/
// TODO(floitsch): Consider removing the extend and switch to implements since
// that's cheaper to allocate.
-class IterableUtf8Decoder extends Iterable<int> {
+class IterableUtf8Decoder extends IterableBase<int> {
final List<int> bytes;
final int offset;
final int length;
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 1a36a9f..7dd2c2a 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 3743a5d..99294d2 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 1064ba7..b7eaa46 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -1,6 +1,7 @@
library dart.dom.web_gl;
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index 486d0cf..b8c6d3c 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -2,6 +2,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index eee01a0..c1eacb9 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -12,6 +12,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName;
@@ -342,6 +343,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Map removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -362,16 +371,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Map> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Map> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Map initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Map fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Map> getRange(int start, int end) =>
diff --git a/sdk/lib/web_sql/dartium/web_sql_dartium.dart b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
index 2a71887..29dcea9 100644
--- a/sdk/lib/web_sql/dartium/web_sql_dartium.dart
+++ b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
@@ -12,6 +12,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
@@ -360,6 +361,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
Map removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -380,16 +389,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<Map> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Map> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Map initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<Map> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [Map fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<Map> getRange(int start, int end) =>
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index fa01ccd..6884411 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -214,6 +214,25 @@
LibTest/core/int/operator_division_A01_t01: Fail # truncate/ceil/floor/round returns ints, issue 389
+LibTest/core/List/List_A01_t02: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A07_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
Language/11_Expressions/06_Lists_A06_t01: Fail # Issue 397
LibTest/core/Iterable/where_A01_t07: Fail # Issue 397
LibTest/core/List/addLast_A01_t01: Fail # Issue 397
@@ -244,5 +263,21 @@
LibTest/core/Set/isSubsetOf_A01_t02: fail # Issue 400
LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.delayed_A02_t01: Fail # No AsyncError anymore. Issue 407
+
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+
+
[ $runtime == drt && $compiler == none ]
*: Skip
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 49253a8..cdf7ed9 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -531,6 +531,40 @@
LibTest/core/List/getRange_A04_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A05_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t02: Fail # Issue 397
Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t02: Fail # Issue 397
Language/11_Expressions/11_Instance_Creation/1_New_A08_t01: Fail # Issue 397
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 91c422c..763f31f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -298,6 +298,19 @@
LibTest/core/List/operator_subscript_A03_t01: Fail # http://dartbug.com/9228
LibTest/core/List/operator_subscripted_assignment_A03_t01: Fail # http://dartbug.com/9228
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A08_t04: Fail, OK # co19 issue 405
+
+
[ $compiler == dart2js ]
LibTest/core/int/operator_GT_A01_t01: Fail, OK # co19 issue 200
LibTest/core/int/operator_LT_A01_t01: Fail, OK # co19 issue 200
@@ -307,7 +320,6 @@
LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
LibTest/core/List/getRange_A03_t01: Fail, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
-LibTest/core/List/setRange_A05_t01: Fail, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
Language/07_Classes/1_Instance_Methods_A02_t05: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
@@ -500,6 +512,41 @@
LibTest/core/List/getRange_A04_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
+[ $compiler == dart2js && $unchecked ]
+LibTest/core/List/setRange_A05_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
# Issues with co19 test suite in checked mode.
[ $compiler == dart2js && $checked ]
@@ -511,6 +558,10 @@
LibTest/collection/Queue/Queue.from_A01_t01: Fail # Issue 400
LibTest/collection/Queue/Queue.from_A01_t02: Fail # Issue 400
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
# Issues with co19 test suite in browsers.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index caf1431..0f7c3ee 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -73,6 +73,22 @@
LibTest/core/int/operator_division_A01_t01: Fail # ~/ returns ints, issue 361
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t05: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A08_t04: Fail, OK # co19 issue 405
+
+
[ $compiler == none && $runtime == vm ]
Language/13_Libraries_and_Scripts/1_Imports_A02_t21: Crash # Dart issue 6060
@@ -198,6 +214,16 @@
Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # issue 6085
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
[ $compiler == none && $runtime == vm && $checked ]
Language/12_Statements/09_Switch_A05_t01: Fail # TODO(vm-team): Please triage this failure.
@@ -429,6 +455,28 @@
LibTest/core/Set/isSubsetOf_A01_t01: fail # Issue 400
LibTest/core/Set/isSubsetOf_A01_t02: fail # Issue 400
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
[ $compiler == none && $runtime == vm && $checked ]
LibTest/core/Set/intersection_A01_t01: Fail # issue 390
LibTest/core/Set/intersection_A01_t02: Fail # issue 390
@@ -441,6 +489,13 @@
LibTest/core/Match/str_A01_t01: fail # Issue 400
LibTest/core/RegExp/allMatches_A01_t01: fail # Issue 400
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
+
+[ $compiler == none && $runtime == vm && $unchecked ]
+LibTest/core/List/setRange_A05_t01: Fail # setRange now takes end-argument. Issue 402
[ $compiler == none && $arch == simarm ]
*: Skip
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 394fe0d..c890e85 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -19,7 +19,7 @@
Future<String> localProvider(Uri uri) {
if (uri.scheme != 'main') return dummy.provider(uri);
- return new Future<String>.immediate(main);
+ return new Future<String>.value(main);
}
void localHandler(Uri uri, int begin, int end,
@@ -42,7 +42,7 @@
localProvider, localHandler, options);
result.then((String code) {
onValue(code, errors, warnings);
- }, onError: (AsyncError e) {
+ }, onError: (e) {
throw 'Compilation failed';
});
}
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 3a4c2fc..9e21cba 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -92,25 +92,25 @@
final libUri = fileUri('mylib.dart');
provider(uri) {
- if (uri == scriptUri) return new Future.immediate(srcMain);
+ if (uri == scriptUri) return new Future.value(srcMain);
if (uri.toString() == libUri.toString()) {
- return new Future.immediate(srcLibrary);
+ return new Future.value(srcLibrary);
}
if (uri.path.endsWith('/core.dart')) {
- return new Future.immediate(coreLib);
+ return new Future.value(coreLib);
} else if (uri.path.endsWith('/io.dart')) {
- return new Future.immediate(ioLib);
+ return new Future.value(ioLib);
} else if (uri.path.endsWith('/js_helper.dart')) {
- return new Future.immediate(helperLib);
+ return new Future.value(helperLib);
} else if (uri.path.endsWith('/html_dart2js.dart')) {
// TODO(smok): The file should change to html_dartium at some point.
- return new Future.immediate(htmlLib);
+ return new Future.value(htmlLib);
} else if (uri.path.endsWith('/foreign_helper.dart')) {
- return new Future.immediate(foreignLib);
+ return new Future.value(foreignLib);
} else if (uri.path.endsWith('/isolate_helper.dart')) {
- return new Future.immediate(isolateHelperLib);
+ return new Future.value(isolateHelperLib);
}
- return new Future.immediate('');
+ return new Future.value('');
}
handler(uri, begin, end, message, kind) {
diff --git a/tests/compiler/dart2js/declare_once_test.dart b/tests/compiler/dart2js/declare_once_test.dart
new file mode 100644
index 0000000..01fb13e
--- /dev/null
+++ b/tests/compiler/dart2js/declare_once_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that parameters keep their names in the output.
+
+import "package:expect/expect.dart";
+import 'compiler_helper.dart';
+
+main() {
+ // For a function with only one variable we declare it inline for more
+ // compactness. Test that we don't also declare it at the start of the
+ // method.
+ var generated = compile(
+ 'final List a = const ["bar", "baz"];'
+ 'int foo() {'
+ ' for (int i = 0; i < a.length; i++) {'
+ ' print(a[i]);'
+ ' }'
+ '}',
+ entry: 'foo', minify: false);
+ RegExp re = new RegExp(r"var ");
+ Expect.isTrue(re.hasMatch(generated));
+ print(generated);
+ Expect.equals(1, re.allMatches(generated).length);
+}
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 20d6e90..7c4c551 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -37,8 +37,9 @@
compiler.deferredLoadTask.allDeferredElements.where((e) => e.isClass())
.toSet();
- var expando =
- deferredClasses.where((e) => e.name.slowToString() == 'Expando').single;
+ var dateTime =
+ deferredClasses
+ .where((e) => e.name.slowToString() == 'DateTime').single;
var myClass =
deferredClasses.where((e) => e.name.slowToString() == 'MyClass').single;
@@ -46,7 +47,7 @@
var deferredLibrary = compiler.libraries['memory:deferred.dart'];
Expect.equals(deferredLibrary, myClass.getLibrary());
- Expect.equals(compiler.coreLibrary, expando.declaration.getLibrary());
+ Expect.equals(compiler.coreLibrary, dateTime.declaration.getLibrary());
}
const Map MEMORY_SOURCE_FILES = const {
@@ -71,7 +72,7 @@
const MyClass();
foo(x) {
- new Expando();
+ new DateTime.now();
return (x - 3) ~/ 2;
}
}
diff --git a/tests/compiler/dart2js/js_parser_test.dart b/tests/compiler/dart2js/js_parser_test.dart
index 0bfc6bc..1d972f0 100644
--- a/tests/compiler/dart2js/js_parser_test.dart
+++ b/tests/compiler/dart2js/js_parser_test.dart
@@ -71,21 +71,18 @@
// String literal with escaped quote.
testExpression(r'var x = "\""');
// *No clever escapes.
- testError(r'var x = "\x42"', 'escapes allowed in string literals');
+ testError(r'var x = "\x42"', 'escapes are not allowed in literals');
// Operator new.
testExpression('new Foo()');
// New with dotted access.
testExpression('new Frobinator.frobinate()');
- // *We don't handle dot after 'new' because we group 'new' with regular calls
- // instead of having it together with the dot operator but with opposite
- // associativity.
- testError('new Frobinator().frobinate()', "DOT");
- // The prettyprinter is smarter than we are.
+ testExpression('new Frobinator().frobinate()');
+ // The prettyprinter strips some superfluous parentheses.
testExpression('(new Frobinator()).frobinate()',
'new Frobinator().frobinate()');
// *We want a bracket on 'new'.
- testError('new Foo');
- testError('(new Foo)');
+ testError('new Foo', 'Parentheses are required');
+ testError('(new Foo)', 'Parentheses are required');
// Bogus operators.
testError('a +++ b', 'Unknown operator');
// This isn't perl. There are rules.
@@ -107,9 +104,24 @@
testExpression('var new = 42');
// Bad keyword.
testError('var typeof = 42', "Expected ALPHA");
- // Malformed decimal
+ // Malformed decimal/hex.
testError('var x = 42.', "Unparseable number");
testError('var x = 1.1.1', "Unparseable number");
+ testError('var x = 0xabcdefga', "Unparseable number");
+ testError('var x = 0xabcdef\$a', "Unparseable number");
+ testError('var x = 0x ', "Unparseable number");
+ // Good hex constants.
+ testExpression('var x = 0xff');
+ testExpression('var x = 0xff + 0xff');
+ testExpression('var x = 0xaF + 0x0123456789abcdefABCDEF');
+ // All sorts of keywords are allowed as property names in ES5.
+ testExpression('x.new = 0');
+ testExpression('x.delete = 0');
+ testExpression('x.for = 0');
+ testExpression('x.instanceof = 0');
+ testExpression('x.in = 0');
+ testExpression('x.void = 0');
+ testExpression('x.continue = 0');
// More unary.
testExpression('x = !x');
testExpression('!x == false');
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 16cccf3..26a33b0 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -32,10 +32,10 @@
return super.readStringFromUri(resourceUri);
}
String source = MEMORY_SOURCE_FILES[resourceUri.path];
- // TODO(ahe): Return new Future.immediateError(...) ?
+ // TODO(ahe): Return new Future.error(...) ?
if (source == null) throw 'No such file $resourceUri';
String resourceName = '$resourceUri';
this.sourceFiles[resourceName] = new SourceFile(resourceName, source);
- return new Future.immediate(source);
+ return new Future.value(source);
}
}
diff --git a/tests/compiler/dart2js/scanner_test.dart b/tests/compiler/dart2js/scanner_test.dart
index 28c01b0..da8f032 100644
--- a/tests/compiler/dart2js/scanner_test.dart
+++ b/tests/compiler/dart2js/scanner_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import 'dart:collection';
import 'dart:utf';
import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart';
import '../../../sdk/lib/_internal/compiler/implementation/scanner/scanner_implementation.dart';
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 181014f..d2c3205 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -6,7 +6,7 @@
class_test: Fail
statements_test: Fail
typed_locals_test: Fail
-no_such_method_test: Fail # Wrong InvocationMirror.memberName.
+no_such_method_test: Fail # Wrong Invocation.memberName.
deferred_semantics_test/none: Fail # TODO(ahe): Multitest cannot use import.
diff --git a/tests/compiler/dart2js_extra/for_in_test.dart b/tests/compiler/dart2js_extra/for_in_test.dart
index 39d45d9..eb5de79 100644
--- a/tests/compiler/dart2js_extra/for_in_test.dart
+++ b/tests/compiler/dart2js_extra/for_in_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import "dart:collection";
import "package:expect/expect.dart";
// Test foreach (aka. for-in) functionality.
@@ -25,7 +26,7 @@
Expect.equals(expect.length, i);
}
-class MyIterable<T> extends Iterable<T> {
+class MyIterable<T> extends IterableBase<T> {
final List<T> values;
MyIterable(List<T> values) : this.values = values;
Iterator get iterator {
diff --git a/tests/compiler/dart2js_extra/no_such_method_test.dart b/tests/compiler/dart2js_extra/no_such_method_test.dart
index dc28e07..a139c02 100644
--- a/tests/compiler/dart2js_extra/no_such_method_test.dart
+++ b/tests/compiler/dart2js_extra/no_such_method_test.dart
@@ -13,7 +13,7 @@
}
class A {
- noSuchMethod(InvocationMirror invocation) {
+ noSuchMethod(Invocation invocation) {
topLevelInfo = new NoSuchMethodInfo(this, invocation.memberName,
invocation.positionalArguments);
return topLevelInfo;
diff --git a/tests/corelib/apply2_test.dart b/tests/corelib/apply2_test.dart
index e733a24..f2984bf 100644
--- a/tests/corelib/apply2_test.dart
+++ b/tests/corelib/apply2_test.dart
@@ -3,10 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import "symbol_map_helper.dart";
apply(Function function, ArgumentDescriptor args) {
return Function.apply(
- function, args.positionalArguments, args.namedArguments);
+ function, args.positionalArguments,
+ symbolMapToStringMap(args.namedArguments));
}
class ArgumentDescriptor {
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index 71e87b9..d872227 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import "symbol_map_helper.dart";
// Testing Function.apply calls correctly.
// This test is not testing error handling, only that correct parameters
@@ -38,15 +39,17 @@
main() {
testMap(res, func, map) {
+ map = symbolMapToStringMap(map);
Expect.equals(res, Function.apply(func, null, map));
Expect.equals(res, Function.apply(func, [], map));
}
testList(res, func, list) {
Expect.equals(res, Function.apply(func, list));
Expect.equals(res, Function.apply(func, list, null));
- Expect.equals(res, Function.apply(func, list, {}));
+ Expect.equals(res, Function.apply(func, list, new Map<Symbol, dynamic>()));
}
test(res, func, list, map) {
+ map = symbolMapToStringMap(map);
Expect.equals(res, Function.apply(func, list, map));
}
testList(42, test0, null);
diff --git a/tests/corelib/iterable_expand_test.dart b/tests/corelib/iterable_expand_test.dart
index 5737a9b..9c60541 100644
--- a/tests/corelib/iterable_expand_test.dart
+++ b/tests/corelib/iterable_expand_test.dart
@@ -3,6 +3,21 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import 'dart:collection';
+
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+
+ get length => list.length;
+ set length(val) { list.length = val; }
+
+ operator [](index) => list[index];
+ operator []=(index, val) => list[index] = val;
+
+ String toString() => "[" + join(", ") + "]";
+}
+
main() {
test(expectation, iterable) {
@@ -25,6 +40,16 @@
test([1, 1, 2, 2, 3, 3], [1, 2, 3].expand((x) => [x, x]));
test([1, 1, 2], [1, 2, 3].expand((x) => [x, x, x].skip(x)));
+ test([1], new MyList([1]).expand((x) => [x]));
+ test([1, 2, 3], new MyList([1, 2, 3]).expand((x) => [x]));
+
+ test([], new MyList([1]).expand((x) => []));
+ test([], new MyList([1, 2, 3]).expand((x) => []));
+ test([2], new MyList([1, 2, 3]).expand((x) => x == 2 ? [2] : []));
+
+ test([1, 1, 2, 2, 3, 3], new MyList([1, 2, 3]).expand((x) => [x, x]));
+ test([1, 1, 2], new MyList([1, 2, 3]).expand((x) => [x, x, x].skip(x)));
+
// if function throws, iteration is stopped.
Iterable iterable = [1, 2, 3].expand((x) {
if (x == 2) throw "FAIL";
diff --git a/tests/corelib/iterable_length_test.dart b/tests/corelib/iterable_length_test.dart
index 225d398..20c9663 100644
--- a/tests/corelib/iterable_length_test.dart
+++ b/tests/corelib/iterable_length_test.dart
@@ -2,9 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import "dart:collection";
import "package:expect/expect.dart";
-class A extends Iterable {
+class A extends IterableBase {
int count;
A(this.count);
diff --git a/tests/corelib/iterable_test.dart b/tests/corelib/iterable_test.dart
index 51e363d..f99bba6 100644
--- a/tests/corelib/iterable_test.dart
+++ b/tests/corelib/iterable_test.dart
@@ -7,7 +7,9 @@
import "package:expect/expect.dart";
-class MyIterable implements Iterable {
+import 'dart:collection';
+
+class MyIterable implements IterableBase {
get iterator => [].iterator;
}
diff --git a/tests/corelib/list_fill_range_test.dart b/tests/corelib/list_fill_range_test.dart
new file mode 100644
index 0000000..cd0e023
--- /dev/null
+++ b/tests/corelib/list_fill_range_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int start, int end, [fillValue]) {
+ List copy = list.toList();
+ if (?fillValue) {
+ list.fillRange(start, end, fillValue);
+ } else {
+ list.fillRange(start, end, fillValue);
+ }
+ Expect.equals(copy.length, list.length);
+ for (int i = 0; i < start; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+ for (int i = start; i < end; i++) {
+ Expect.equals(fillValue, list[i]);
+ }
+ for (int i = end; i < list.length; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+}
+
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(value) { list.length = value; }
+ operator [](index) => list[index];
+ operator []=(index, val) { list[index] = val; }
+ toString() => list.toString();
+}
+
+main() {
+ test([1, 2, 3], 0, 1);
+ test([1, 2, 3], 0, 1, 99);
+ test([1, 2, 3], 1, 1);
+ test([1, 2, 3], 1, 1, 499);
+ test([1, 2, 3], 3, 3);
+ test([1, 2, 3], 3, 3, 499);
+ test([1, 2, 3].toList(growable: false), 0, 1);
+ test([1, 2, 3].toList(growable: false), 0, 1, 99);
+ test([1, 2, 3].toList(growable: false), 1, 1);
+ test([1, 2, 3].toList(growable: false), 1, 1, 499);
+ test([1, 2, 3].toList(growable: false), 3, 3);
+ test([1, 2, 3].toList(growable: false), 3, 3, 499);
+ test(new MyList([1, 2, 3]), 0, 1);
+ test(new MyList([1, 2, 3]), 0, 1, 99);
+ test(new MyList([1, 2, 3]), 1, 1);
+ test(new MyList([1, 2, 3]), 1, 1, 499);
+ test(new MyList([1, 2, 3]), 3, 3);
+ test(new MyList([1, 2, 3]), 3, 3, 499);
+
+ expectRE(() => test([1, 2, 3], -1, 0));
+ expectRE(() => test([1, 2, 3], 2, 1));
+ expectRE(() => test([1, 2, 3], 0, -1));
+ expectRE(() => test([1, 2, 3], 1, 4));
+ expectRE(() => test(new MyList([1, 2, 3]), -1, 0));
+ expectRE(() => test(new MyList([1, 2, 3]), 2, 1));
+ expectRE(() => test(new MyList([1, 2, 3]), 0, -1));
+ expectRE(() => test(new MyList([1, 2, 3]), 1, 4));
+ expectUE(() => test(const [1, 2, 3], 2, 3));
+ expectUE(() => test(const [1, 2, 3], -1, 0));
+ expectUE(() => test(const [1, 2, 3], 2, 1));
+ expectUE(() => test(const [1, 2, 3], 0, -1));
+ expectUE(() => test(const [1, 2, 3], 1, 4));
+}
+
+void expectRE(Function f) {
+ Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+ Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_insert_all_test.dart b/tests/corelib/list_insert_all_test.dart
new file mode 100644
index 0000000..a1d025a
--- /dev/null
+++ b/tests/corelib/list_insert_all_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int index, Iterable iterable) {
+ List copy = list.toList();
+ list.insertAll(index, iterable);
+ List iterableList = iterable.toList();
+ Expect.equals(copy.length + iterableList.length, list.length);
+ for (int i = 0; i < index; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+ for (int i = 0; i < iterableList.length; i++) {
+ Expect.equals(iterableList[i], list[i + index]);
+ }
+ for (int i = index + iterableList.length; i < copy.length; i++) {
+ Expect.equals(copy[i], list[i + iterableList.length]);
+ }
+}
+
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(value) { list.length = value; }
+ operator [](index) => list[index];
+ operator []=(index, val) { list[index] = val; }
+ toString() => list.toString();
+}
+
+main() {
+ test([1, 2, 3], 0, [4, 5]);
+ test([1, 2, 3], 1, [4, 5]);
+ test([1, 2, 3], 2, [4, 5]);
+ test([1, 2, 3], 3, [4, 5]);
+ test([1, 2, 3], 2, [4]);
+ test([1, 2, 3], 3, []);
+ test([1, 2, 3], 0, [4, 5].map((x) => x));
+ test([1, 2, 3], 1, [4, 5].map((x) => x));
+ test([1, 2, 3], 2, [4, 5].map((x) => x));
+ test([1, 2, 3], 3, [4, 5].map((x) => x));
+ test([1, 2, 3], 2, [4].map((x) => x));
+ test([1, 2, 3], 3, [].map((x) => x));
+ test([1, 2, 3], 0, const [4, 5]);
+ test([1, 2, 3], 1, const [4, 5]);
+ test([1, 2, 3], 2, const [4, 5]);
+ test([1, 2, 3], 3, const [4 ,5]);
+ test([1, 2, 3], 2, const [4]);
+ test([1, 2, 3], 3, const []);
+ test([1, 2, 3], 0, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 1, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 2, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 3, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 2, new Iterable.generate(1, (x) => x + 4));
+ test([1, 2, 3], 3, new Iterable.generate(0, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 0, [4, 5]);
+ test(new MyList([1, 2, 3]), 1, [4, 5]);
+ test(new MyList([1, 2, 3]), 2, [4]);
+ test(new MyList([1, 2, 3]), 3, []);
+ test(new MyList([1, 2, 3]), 2, [4, 5]);
+ test(new MyList([1, 2, 3]), 3, [4, 5]);
+ test(new MyList([1, 2, 3]), 0, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 1, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 2, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 3, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 2, [4].map((x) => x));
+ test(new MyList([1, 2, 3]), 3, [].map((x) => x));
+
+ expectRE(() => test([1, 2, 3], -1, [4, 5]));
+ expectUE(() => test([1, 2, 3].toList(growable: false), -1, [4, 5]));
+ expectRE(() => test(new MyList([1, 2, 3]), -1, [4, 5]));
+ expectUE(() => test([1, 2, 3].toList(growable: false), 0, [4, 5]));
+}
+
+void expectRE(Function f) {
+ Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+ Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_insert_range_test.dart b/tests/corelib/list_insert_range_test.dart
deleted file mode 100644
index 8670c62..0000000
--- a/tests/corelib/list_insert_range_test.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-
-main() {
- var list = [];
- list.insertRange(-1, 0);
- Expect.listEquals([], list);
- list.insertRange(0, 0);
- Expect.listEquals([], list);
- list.insertRange(0, 0, 2);
- Expect.listEquals([], list);
- list.insertRange(0, 0, 2);
- Expect.listEquals([], list);
-
- expectIOORE(() { [1, 2].insertRange(-1, 1); });
- expectIOORE(() { [1, 2].insertRange(3, 1); });
- expectIAE(() { [1, 2].insertRange(0, -1); });
-
- list = []; list.insertRange(0, 3);
- Expect.listEquals([null, null, null], list);
-
- list = []; list.insertRange(0, 3, 1);
- Expect.listEquals([1, 1, 1], list);
-
- list = [1, 1]; list.insertRange(1, 1, 2);
- Expect.listEquals([1, 2, 1], list);
-
- list = [1, 1]; list.insertRange(2, 2, 9);
- Expect.listEquals([1, 1, 9, 9], list);
-
- list = [1, 1]; list.insertRange(2, 1);
- Expect.listEquals([1, 1, null], list);
-
- list = [1, 1]; list.insertRange(0, 3, 3);
- Expect.listEquals([3, 3, 3, 1, 1], list);
-}
-
-void expectIOORE(Function f) {
- Expect.throws(f, (e) => e is RangeError);
-}
-
-void expectIAE(Function f) {
- Expect.throws(f, (e) => e is ArgumentError);
-}
diff --git a/tests/corelib/list_insert_test.dart b/tests/corelib/list_insert_test.dart
index adfd677..50d088f 100644
--- a/tests/corelib/list_insert_test.dart
+++ b/tests/corelib/list_insert_test.dart
@@ -3,11 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:expect/expect.dart';
+import 'dart:collection';
-void main() {
- // Normal modifiable list.
- var l1 = [0, 1, 2, 3, 4];
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(val) { list.length = val; }
+
+ operator [](index) => list[index];
+ operator []=(index, val) => list[index] = val;
+
+ String toString() => "[" + join(", ") + "]";
+}
+
+// l1 must be a modifiable list with 5 elements from 0 to 4.
+void testModifiableList(l1) {
bool checkedMode = false;
assert(checkedMode = true);
@@ -31,6 +43,12 @@
Expect.equals(7, l1.length);
Expect.equals(-1, l1[0]);
Expect.equals("[-1, 0, 1, 2, 3, 4, 5]", l1.toString());
+}
+
+void main() {
+ // Normal modifiable list.
+ testModifiableList([0, 1, 2, 3, 4]);
+ testModifiableList(new MyList([0, 1, 2, 3, 4]));
// Fixed size list.
var l2 = new List(5);
diff --git a/tests/corelib/list_remove_range_test.dart b/tests/corelib/list_remove_range_test.dart
index b4fa04f..94032a1 100644
--- a/tests/corelib/list_remove_range_test.dart
+++ b/tests/corelib/list_remove_range_test.dart
@@ -28,14 +28,14 @@
Expect.listEquals([], list);
list.addAll([3, 4, 5, 6]);
- list.removeRange(2, 2);
+ list.removeRange(2, 4);
Expect.listEquals([3, 4], list);
list.addAll([5, 6]);
- expectIOORE(() { list.removeRange(4, 1); });
+ expectIOORE(() { list.removeRange(4, 5); });
Expect.listEquals([3, 4, 5, 6], list);
- list.removeRange(1, 2);
+ list.removeRange(1, 3);
Expect.listEquals([3, 6], list);
testNegativeIndices();
@@ -51,18 +51,14 @@
Expect.listEquals([1, 2], list);
// A negative length throws an ArgumentError.
- Expect.throws(() { list.removeRange(0, -1); },
- (e) => e is ArgumentError);
+ expectIOORE(() { list.removeRange(0, -1); });
Expect.listEquals([1, 2], list);
- Expect.throws(() { list.removeRange(-1, -1); },
- (e) => e is ArgumentError);
+ expectIOORE(() { list.removeRange(-1, -1); });
Expect.listEquals([1, 2], list);
- // A zero length prevails, and does not throw an exception.
- list.removeRange(-1, 0);
- Expect.listEquals([1, 2], list);
+ expectIOORE(() { list.removeRange(-1, 0); });
- list.removeRange(4, 0);
+ expectIOORE(() { list.removeRange(4, 4); });
Expect.listEquals([1, 2], list);
}
diff --git a/tests/corelib/list_removeat_test.dart b/tests/corelib/list_removeat_test.dart
index d8dbf88..d9c7453 100644
--- a/tests/corelib/list_removeat_test.dart
+++ b/tests/corelib/list_removeat_test.dart
@@ -3,11 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import 'dart:collection';
-void main() {
- // Normal modifiable list.
- var l1 = [0, 1, 2, 3, 4];
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(val) { list.length = val; }
+
+ operator [](index) => list[index];
+ operator []=(index, val) => list[index] = val;
+
+ String toString() => "[" + join(", ") + "]";
+}
+
+// l1 must be a modifiable list with 5 elements from 0 to 4.
+void testModifiableList(l1) {
bool checkedMode = false;
assert(checkedMode = true);
@@ -42,6 +54,12 @@
Expect.equals(3, l1[1], "l1-2[1]");
Expect.equals(4, l1[2], "l1-2[2]");
Expect.equals(3, l1.length, "length-2");
+}
+
+void main() {
+ // Normal modifiable list.
+ testModifiableList([0, 1, 2, 3, 4]);
+ testModifiableList(new MyList([0, 1, 2, 3, 4]));
// Fixed size list.
var l2 = new List(5);
diff --git a/tests/corelib/list_replace_range_test.dart b/tests/corelib/list_replace_range_test.dart
new file mode 100644
index 0000000..26f016a
--- /dev/null
+++ b/tests/corelib/list_replace_range_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int start, int end, Iterable iterable) {
+ List copy = list.toList();
+ list.replaceRange(start, end, iterable);
+ List iterableList = iterable.toList();
+ Expect.equals(copy.length + iterableList.length - (end - start), list.length);
+ for (int i = 0; i < start; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+ for (int i = 0; i < iterableList.length; i++) {
+ Expect.equals(iterableList[i], list[i + start]);
+ }
+ int removedLength = end - start;
+ for (int i = end; i < copy.length; i++) {
+ Expect.equals(copy[i], list[i + iterableList.length - removedLength]);
+ }
+}
+
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(value) { list.length = value; }
+ operator [](index) => list[index];
+ operator []=(index, val) { list[index] = val; }
+ toString() => list.toString();
+}
+
+main() {
+ test([1, 2, 3], 0, 1, [4, 5]);
+ test([1, 2, 3], 1, 1, [4, 5]);
+ test([1, 2, 3], 2, 3, [4, 5]);
+ test([1, 2, 3], 3, 3, [4, 5]);
+ test([1, 2, 3], 0, 3, [4, 5]);
+ test([1, 2, 3], 2, 3, [4]);
+ test([1, 2, 3], 0, 3, []);
+ test([1, 2, 3], 0, 1, [4, 5].map((x) => x));
+ test([1, 2, 3], 1, 1, [4, 5].map((x) => x));
+ test([1, 2, 3], 2, 3, [4, 5].map((x) => x));
+ test([1, 2, 3], 3, 3, [4, 5].map((x) => x));
+ test([1, 2, 3], 0, 3, [4, 5].map((x) => x));
+ test([1, 2, 3], 2, 3, [4].map((x) => x));
+ test([1, 2, 3], 0, 3, [].map((x) => x));
+ test([1, 2, 3], 0, 1, const [4, 5]);
+ test([1, 2, 3], 1, 1, const [4, 5]);
+ test([1, 2, 3], 2, 3, const [4, 5]);
+ test([1, 2, 3], 3, 3, const [4, 5]);
+ test([1, 2, 3], 0, 3, const [4, 5]);
+ test([1, 2, 3], 2, 3, const [4]);
+ test([1, 2, 3], 0, 3, const []);
+ test([1, 2, 3], 0, 1, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 1, 1, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 2, 3, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 3, 3, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 0, 3, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 2, 3, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 0, 1, [4, 5]);
+ test(new MyList([1, 2, 3]), 1, 1, [4, 5]);
+ test(new MyList([1, 2, 3]), 2, 3, [4, 5]);
+ test(new MyList([1, 2, 3]), 3, 3, [4, 5]);
+ test(new MyList([1, 2, 3]), 0, 3, [4, 5]);
+ test(new MyList([1, 2, 3]), 2, 3, [4]);
+ test(new MyList([1, 2, 3]), 0, 3, []);
+ test(new MyList([1, 2, 3]), 0, 1, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 1, 1, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 2, 3, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 3, 3, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 0, 3, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 2, 3, [4].map((x) => x));
+ test(new MyList([1, 2, 3]), 0, 3, [].map((x) => x));
+ test(new MyList([1, 2, 3]), 0, 1, const [4, 5]);
+ test(new MyList([1, 2, 3]), 1, 1, const [4, 5]);
+ test(new MyList([1, 2, 3]), 2, 3, const [4, 5]);
+ test(new MyList([1, 2, 3]), 3, 3, const [4, 5]);
+ test(new MyList([1, 2, 3]), 0, 3, const [4, 5]);
+ test(new MyList([1, 2, 3]), 2, 3, const [4]);
+ test(new MyList([1, 2, 3]), 0, 3, const []);
+ test(new MyList([1, 2, 3]), 0, 1, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 1, 1, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 2, 3, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 3, 3, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 0, 3, new Iterable.generate(2, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 2, 3, new Iterable.generate(2, (x) => x + 4));
+
+ expectRE(() => test([1, 2, 3], -1, 0, []));
+ expectRE(() => test([1, 2, 3], 2, 1, []));
+ expectRE(() => test([1, 2, 3], 0, -1, []));
+ expectRE(() => test([1, 2, 3], 1, 4, []));
+ expectRE(() => test(new MyList([1, 2, 3]), -1, 0, []));
+ expectRE(() => test(new MyList([1, 2, 3]), 2, 1, []));
+ expectRE(() => test(new MyList([1, 2, 3]), 0, -1, []));
+ expectRE(() => test(new MyList([1, 2, 3]), 1, 4, []));
+ expectUE(() => test([1, 2, 3].toList(growable: false), 2, 3, []));
+ expectUE(() => test([1, 2, 3].toList(growable: false), -1, 0, []));
+ expectUE(() => test([1, 2, 3].toList(growable: false), 2, 1, []));
+ expectUE(() => test([1, 2, 3].toList(growable: false), 0, -1, []));
+ expectUE(() => test([1, 2, 3].toList(growable: false), 1, 4, []));
+ expectUE(() => test(const [1, 2, 3], 2, 3, []));
+ expectUE(() => test(const [1, 2, 3], -1, 0, []));
+ expectUE(() => test(const [1, 2, 3], 2, 1, []));
+ expectUE(() => test(const [1, 2, 3], 0, -1, []));
+ expectUE(() => test(const [1, 2, 3], 1, 4, []));
+}
+
+void expectRE(Function f) {
+ Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+ Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_set_all_test.dart b/tests/corelib/list_set_all_test.dart
new file mode 100644
index 0000000..50be8b3
--- /dev/null
+++ b/tests/corelib/list_set_all_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int index, Iterable iterable) {
+ List copy = list.toList();
+ list.setAll(index, iterable);
+ Expect.equals(copy.length, list.length);
+ for (int i = 0; i < index; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+ List iterableList = iterable.toList();
+ for (int i = 0; i < iterableList.length; i++) {
+ Expect.equals(iterableList[i], list[i + index]);
+ }
+ for (int i = index + iterableList.length; i < copy.length; i++) {
+ Expect.equals(copy[i], list[i]);
+ }
+}
+
+class MyList extends ListBase {
+ List list;
+ MyList(this.list);
+ get length => list.length;
+ set length(value) { list.length = value; }
+ operator [](index) => list[index];
+ operator []=(index, val) { list[index] = val; }
+ toString() => list.toString();
+}
+
+main() {
+ test([1, 2, 3], 0, [4, 5]);
+ test([1, 2, 3], 1, [4, 5]);
+ test([1, 2, 3], 2, [4]);
+ test([1, 2, 3], 3, []);
+ test([1, 2, 3], 0, [4, 5].map((x) => x));
+ test([1, 2, 3], 1, [4, 5].map((x) => x));
+ test([1, 2, 3], 2, [4].map((x) => x));
+ test([1, 2, 3], 3, [].map((x) => x));
+ test([1, 2, 3], 0, const [4, 5]);
+ test([1, 2, 3], 1, const [4, 5]);
+ test([1, 2, 3], 2, const [4]);
+ test([1, 2, 3], 3, const []);
+ test([1, 2, 3], 0, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 1, new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3], 2, new Iterable.generate(1, (x) => x + 4));
+ test([1, 2, 3], 3, new Iterable.generate(0, (x) => x + 4));
+ test([1, 2, 3].toList(growable: false), 0, [4, 5]);
+ test([1, 2, 3].toList(growable: false), 1, [4, 5]);
+ test([1, 2, 3].toList(growable: false), 2, [4]);
+ test([1, 2, 3].toList(growable: false), 3, []);
+ test([1, 2, 3].toList(growable: false), 0, [4, 5].map((x) => x));
+ test([1, 2, 3].toList(growable: false), 1, [4, 5].map((x) => x));
+ test([1, 2, 3].toList(growable: false), 2, [4].map((x) => x));
+ test([1, 2, 3].toList(growable: false), 3, [].map((x) => x));
+ test([1, 2, 3].toList(growable: false), 0, const [4, 5]);
+ test([1, 2, 3].toList(growable: false), 1, const [4, 5]);
+ test([1, 2, 3].toList(growable: false), 2, const [4]);
+ test([1, 2, 3].toList(growable: false), 3, const []);
+ test([1, 2, 3].toList(growable: false), 0,
+ new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3].toList(growable: false), 1,
+ new Iterable.generate(2, (x) => x + 4));
+ test([1, 2, 3].toList(growable: false), 2,
+ new Iterable.generate(1, (x) => x + 4));
+ test([1, 2, 3].toList(growable: false), 3,
+ new Iterable.generate(0, (x) => x + 4));
+ test(new MyList([1, 2, 3]), 0, [4, 5]);
+ test(new MyList([1, 2, 3]), 1, [4, 5]);
+ test(new MyList([1, 2, 3]), 2, [4]);
+ test(new MyList([1, 2, 3]), 3, []);
+ test(new MyList([1, 2, 3]), 0, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 1, [4, 5].map((x) => x));
+ test(new MyList([1, 2, 3]), 2, [4].map((x) => x));
+ test(new MyList([1, 2, 3]), 3, [].map((x) => x));
+
+ expectRE(() => test([1, 2, 3], -1, [4, 5]));
+ expectRE(() => test([1, 2, 3].toList(growable: false), -1, [4, 5]));
+ expectRE(() => test([1, 2, 3], 1, [4, 5, 6]));
+ expectRE(() => test([1, 2, 3].toList(growable: false), 1, [4, 5, 6]));
+ expectRE(() => test(new MyList([1, 2, 3]), -1, [4, 5]));
+ expectRE(() => test(new MyList([1, 2, 3]), 1, [4, 5, 6]));
+ expectUE(() => test(const [1, 2, 3], 0, [4, 5]));
+ expectUE(() => test(const [1, 2, 3], -1, [4, 5]));
+ expectUE(() => test(const [1, 2, 3], 1, [4, 5, 6]));
+}
+
+void expectRE(Function f) {
+ Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+ Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_set_range_test.dart b/tests/corelib/list_set_range_test.dart
index a693584..da80052 100644
--- a/tests/corelib/list_set_range_test.dart
+++ b/tests/corelib/list_set_range_test.dart
@@ -27,7 +27,7 @@
Expect.equals(1, list.length);
Expect.equals(1, list[0]);
- expectIOORE(() { list.setRange(0, 1, [1, 2], 2); });
+ expectSE(() { list.setRange(0, 1, [1, 2], 2); });
Expect.equals(1, list.length);
Expect.equals(1, list[0]);
@@ -44,13 +44,13 @@
list.setRange(0, 4, [1, 2, 3, 4]);
Expect.listEquals([1, 2, 3, 4], list);
- list.setRange(2, 2, [5, 6, 7, 8]);
+ list.setRange(2, 4, [5, 6, 7, 8]);
Expect.listEquals([1, 2, 5, 6], list);
- expectIOORE(() { list.setRange(4, 1, [5, 6, 7, 8]); });
+ expectIOORE(() { list.setRange(4, 5, [5, 6, 7, 8]); });
Expect.listEquals([1, 2, 5, 6], list);
- list.setRange(1, 2, [9, 10, 11, 12]);
+ list.setRange(1, 3, [9, 10, 11, 12]);
Expect.listEquals([1, 9, 10, 6], list);
testNegativeIndices();
@@ -62,23 +62,29 @@
Expect.throws(f, (e) => e is RangeError);
}
+void expectSE(Function f) {
+ Expect.throws(f, (e) => e is StateError);
+}
+
+void expectAE(Function f) {
+ Expect.throws(f, (e) => e is ArgumentError);
+}
+
void testNegativeIndices() {
var list = [1, 2];
expectIOORE(() { list.setRange(-1, 1, [1]); });
- expectIOORE(() { list.setRange(0, 1, [1], -1); });
+ expectAE(() { list.setRange(0, 1, [1], -1); });
// A negative length throws an ArgumentError.
- Expect.throws(() { list.setRange(0, -1, [1]); },
- (e) => e is ArgumentError);
+ expectIOORE(() { list.setRange(2, 1, [1]); });
- Expect.throws(() { list.setRange(-1, -1, [1], -1); },
- (e) => e is ArgumentError);
+ expectAE(() { list.setRange(-1, -2, [1], -1); });
Expect.listEquals([1, 2], list);
- // A zero length prevails, and does not throw an exception.
- list.setRange(-1, 0, [1]);
+ expectIOORE(() { list.setRange(-1, -1, [1]); });
Expect.listEquals([1, 2], list);
+ // The skipCount is only used if the length is not 0.
list.setRange(0, 0, [1], -1);
Expect.listEquals([1, 2], list);
}
@@ -87,6 +93,6 @@
var list = new List<int>(6);
Expect.listEquals([null, null, null, null, null, null], list);
list.setRange(0, 3, [1, 2, 3, 4]);
- list.setRange(3, 3, [1, 2, 3, 4]);
+ list.setRange(3, 6, [1, 2, 3, 4]);
Expect.listEquals([1, 2, 3, 1, 2, 3], list);
}
diff --git a/tests/corelib/list_to_string_test.dart b/tests/corelib/list_to_string_test.dart
new file mode 100644
index 0000000..a127c26
--- /dev/null
+++ b/tests/corelib/list_to_string_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:collection';
+
+class MyList extends ListBase {
+ final list;
+ MyList(this.list);
+
+ get length => list.length;
+ set length(val) { list.length = val; }
+
+ operator [](index) => list[index];
+ operator []=(index, val) => list[index] = val;
+}
+
+main() {
+ Expect.equals("[]", [].toString());
+ Expect.equals("[1]", [1].toString());
+ Expect.equals("[1, 2]", [1, 2].toString());
+ Expect.equals("[]", const [].toString());
+ Expect.equals("[1]", const [1].toString());
+ Expect.equals("[1, 2]", const [1, 2].toString());
+ Expect.equals("[]", new MyList([]).toString());
+ Expect.equals("[1]", new MyList([1]).toString());
+ Expect.equals("[1, 2]", new MyList([1, 2]).toString());
+}
diff --git a/tests/corelib/string_slice_test.dart b/tests/corelib/string_slice_test.dart
deleted file mode 100644
index b003a42..0000000
--- a/tests/corelib/string_slice_test.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-
-// Short string.
-var s = "0123456789";
-// Long string.
-var l = "$s$s$s$s$s$s$s$s$s$s";
-// Very long string.
-var v = "$l$l$l$l$l$l$l$l$l$l";
-
-
-testSliceSuccess() {
- // Test different ways to get the same slice from a string.
- testSlice(String string, int start, int end) {
- int length = string.length;
- String expect = string.substring(start, end);
- Expect.equals(expect, string.slice(start, end), "#${length}[$start:$end]");
- if (start < length) {
- // If start == length, there is no negative representation of the position.
- Expect.equals(expect, string.slice(start - length, end),
- "#${length}[${start - length}:$end]");
- }
- if (end < length) {
- Expect.equals(expect, string.slice(start, end - length),
- "#${length}[$start:${end - length}]");
- Expect.equals(expect, string.slice(start - length, end - length),
- "#${length}[${start-length}:${end-length}]");
- } else {
- Expect.equals(expect, string.slice(start),
- "#${length}[$start]");
- if (start < length) {
- Expect.equals(expect, string.slice(start - length),
- "#${length}[${start-length}]");
- if (start == 0) {
- Expect.equals(string, string.slice(), "#$length[:]");
- }
- }
- }
- }
-
- testSliceCombinations(String string) {
- int length = string.length;
- List<int> positions = [0, 1, string.length >> 1, length - 1, length];
- for (int i = 0; i < positions.length; i++) {
- for (int j = i; j < positions.length; j++) {
- testSlice(string, positions[i], positions[j]);
- }
- }
- }
-
- testSliceCombinations(s);
- testSliceCombinations(l);
- testSliceCombinations(v);
-}
-
-testSliceError() {
- function expectRangeError(void thunk()) {
- Expect.throws(thunk, (e) => e is RangeError);
- };
- function expectArgumentError(void thunk()) {
- Expect.throws(thunk, (e) => e is ArgumentError);
- };
- function badType(void thunk()) {
- bool checkedMode = false;
- assert(checkedMode = true);
- Expect.throws(thunk,
- (e) => checkedMode ? e is TypeError : e is ArgumentError);
- }
-
- // Invalid start:
- expectRangeError(() => s.slice(11));
- expectRangeError(() => s.slice(-11));
- // Invalid end:
- expectRangeError(() => s.slice(0, 11));
- expectRangeError(() => s.slice(0, -11));
- // Non-int:
- badType(() => s.slice(1.5));
- badType(() => s.slice(0, 1.5));
- badType(() => s.slice("1"));
- badType(() => s.slice(0, "1"));
- // Bad order:
- expectArgumentError(() => s.slice(5, 4));
- expectArgumentError(() => s.slice(-5, 4));
- expectArgumentError(() => s.slice(5, -6));
- expectArgumentError(() => s.slice(-5, -6));
-}
-
-
-main() {
- testSliceSuccess();
- testSliceError();
-}
diff --git a/tests/corelib/symbol_map_helper.dart b/tests/corelib/symbol_map_helper.dart
new file mode 100644
index 0000000..da9e7e5
--- /dev/null
+++ b/tests/corelib/symbol_map_helper.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart.test.symbol_map_helper;
+
+// TODO(ahe): Update map literals to avoid this method.
+Map<Symbol, dynamic> symbolMapToStringMap(Map<String, dynamic> map) {
+ if (map == null) return null;
+ Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
+ map.forEach((name, value) {
+ result[new Symbol(name)] = value;
+ });
+ return result;
+}
diff --git a/tests/corelib/symbol_test.dart b/tests/corelib/symbol_test.dart
index b3604c4..a160244 100644
--- a/tests/corelib/symbol_test.dart
+++ b/tests/corelib/symbol_test.dart
@@ -83,4 +83,8 @@
if (new Symbol('fisk').hashCode != x.hashCode) {
throw "non-const Symbol's hashCode not equal to its const equivalent";
}
+
+ if (new Symbol('') != const Symbol('')) {
+ throw 'empty Symbol not equals to itself';
+ }
}
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 449a0b8..f953129 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -608,8 +608,6 @@
testUnsupported('removeRange', () => getQueryAll().removeRange(0, 1));
- testUnsupported('insertangeRange', () => getQueryAll().insertRange(0, 1));
-
testUnsupported('clear', () => getQueryAll().clear());
testUnsupported('removeLast', () => getQueryAll().removeLast());
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index 697f176..47f0695 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -44,8 +44,8 @@
test('directoryDoesntExist', () {
return fs.root.getDirectory(
'directory2')
- .catchError((e) {
- expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+ .catchError((error) {
+ expect(error.code, equals(FileError.NOT_FOUND_ERR));
}, test: (e) => e is FileError);
});
@@ -66,8 +66,8 @@
test('fileDoesntExist', () {
return fs.root.getFile(
'file2')
- .catchError((e) {
- expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+ .catchError((error) {
+ expect(error.code, equals(FileError.NOT_FOUND_ERR));
}, test: (e) => e is FileError);
});
@@ -99,7 +99,7 @@
return fs.root.createDirectory(
'directory3')
.then((DirectoryEntry dir) {
- return new Future.immediate(new FileAndDir(file, dir));
+ return new Future.value(new FileAndDir(file, dir));
});
});
}
@@ -152,8 +152,8 @@
expect(entry.name, 'movedFile');
expect(entry.fullPath, '/directory3/movedFile');
return fs.root.getFile('file4');
- }).catchError((e) {
- expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+ }).catchError((error) {
+ expect(error.code, equals(FileError.NOT_FOUND_ERR));
}, test: (e) => e is FileError);
});
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index 27b11a8..cac79de 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -110,7 +110,7 @@
test('Web Database', () {
// Skip if not supported.
if (!SqlDatabase.supported) {
- return new Future.immediate(null);
+ return new Future.value();
}
final tableName = 'test_table';
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index 6214581..0087b74 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -86,8 +86,8 @@
test('XHR.request No file', () {
HttpRequest.request('NonExistingFile').then(
(_) { fail('Request should not have succeeded.'); },
- onError: expectAsync1((e) {
- var xhr = e.error.target;
+ onError: expectAsync1((error) {
+ var xhr = error.target;
expect(xhr.readyState, equals(HttpRequest.DONE));
validate404(xhr);
}));
@@ -116,8 +116,8 @@
test('XHR.request withCredentials No file', () {
HttpRequest.request('NonExistingFile', withCredentials: true).then(
(_) { fail('Request should not have succeeded.'); },
- onError: expectAsync1((e) {
- var xhr = e.error.target;
+ onError: expectAsync1((error) {
+ var xhr = error.target;
expect(xhr.readyState, equals(HttpRequest.DONE));
validate404(xhr);
}));
@@ -137,8 +137,8 @@
test('XHR.getString No file', () {
HttpRequest.getString('NonExistingFile').then(
(_) { fail('Succeeded for non-existing file.'); },
- onError: expectAsync1((e) {
- validate404(e.error.target);
+ onError: expectAsync1((error) {
+ validate404(error.target);
}));
});
diff --git a/tests/isolate/global_error_handler_stream2_test.dart b/tests/isolate/global_error_handler_stream2_test.dart
index ef079d0..f349589 100644
--- a/tests/isolate/global_error_handler_stream2_test.dart
+++ b/tests/isolate/global_error_handler_stream2_test.dart
@@ -21,9 +21,6 @@
bool globalErrorHandler(IsolateUnhandledException e) {
var source = e.source;
- if (source is AsyncError) {
- source = source.error;
- }
return source is RuntimeError && source.message == "ignore exception";
}
diff --git a/tests/language/factory2_test.dart b/tests/language/factory2_test.dart
index 80c0cc0..882ec7b 100644
--- a/tests/language/factory2_test.dart
+++ b/tests/language/factory2_test.dart
@@ -2,7 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-abstract class Link<T> extends Iterable<T> {
+import "dart:collection";
+
+abstract class Link<T> extends IterableBase<T> {
// does not match constructor for LinkFactory
factory Link(T head, [Link<T> tail]) = LinkFactory<T>; /// static type warning
Link<T> prepend(T element);
diff --git a/tests/language/factory3_test.dart b/tests/language/factory3_test.dart
index 403633b..c6c61ab 100644
--- a/tests/language/factory3_test.dart
+++ b/tests/language/factory3_test.dart
@@ -3,7 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
// VMOptions=--enable_checked_mode
-abstract class Link<T> extends Iterable<T> {
+import "dart:collection";
+
+abstract class Link<T> extends IterableBase<T> {
factory Link(T head, [Link<T> tail]) = LinkEntry<T>;
Link<T> prepend(T element);
}
diff --git a/tests/language/full_stacktrace1_test.dart b/tests/language/full_stacktrace1_test.dart
index 4bef00e..945ca70 100644
--- a/tests/language/full_stacktrace1_test.dart
+++ b/tests/language/full_stacktrace1_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
void func1() {
- throw new Exception("Test peanut gallery request for Full stacktrace");
+ throw new Exception("Test full stacktrace");
}
void func2() {
func1();
@@ -14,34 +14,14 @@
try {
func2();
} on Object catch(e, s) {
- print(e);
-
- var full_trace = s.fullStackTrace;
- Expect.isTrue(full_trace.contains("func1"));
- Expect.isTrue(full_trace.contains("func2"));
- Expect.isTrue(full_trace.contains("func3"));
- Expect.isTrue(full_trace.contains("func4"));
- Expect.isTrue(full_trace.contains("func5"));
- Expect.isTrue(full_trace.contains("func6"));
- Expect.isTrue(full_trace.contains("main"));
-
- var trace = s.stackTrace;
- Expect.isTrue(trace.contains("func1"));
- Expect.isTrue(trace.contains("func2"));
- Expect.isTrue(trace.contains("func3"));
-
- Expect.isFalse(trace.contains("func4"));
- Expect.isFalse(trace.contains("func5"));
- Expect.isFalse(trace.contains("func6"));
- Expect.isFalse(trace.contains("main"));
-
- print(s);
-
- print("Full stack trace");
- print(full_trace);
-
- print("Stack trace");
- print(trace);
+ var fullTrace = s.toString();
+ Expect.isTrue(fullTrace.contains("func1"));
+ Expect.isTrue(fullTrace.contains("func2"));
+ Expect.isTrue(fullTrace.contains("func3"));
+ Expect.isTrue(fullTrace.contains("func4"));
+ Expect.isTrue(fullTrace.contains("func5"));
+ Expect.isTrue(fullTrace.contains("func6"));
+ Expect.isTrue(fullTrace.contains("main"));
}
}
int func4() {
diff --git a/tests/language/full_stacktrace2_test.dart b/tests/language/full_stacktrace2_test.dart
index 7f45706..a98f5a6 100644
--- a/tests/language/full_stacktrace2_test.dart
+++ b/tests/language/full_stacktrace2_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
void func1() {
- throw new Exception("Test peanut gallery request for Full stacktrace");
+ throw new Exception("Test full stacktrace");
}
void func2() {
func1();
@@ -14,36 +14,15 @@
try {
func2();
} on Object catch(e, s) {
- print(e);
-
- var full_trace = s.fullStackTrace;
- Expect.isTrue(full_trace.contains("func1"));
- Expect.isTrue(full_trace.contains("func2"));
- Expect.isTrue(full_trace.contains("func3"));
- Expect.isTrue(full_trace.contains("func4"));
- Expect.isTrue(full_trace.contains("func5"));
- Expect.isTrue(full_trace.contains("func6"));
- Expect.isTrue(full_trace.contains("func7"));
- Expect.isTrue(full_trace.contains("main"));
-
- var trace = s.stackTrace;
- Expect.isTrue(trace.contains("func1"));
- Expect.isTrue(trace.contains("func2"));
- Expect.isTrue(trace.contains("func3"));
-
- Expect.isFalse(trace.contains("func4"));
- Expect.isFalse(trace.contains("func5"));
- Expect.isFalse(trace.contains("func6"));
- Expect.isFalse(trace.contains("func7"));
- Expect.isFalse(trace.contains("main"));
-
- print(s);
-
- print("Full stack trace");
- print(full_trace);
-
- print("Stack trace");
- print(trace);
+ var fullTrace = s.toString();
+ Expect.isTrue(fullTrace.contains("func1"));
+ Expect.isTrue(fullTrace.contains("func2"));
+ Expect.isTrue(fullTrace.contains("func3"));
+ Expect.isTrue(fullTrace.contains("func4"));
+ Expect.isTrue(fullTrace.contains("func5"));
+ Expect.isTrue(fullTrace.contains("func6"));
+ Expect.isTrue(fullTrace.contains("func7"));
+ Expect.isTrue(fullTrace.contains("main"));
throw; // This is a rethrow.
}
@@ -56,36 +35,15 @@
try {
func4();
} on Object catch(e, s) {
-
- var full_trace = s.fullStackTrace;
- print(full_trace);
- Expect.isTrue(full_trace.contains("func1"));
- Expect.isTrue(full_trace.contains("func2"));
- Expect.isTrue(full_trace.contains("func3"));
- Expect.isTrue(full_trace.contains("func4"));
- Expect.isTrue(full_trace.contains("func5"));
- Expect.isTrue(full_trace.contains("func6"));
- Expect.isTrue(full_trace.contains("func7"));
- Expect.isTrue(full_trace.contains("main"));
-
- var trace = s.stackTrace;
- Expect.isTrue(trace.contains("func1"));
- Expect.isTrue(trace.contains("func2"));
- Expect.isTrue(trace.contains("func3"));
- Expect.isTrue(trace.contains("func4"));
- Expect.isTrue(trace.contains("func5"));
-
- Expect.isFalse(trace.contains("func6"));
- Expect.isFalse(trace.contains("func7"));
- Expect.isFalse(trace.contains("main"));
-
- print(s);
-
- print("Full stack trace");
- print(full_trace);
-
- print("Stack trace");
- print(trace);
+ var fullTrace = s.toString();
+ Expect.isTrue(fullTrace.contains("func1"));
+ Expect.isTrue(fullTrace.contains("func2"));
+ Expect.isTrue(fullTrace.contains("func3"));
+ Expect.isTrue(fullTrace.contains("func4"));
+ Expect.isTrue(fullTrace.contains("func5"));
+ Expect.isTrue(fullTrace.contains("func6"));
+ Expect.isTrue(fullTrace.contains("func7"));
+ Expect.isTrue(fullTrace.contains("main"));
}
return 1;
}
diff --git a/tests/language/full_stacktrace3_test.dart b/tests/language/full_stacktrace3_test.dart
index 4bacd04..553f86a 100644
--- a/tests/language/full_stacktrace3_test.dart
+++ b/tests/language/full_stacktrace3_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
void func1() {
- throw new Exception("Test peanut gallery request for Full stacktrace");
+ throw new Exception("Test full stacktrace");
}
void func2() {
func1();
@@ -14,35 +14,15 @@
try {
func2();
} on Object catch(e, s) {
- print(e);
- var full_trace = s.fullStackTrace;
- Expect.isTrue(full_trace.contains("func1"));
- Expect.isTrue(full_trace.contains("func2"));
- Expect.isTrue(full_trace.contains("func3"));
- Expect.isTrue(full_trace.contains("func4"));
- Expect.isTrue(full_trace.contains("func5"));
- Expect.isTrue(full_trace.contains("func6"));
- Expect.isTrue(full_trace.contains("func7"));
- Expect.isTrue(full_trace.contains("main"));
-
- var trace = s.stackTrace;
- Expect.isTrue(trace.contains("func1"));
- Expect.isTrue(trace.contains("func2"));
- Expect.isTrue(trace.contains("func3"));
-
- Expect.isFalse(trace.contains("func4"));
- Expect.isFalse(trace.contains("func5"));
- Expect.isFalse(trace.contains("func6"));
- Expect.isFalse(trace.contains("func7"));
- Expect.isFalse(trace.contains("main"));
-
- print(s);
-
- print("Full stack trace");
- print(full_trace);
-
- print("Stack trace");
- print(trace);
+ var fullTrace = s.toString();
+ Expect.isTrue(fullTrace.contains("func1"));
+ Expect.isTrue(fullTrace.contains("func2"));
+ Expect.isTrue(fullTrace.contains("func3"));
+ Expect.isTrue(fullTrace.contains("func4"));
+ Expect.isTrue(fullTrace.contains("func5"));
+ Expect.isTrue(fullTrace.contains("func6"));
+ Expect.isTrue(fullTrace.contains("func7"));
+ Expect.isTrue(fullTrace.contains("main"));
throw new Exception("This is not a rethrow");
}
}
@@ -54,35 +34,15 @@
try {
func4();
} on Object catch(e, s) {
- var full_trace = s.fullStackTrace;
- Expect.isFalse(full_trace.contains("func1"));
- Expect.isFalse(full_trace.contains("func2"));
- Expect.isTrue(full_trace.contains("func3"));
- Expect.isTrue(full_trace.contains("func4"));
- Expect.isTrue(full_trace.contains("func5"));
- Expect.isTrue(full_trace.contains("func6"));
- Expect.isTrue(full_trace.contains("func7"));
- Expect.isTrue(full_trace.contains("main"));
-
- var trace = s.stackTrace;
- Expect.isFalse(trace.contains("func1"));
- Expect.isFalse(trace.contains("func2"));
-
- Expect.isTrue(trace.contains("func3"));
- Expect.isTrue(trace.contains("func4"));
- Expect.isTrue(trace.contains("func5"));
-
- Expect.isFalse(trace.contains("func6"));
- Expect.isFalse(trace.contains("func7"));
- Expect.isFalse(trace.contains("main"));
-
- print(s);
-
- print("Full stack trace");
- print(full_trace);
-
- print("Stack trace");
- print(trace);
+ var fullTrace = s.toString();
+ Expect.isFalse(fullTrace.contains("func1"));
+ Expect.isFalse(fullTrace.contains("func2"));
+ Expect.isTrue(fullTrace.contains("func3"));
+ Expect.isTrue(fullTrace.contains("func4"));
+ Expect.isTrue(fullTrace.contains("func5"));
+ Expect.isTrue(fullTrace.contains("func6"));
+ Expect.isTrue(fullTrace.contains("func7"));
+ Expect.isTrue(fullTrace.contains("main"));
}
return 1;
}
diff --git a/tests/language/invocation_mirror_invoke_on_test.dart b/tests/language/invocation_mirror_invoke_on_test.dart
index 030fee6..4f84915 100644
--- a/tests/language/invocation_mirror_invoke_on_test.dart
+++ b/tests/language/invocation_mirror_invoke_on_test.dart
@@ -4,7 +4,7 @@
import "package:expect/expect.dart";
-// Testing InvocationMirror.invokeOn method; test of issue 7227.
+// Testing Invocation.invokeOn method; test of issue 7227.
var reachedSetX = 0;
var reachedGetX = 0;
diff --git a/tests/language/invocation_mirror_test.dart b/tests/language/invocation_mirror_test.dart
index 5c5a91b..d1bb2aa 100644
--- a/tests/language/invocation_mirror_test.dart
+++ b/tests/language/invocation_mirror_test.dart
@@ -4,14 +4,14 @@
import "package:expect/expect.dart";
-// InvocationMirror and noSuchMethod testing.
+// Invocation and noSuchMethod testing.
/** Class with noSuchMethod that returns the mirror */
class N {
// Storage for the last argument to noSuchMethod.
// Needed for setters, which don't evaluate to the return value.
var last;
- noSuchMethod(InvocationMirror m) => last = m;
+ noSuchMethod(Invocation m) => last = m;
flif(int x) { Expect.fail("never get here"); }
flaf([int x]) { Expect.fail("never get here"); }
@@ -28,14 +28,14 @@
}
/**
- * Checks the data of an InvocationMirror.
+ * Checks the data of an Invocation.
*
* Call without optionals for getters, with only positional for setters,
* and with both optionals for everything else.
*/
-testInvocationMirror(InvocationMirror im, String name,
+testInvocationMirror(Invocation im, String name,
[List positional, Map named]) {
- Expect.isTrue(im is InvocationMirror, "is InvocationMirror");
+ Expect.isTrue(im is Invocation, "is Invocation");
Expect.equals(name, im.memberName, "name");
if (named == null) {
Expect.isTrue(im.isAccessor, "$name:isAccessor");
@@ -152,7 +152,7 @@
}
class M extends N {
- noSuchMethod(InvocationMirror m) { throw "never get here"; }
+ noSuchMethod(Invocation m) { throw "never get here"; }
testSuperCalls() {
// Missing property/method access.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index ff16206..360ffc3 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -26,10 +26,13 @@
class_literal_test/27: Fail # Class literals are expression now; delete this test.
class_literal_test/28: Fail # Class literals are expression now; delete this test.
class_literal_test/29: Fail # Class literals are expression now; delete this test.
-full_stacktrace1_test: Skip # Stack trace interface is not implemented yet.
-full_stacktrace2_test: Skip # Stack trace interface is not implemented yet.
-full_stacktrace3_test: Skip # Stack trace interface is not implemented yet.
-stacktrace_test: Skip # Stack trace interface is not implemented yet.
+
+# Fails due to inlining. Not all expected frames are in the trace.
+full_stacktrace1_test: Pass, Fail # issue 9895
+full_stacktrace2_test: Pass, Fail # issue 9895
+full_stacktrace3_test: Pass, Fail # issue 9895
+# Stack traces may or may not end in a newline depending on the JS enging.
+stacktrace_test: Pass, Fail # Assumes stack trace string ends in newline.
# VM specific tests that should not be run by dart2js.
*vm_test: Skip
diff --git a/tests/language/list_test.dart b/tests/language/list_test.dart
index a0a12ec..d3afdf8 100644
--- a/tests/language/list_test.dart
+++ b/tests/language/list_test.dart
@@ -54,17 +54,17 @@
Expect.throws(() {
List a = new List(4);
- a.setRange(1, 1, a, null);
+ a.setRange(1, 2, a, null);
});
Expect.throws(() {
List a = new List(4);
- a.setRange(1, 1, const [1, 2, 3, 4], null);
+ a.setRange(1, 2, const [1, 2, 3, 4], null);
});
Expect.throws(() {
List a = new List(4);
- a.setRange(10, 1, a, 1);
+ a.setRange(10, 11, a, 1);
}, (e) => e is RangeError);
a = new List(4);
diff --git a/tests/language/no_such_method2_test.dart b/tests/language/no_such_method2_test.dart
index bd0b6a8..5b1e9fa 100644
--- a/tests/language/no_such_method2_test.dart
+++ b/tests/language/no_such_method2_test.dart
@@ -7,7 +7,7 @@
// Regression test for https://code.google.com/p/dart/issues/detail?id=7697.
// dart2js used to optimize [noSuchMethod] based on the user-provided
// argument, and forget that the runtime might call it with its own
-// [InvocationMirror] implementation.
+// [Invocation] implementation.
class Hey {
foo() => noSuchMethod(new FakeInvocationMirror());
@@ -21,7 +21,7 @@
noSuchMethod(x) => x.isGetter;
}
-class FakeInvocationMirror implements InvocationMirror {
+class FakeInvocationMirror implements Invocation {
final bool isGetter = false;
}
diff --git a/tests/language/no_such_method_test.dart b/tests/language/no_such_method_test.dart
index 5e154d2..39f1417 100644
--- a/tests/language/no_such_method_test.dart
+++ b/tests/language/no_such_method_test.dart
@@ -18,7 +18,7 @@
return (10 * a) + b;
}
- noSuchMethod(InvocationMirror im) {
+ noSuchMethod(Invocation im) {
Expect.equals("moo", getName(im));
Expect.equals(0, im.positionalArguments.length);
Expect.equals(1, im.namedArguments.length);
diff --git a/tests/language/overridden_no_such_method.dart b/tests/language/overridden_no_such_method.dart
index 127a53d..97433e3 100644
--- a/tests/language/overridden_no_such_method.dart
+++ b/tests/language/overridden_no_such_method.dart
@@ -13,7 +13,7 @@
OverriddenNoSuchMethod() {}
- noSuchMethod(InvocationMirror mirror) {
+ noSuchMethod(Invocation mirror) {
Expect.equals("foo", getName(mirror));
// 'foo' was called with two parameters (not counting receiver).
List args = mirror.positionalArguments;
diff --git a/tests/language/stack_trace_test.dart b/tests/language/stack_trace_test.dart
index 665313f..2f584a6 100644
--- a/tests/language/stack_trace_test.dart
+++ b/tests/language/stack_trace_test.dart
@@ -18,7 +18,7 @@
} on MyException catch (exception, stacktrace) {
i = 50;
print(exception.message_);
- Expect.equals((stacktrace != null), true);
+ Expect.isNotNull(stacktrace);
print(stacktrace);
}
try {
@@ -28,7 +28,7 @@
} on MyException catch (exception, stacktrace) {
i = 50;
print(exception.message_);
- Expect.equals((stacktrace != null), true);
+ Expect.isNotNull(stacktrace);
print(stacktrace);
}
try {
@@ -38,7 +38,7 @@
} on MyException catch (exception, stacktrace) {
i = 50;
print(exception.message_);
- Expect.equals((stacktrace != null), true);
+ Expect.isNotNull(stacktrace);
print(stacktrace);
} finally {
i = i + 800;
diff --git a/tests/language/store_to_load_forwarding_phis_vm_test.dart b/tests/language/store_to_load_forwarding_phis_vm_test.dart
index 13654a6..72ee9b3 100644
--- a/tests/language/store_to_load_forwarding_phis_vm_test.dart
+++ b/tests/language/store_to_load_forwarding_phis_vm_test.dart
@@ -22,7 +22,7 @@
foo(obj) {
var a = obj.foo;
- return new Future.immediate(null).then((val) { });
+ return new Future.value().then((val) { });
}
main() {
diff --git a/tests/language/super_call4_test.dart b/tests/language/super_call4_test.dart
index 4d68a19..079b8d2 100644
--- a/tests/language/super_call4_test.dart
+++ b/tests/language/super_call4_test.dart
@@ -10,7 +10,7 @@
class C {
E e = new E();
- bool noSuchMethod(InvocationMirror im) {
+ bool noSuchMethod(Invocation im) {
if (im.memberName == 'foo') {
return im.positionalArguments.isEmpty &&
im.namedArguments.isEmpty &&
@@ -36,7 +36,7 @@
}
class D extends C {
- bool noSuchMethod(InvocationMirror im) {
+ bool noSuchMethod(Invocation im) {
return false;
}
test1() {
diff --git a/tests/language/super_getter_setter_test.dart b/tests/language/super_getter_setter_test.dart
index ea923e8..ac50bbb 100644
--- a/tests/language/super_getter_setter_test.dart
+++ b/tests/language/super_getter_setter_test.dart
@@ -30,7 +30,7 @@
operator[](index) => indexField[index];
operator[]=(index, value) { indexField[index] = value; }
- noSuchMethod(InvocationMirror im) {
+ noSuchMethod(Invocation im) {
if (im.memberName.startsWith('missingSetter')) {
Expect.isTrue(im.isSetter);
missingSetterField = im.positionalArguments[0];
diff --git a/tests/language/super_operator_index5_test.dart b/tests/language/super_operator_index5_test.dart
index 6842709..1342852 100644
--- a/tests/language/super_operator_index5_test.dart
+++ b/tests/language/super_operator_index5_test.dart
@@ -10,7 +10,7 @@
var indexField = new List(2);
operator[](index) => indexField[index];
- noSuchMethod(InvocationMirror im) {
+ noSuchMethod(Invocation im) {
if (im.memberName == '[]=') {
Expect.equals(2, im.positionalArguments.length);
indexField[im.positionalArguments[0]] = im.positionalArguments[1];
diff --git a/tests/language/super_operator_index6_test.dart b/tests/language/super_operator_index6_test.dart
index 9fb942f..57e3951 100644
--- a/tests/language/super_operator_index6_test.dart
+++ b/tests/language/super_operator_index6_test.dart
@@ -10,7 +10,7 @@
var indexField = new List(2);
operator[]=(index, value) { indexField[index] = value; }
- noSuchMethod(InvocationMirror im) {
+ noSuchMethod(Invocation im) {
if (im.memberName == '[]') {
Expect.equals(1, im.positionalArguments.length);
return indexField[im.positionalArguments[0]];
diff --git a/tests/language/super_operator_index7_test.dart b/tests/language/super_operator_index7_test.dart
index b77b06f..fb0b78a 100644
--- a/tests/language/super_operator_index7_test.dart
+++ b/tests/language/super_operator_index7_test.dart
@@ -9,7 +9,7 @@
class A {
var indexField = new List(2);
- noSuchMethod(InvocationMirror im) {
+ noSuchMethod(Invocation im) {
if (im.memberName == '[]=') {
Expect.equals(2, im.positionalArguments.length);
indexField[im.positionalArguments[0]] = im.positionalArguments[1];
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index bfa469b..7309143 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -1,3 +1,6 @@
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == dartc ]
+lib/core/core: Fail
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index db5189c..eeafcc6 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -29,7 +29,7 @@
}
class ErrorEvent implements Event {
- final AsyncError error;
+ final error;
ErrorEvent(this.error);
@@ -40,10 +40,10 @@
bool operator==(Object other) {
if (other is! ErrorEvent) return false;
ErrorEvent otherEvent = other;
- return error.error == other.error.error;
+ return error == other.error;
}
- String toString() => "ErrorEvent: ${error.error}";
+ String toString() => "ErrorEvent: ${error}";
}
class DoneEvent implements Event {
@@ -70,14 +70,14 @@
/** Capture events from a stream into a new [Events] object. */
factory Events.capture(Stream stream,
- { bool unsubscribeOnError: false }) = CaptureEvents;
+ { bool cancelOnError: false }) = CaptureEvents;
// EventSink interface.
void add(var value) {
events.add(new DataEvent(value));
}
- void addError(AsyncError error) {
+ void addError(error) {
events.add(new ErrorEvent(error));
}
@@ -86,7 +86,7 @@
}
// Error helper for creating errors manually..
- void error(var value) { addError(new AsyncError(value, null)); }
+ void error(var value) { addError(value); }
/** Replay the captured events on a sink. */
void replay(EventSink sink) {
@@ -134,21 +134,21 @@
class CaptureEvents extends Events {
StreamSubscription subscription;
Completer onDoneSignal;
- bool unsubscribeOnError = false;
+ bool cancelOnError = false;
CaptureEvents(Stream stream,
- { bool unsubscribeOnError: false })
+ { bool cancelOnError: false })
: onDoneSignal = new Completer() {
- this.unsubscribeOnError = unsubscribeOnError;
+ this.cancelOnError = cancelOnError;
subscription = stream.listen(add,
onError: addError,
onDone: close,
- unsubscribeOnError: unsubscribeOnError);
+ cancelOnError: cancelOnError);
}
- void addError(AsyncError error) {
+ void addError(error) {
super.addError(error);
- if (unsubscribeOnError) onDoneSignal.complete(null);
+ if (cancelOnError) onDoneSignal.complete(null);
}
void close() {
diff --git a/tests/lib/async/future_constructor_test.dart b/tests/lib/async/future_constructor_test.dart
new file mode 100644
index 0000000..64d946c
--- /dev/null
+++ b/tests/lib/async/future_constructor_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library future_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+main() {
+ compare(func) {
+ // Compare the results of the following two futures.
+ Future f1 = new Future(func);
+ Future f2 = new Future.value().then((_) => func());
+ f2.catchError((_){}); // I'll get the error later.
+ f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); },
+ onError: (e1) {
+ f2.then((_) { Expect.fail("Expected error"); },
+ onError: (e2) {
+ Expect.equals(e1, e2);
+ });
+ });
+ }
+ Future val = new Future.value(42);
+ Future err1 = new Future.error("Error")..catchError((_){});
+ compare(() => 42);
+ compare(() => val);
+ compare(() { throw "Flif"; });
+ compare(() => err1);
+ bool hasExecuted = false;
+ compare(() {
+ hasExecuted = true;
+ return 499;
+ });
+ Expect.isFalse(hasExecuted);
+}
+
diff --git a/tests/lib/async/future_delayed_error_test.dart b/tests/lib/async/future_delayed_error_test.dart
index 8d444c2..be16cf0 100644
--- a/tests/lib/async/future_delayed_error_test.dart
+++ b/tests/lib/async/future_delayed_error_test.dart
@@ -12,10 +12,10 @@
// An open ReceivePort keeps the VM running. If the error-handler below is not
// executed then the test will fail with a timeout.
var port = new ReceivePort();
- var future = new Future.immediateError("error");
- future.catchError((e) {
+ var future = new Future.error("error");
+ future.catchError((error) {
port.close();
- Expect.equals(e.error, "error");
+ Expect.equals(error, "error");
});
}
@@ -27,9 +27,9 @@
testDelayedError() {
var port = new ReceivePort();
- completedFuture.catchError((e) {
+ completedFuture.catchError((error) {
port.close();
- Expect.equals(e.error, "foobar");
+ Expect.equals(error, "foobar");
});
}
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 6feffe1..078ee4a 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -10,8 +10,8 @@
const Duration MS = const Duration(milliseconds: 1);
-testImmediate() {
- final future = new Future<String>.immediate("42");
+testValue() {
+ final future = new Future<String>.value("42");
var port = new ReceivePort();
future.then((x) {
Expect.equals("42", x);
@@ -19,29 +19,37 @@
});
}
-testOf() {
+testSync() {
compare(func) {
// Compare the results of the following two futures.
- Future f1 = new Future.of(func);
- Future f2 = new Future.immediate(null).then((_) => func());
+ Future f1 = new Future.sync(func);
+ Future f2 = new Future.value().then((_) => func());
f2.catchError((_){}); // I'll get the error later.
f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); },
onError: (e1) {
f2.then((_) { Expect.fail("Expected error"); },
onError: (e2) {
- Expect.equals(e1.error, e2.error);
+ Expect.equals(e1, e2);
});
});
}
- Future val = new Future.immediate(42);
- Future err1 = new Future.immediateError("Error")..catchError((_){});
- Future err2 = new Future.immediateError(new AsyncError("AsyncError"))..catchError((_){});
+ Future val = new Future.value(42);
+ Future err1 = new Future.error("Error")..catchError((_){});
+ try {
+ throw new List(0);
+ } catch (e, st) {
+ Future err2 = new Future.error(e, st)..catchError((_){});
+ }
compare(() => 42);
compare(() => val);
compare(() { throw "Flif"; });
- compare(() { throw new AsyncError("AsyncFlif"); });
compare(() => err1);
- compare(() => err2);
+ bool hasExecuted = false;
+ compare(() {
+ hasExecuted = true;
+ return 499;
+ });
+ Expect.isTrue(hasExecuted);
}
testNeverComplete() {
@@ -127,8 +135,8 @@
var port = new ReceivePort();
future
.then((v) { throw "Value not expected"; })
- .catchError((e) {
- Expect.equals(e.error, ex);
+ .catchError((error) {
+ Expect.equals(error, ex);
port.close();
}, test: (e) => e == ex);
completer.completeError(ex);
@@ -140,7 +148,7 @@
final ex = new Exception();
var ex2;
- var done = future.catchError((e) { ex2 = e.error; });
+ var done = future.catchError((error) { ex2 = error; });
Expect.isFalse(completer.isCompleted);
completer.completeError(ex);
@@ -240,7 +248,7 @@
testFutureAsStreamCompleteImmediate() {
bool gotValue = false;
var port = new ReceivePort();
- new Future.immediate("value").asStream().listen(
+ new Future.value("value").asStream().listen(
(data) {
Expect.isFalse(gotValue);
gotValue = true;
@@ -263,7 +271,7 @@
onError: (error) {
Expect.isFalse(gotError);
gotError = true;
- Expect.equals("error", error.error);
+ Expect.equals("error", error);
},
onDone: () {
Expect.isTrue(gotError);
@@ -316,8 +324,8 @@
var completer = new Completer();
Future future = completer.future;
Future later = future.whenComplete(countDown);
- later.catchError((AsyncError e) {
- Expect.equals("error", e.error);
+ later.catchError((error) {
+ Expect.equals("error", error);
countDown();
});
completer.completeError("error");
@@ -335,8 +343,8 @@
countDown();
throw "new error";
});
- later.catchError((AsyncError e) {
- Expect.equals("new error", e.error);
+ later.catchError((error) {
+ Expect.equals("new error", error);
countDown();
});
completer.complete(42);
@@ -354,8 +362,8 @@
countDown();
throw "new error";
});
- later.catchError((AsyncError e) {
- Expect.equals("new error", e.error);
+ later.catchError((error) {
+ Expect.equals("new error", error);
countDown();
});
completer.completeError("error");
@@ -422,8 +430,8 @@
return completer2.future;
}).then((v) {
Expect.fail("should fail async");
- }, onError: (AsyncError e) {
- Expect.equals("Fail", e.error);
+ }, onError: (error) {
+ Expect.equals("Fail", error);
countDown(1);
});
@@ -448,8 +456,8 @@
return completer2.future;
}).then((v) {
Expect.fail("should fail async");
- }, onError: (AsyncError e) {
- Expect.equals("Error", e.error);
+ }, onError: (error) {
+ Expect.equals("Error", error);
countDown(1);
});
@@ -474,8 +482,8 @@
return completer2.future;
}).then((v) {
Expect.fail("should fail async");
- }, onError: (AsyncError e) {
- Expect.equals("Fail", e.error);
+ }, onError: (error) {
+ Expect.equals("Fail", error);
countDown(1);
});
@@ -485,12 +493,12 @@
testFutureThenThrowsAsync() {
final completer = new Completer<int>();
final future = completer.future;
- AsyncError error = new AsyncError(42, "st");
+ int error = 42;
var port = new ReceivePort();
future.then((v) {
throw error;
- }).catchError((AsyncError e) {
+ }).catchError((e) {
Expect.identical(error, e);
port.close();
});
@@ -500,12 +508,12 @@
testFutureCatchThrowsAsync() {
final completer = new Completer<int>();
final future = completer.future;
- AsyncError error = new AsyncError(42, "st");
+ int error = 42;
var port = new ReceivePort();
- future.catchError((AsyncError e) {
+ future.catchError((e) {
throw error;
- }).catchError((AsyncError e) {
+ }).catchError((e) {
Expect.identical(error, e);
port.close();
});
@@ -515,13 +523,13 @@
testFutureCatchRethrowsAsync() {
final completer = new Completer<int>();
final future = completer.future;
- AsyncError error;
+ var error;
var port = new ReceivePort();
- future.catchError((AsyncError e) {
+ future.catchError((e) {
error = e;
throw e;
- }).catchError((AsyncError e) {
+ }).catchError((e) {
Expect.identical(error, e);
port.close();
});
@@ -531,25 +539,25 @@
testFutureWhenThrowsAsync() {
final completer = new Completer<int>();
final future = completer.future;
- AsyncError error = new AsyncError(42, "st");
+ var error = 42;
var port = new ReceivePort();
future.whenComplete(() {
throw error;
- }).catchError((AsyncError e) {
+ }).catchError((e) {
Expect.identical(error, e);
port.close();
});
completer.complete(0);
}
-testCompleteWithAsyncError() {
+testCompleteWithError() {
final completer = new Completer<int>();
final future = completer.future;
- AsyncError error = new AsyncError(42, "st");
+ var error = 42;
var port = new ReceivePort();
- future.catchError((AsyncError e) {
+ future.catchError((e) {
Expect.identical(error, e);
port.close();
});
@@ -562,7 +570,7 @@
final future = completer.future;
var port = new ReceivePort();
- future.then((v) => new Future.immediate(v * 2))
+ future.then((v) => new Future.value(v * 2))
.then((v) {
Expect.equals(42, v);
port.close();
@@ -598,24 +606,24 @@
final future = completer.future;
var port = new ReceivePort();
- future.then((v) => new Future.immediateError("Fehler"))
- .then((v) { Expect.fail("unreachable!"); }, onError: (e) {
- Expect.equals("Fehler", e.error);
+ future.then((v) => new Future.error("Fehler"))
+ .then((v) { Expect.fail("unreachable!"); }, onError: (error) {
+ Expect.equals("Fehler", error);
port.close();
});
completer.complete(21);
}
main() {
- testImmediate();
- testOf();
+ testValue();
+ testSync();
testNeverComplete();
testComplete();
testCompleteWithSuccessHandlerBeforeComplete();
testCompleteWithSuccessHandlerAfterComplete();
testCompleteManySuccessHandlers();
- testCompleteWithAsyncError();
+ testCompleteWithError();
testException();
testExceptionHandler();
diff --git a/tests/lib/async/futures_test.dart b/tests/lib/async/futures_test.dart
index 7ae1d7e..446d93b 100644
--- a/tests/lib/async/futures_test.dart
+++ b/tests/lib/async/futures_test.dart
@@ -53,8 +53,8 @@
return Future.wait(futures).then((_) {
throw 'incorrect error';
- }).catchError((e) {
- Expect.equals('correct error', e.error);
+ }).catchError((error) {
+ Expect.equals('correct error', error);
});
}
@@ -69,8 +69,8 @@
return Future.wait(futures).then((_) {
throw 'incorrect error 2';
- }).catchError((e) {
- Expect.equals('correct error', e.error);
+ }).catchError((error) {
+ Expect.equals('correct error', error);
});
}
@@ -84,7 +84,7 @@
var seen = <int>[];
return Future.forEach([1, 2, 3, 4, 5], (n) {
seen.add(n);
- return new Future.immediate(null);
+ return new Future.value();
}).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
}
@@ -93,11 +93,11 @@
return Future.forEach([1, 2, 3, 4, 5], (n) {
if (n == 4) throw 'correct exception';
seen.add(n);
- return new Future.immediate(null);
+ return new Future.value();
}).then((_) {
throw 'incorrect exception';
- }).catchError((e) {
- Expect.equals('correct exception', e.error);
+ }).catchError((error) {
+ Expect.equals('correct exception', error);
});
}
diff --git a/tests/lib/async/slow_consumer2_test.dart b/tests/lib/async/slow_consumer2_test.dart
index d4865c4..2108870 100644
--- a/tests/lib/async/slow_consumer2_test.dart
+++ b/tests/lib/async/slow_consumer2_test.dart
@@ -58,7 +58,7 @@
}
Future close() {
- return new Future.immediate(finalCount);
+ return new Future.value(finalCount);
}
}
@@ -70,7 +70,9 @@
StreamController controller;
DataProvider(int this.bytesPerSecond, int this.targetCount, this.chunkSize) {
- controller = new StreamController(onPauseStateChange: onPauseStateChange);
+ controller = new StreamController(
+ onPause: onPauseStateChange,
+ onResume: onPauseStateChange);
Timer.run(send);
}
diff --git a/tests/lib/async/slow_consumer3_test.dart b/tests/lib/async/slow_consumer3_test.dart
index 18842c0..5bb3f99 100644
--- a/tests/lib/async/slow_consumer3_test.dart
+++ b/tests/lib/async/slow_consumer3_test.dart
@@ -58,7 +58,7 @@
}
Future close() {
- return new Future.immediate(finalCount);
+ return new Future.value(finalCount);
}
}
diff --git a/tests/lib/async/slow_consumer_test.dart b/tests/lib/async/slow_consumer_test.dart
index c07f8ac..a20ad6d 100644
--- a/tests/lib/async/slow_consumer_test.dart
+++ b/tests/lib/async/slow_consumer_test.dart
@@ -15,7 +15,7 @@
const int GB = KB * KB * KB;
class SlowConsumer extends StreamConsumer {
- var current = new Future.immediate(0);
+ var current = new Future.value(0);
final int bytesPerSecond;
int finalCount;
@@ -55,7 +55,7 @@
}
Future close() {
- return new Future.immediate(finalCount);
+ return new Future.value(finalCount);
}
}
@@ -68,7 +68,9 @@
Timer pendingSend;
DataProvider(int this.bytesPerSecond, int this.targetCount, this.chunkSize) {
- controller = new StreamController(onPauseStateChange: onPauseStateChange);
+ controller = new StreamController(
+ onPause: onPauseStateChange,
+ onResume: onPauseStateChange);
Timer.run(send);
}
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index dca28e1..6949900 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -14,8 +14,8 @@
testController() {
// Test fold
test("StreamController.fold", () {
- StreamController c = new StreamController.broadcast();
- Stream stream = c.stream;
+ StreamController c = new StreamController();
+ Stream stream = c.stream.asBroadcastStream();
stream.fold(0, (a,b) => a + b)
.then(expectAsync1((int v) {
Expect.equals(42, v);
@@ -26,10 +26,10 @@
});
test("StreamController.fold throws", () {
- StreamController c = new StreamController.broadcast();
- Stream stream = c.stream;
+ StreamController c = new StreamController();
+ Stream stream = c.stream.asBroadcastStream();
stream.fold(0, (a,b) { throw "Fnyf!"; })
- .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e.error); }));
+ .catchError(expectAsync1((error) { Expect.equals("Fnyf!", error); }));
c.add(42);
});
}
@@ -49,7 +49,7 @@
StreamController c = new StreamController();
Stream stream = c.stream;
stream.fold(0, (a,b) { throw "Fnyf!"; })
- .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e.error); }));
+ .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e); }));
c.add(42);
});
@@ -177,8 +177,8 @@
test("singleWhere 2", () {
StreamController c = new StreamController();
- Future f = c.stream.singleWhere((x) => (x % 3) == 0); // Matches both 9 and 87..
- f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+ Future f = c.stream.singleWhere((x) => (x % 3) == 0); // Matches 9 and 87..
+ f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
sentEvents.replay(c);
});
@@ -192,7 +192,7 @@
test("first empty", () {
StreamController c = new StreamController();
Future f = c.stream.first;
- f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+ f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
Events emptyEvents = new Events()..close();
emptyEvents.replay(c);
});
@@ -200,7 +200,7 @@
test("first error", () {
StreamController c = new StreamController();
Future f = c.stream.first;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..close();
errorEvents.replay(c);
});
@@ -208,7 +208,7 @@
test("first error 2", () {
StreamController c = new StreamController();
Future f = c.stream.first;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..error("error2")..close();
errorEvents.replay(c);
});
@@ -223,7 +223,7 @@
test("last empty", () {
StreamController c = new StreamController();
Future f = c.stream.last;
- f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+ f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
Events emptyEvents = new Events()..close();
emptyEvents.replay(c);
});
@@ -231,7 +231,7 @@
test("last error", () {
StreamController c = new StreamController();
Future f = c.stream.last;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..close();
errorEvents.replay(c);
});
@@ -239,7 +239,7 @@
test("last error 2", () {
StreamController c = new StreamController();
Future f = c.stream.last;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..error("error2")..close();
errorEvents.replay(c);
});
@@ -254,7 +254,7 @@
test("elementAt 2", () {
StreamController c = new StreamController();
Future f = c.stream.elementAt(20);
- f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+ f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
sentEvents.replay(c);
});
}
@@ -369,15 +369,18 @@
});
}
+class TestError { const TestError(); }
+
testRethrow() {
- AsyncError error = new AsyncError("UNIQUE", "UNIQUE");
+ TestError error = const TestError();
+
testStream(name, streamValueTransform) {
test("rethrow-$name-value", () {
StreamController c = new StreamController();
Stream s = streamValueTransform(c.stream, (v) { throw error; });
s.listen((_) { Expect.fail("unexpected value"); }, onError: expectAsync1(
- (AsyncError e) { Expect.identical(error, e); }));
+ (e) { Expect.identical(error, e); }));
c.add(null);
c.close();
});
@@ -388,7 +391,7 @@
StreamController c = new StreamController();
Stream s = streamErrorTransform(c.stream, (e) { throw error; });
s.listen((_) { Expect.fail("unexpected value"); }, onError: expectAsync1(
- (AsyncError e) { Expect.identical(error, e); }));
+ (e) { Expect.identical(error, e); }));
c.addError(null);
c.close();
});
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index 7eba3c1..e3a6da2 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -11,76 +11,84 @@
testMultiController() {
// Test normal flow.
- var c = new StreamController.broadcast();
+ var c = new StreamController();
Events expectedEvents = new Events()
..add(42)
..add("dibs")
..error("error!")
..error("error too!")
..close();
- Events actualEvents = new Events.capture(c.stream);
+ Events actualEvents = new Events.capture(c.stream.asBroadcastStream());
expectedEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test automatic unsubscription on error.
- c = new StreamController.broadcast();
+ c = new StreamController();
expectedEvents = new Events()..add(42)..error("error");
- actualEvents = new Events.capture(c.stream, unsubscribeOnError: true);
+ actualEvents = new Events.capture(c.stream.asBroadcastStream(),
+ cancelOnError: true);
Events sentEvents =
new Events()..add(42)..error("error")..add("Are you there?");
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test manual unsubscription.
- c = new StreamController.broadcast();
+ c = new StreamController();
expectedEvents = new Events()..add(42)..error("error")..add(37);
- actualEvents = new Events.capture(c.stream, unsubscribeOnError: false);
+ actualEvents = new Events.capture(c.stream.asBroadcastStream(),
+ cancelOnError: false);
expectedEvents.replay(c);
actualEvents.subscription.cancel();
c.add("Are you there"); // Not sent to actualEvents.
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test filter.
- c = new StreamController.broadcast();
+ c = new StreamController();
expectedEvents = new Events()
..add("a string")..add("another string")..close();
sentEvents = new Events()
..add("a string")..add(42)..add("another string")..close();
- actualEvents = new Events.capture(c.stream.where((v) => v is String));
+ actualEvents = new Events.capture(c.stream
+ .asBroadcastStream()
+ .where((v) => v is String));
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test map.
- c = new StreamController.broadcast();
+ c = new StreamController();
expectedEvents = new Events()..add("abab")..error("error")..close();
sentEvents = new Events()..add("ab")..error("error")..close();
- actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
+ actualEvents = new Events.capture(c.stream
+ .asBroadcastStream()
+ .map((v) => "$v$v"));
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test handleError.
- c = new StreamController.broadcast();
+ c = new StreamController();
expectedEvents = new Events()..add("ab")..error("[foo]");
sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
- actualEvents = new Events.capture(c.stream.handleError((v) {
- if (v.error is String) {
- throw new AsyncError("[${v.error}]",
- "other stack");
+ actualEvents = new Events.capture(c.stream
+ .asBroadcastStream()
+ .handleError((error) {
+ if (error is String) {
+ // TODO(floitsch): this test originally changed the stacktrace.
+ throw "[${error}]";
}
- }), unsubscribeOnError: true);
+ }), cancelOnError: true);
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// reduce is tested asynchronously and therefore not in this file.
// Test expand
- c = new StreamController.broadcast();
+ c = new StreamController();
sentEvents = new Events()..add(3)..add(2)..add(4)..close();
expectedEvents = new Events()..add(1)..add(2)..add(3)
..add(1)..add(2)
..add(1)..add(2)..add(3)..add(4)
..close();
- actualEvents = new Events.capture(c.stream.expand((v) {
+ actualEvents = new Events.capture(c.stream.asBroadcastStream().expand((v) {
var l = [];
for (int i = 0; i < v; i++) l.add(i + 1);
return l;
@@ -89,14 +97,14 @@
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test transform.
- c = new StreamController.broadcast();
+ c = new StreamController();
sentEvents = new Events()..add("a")..error(42)..add("b")..close();
expectedEvents =
new Events()..error("a")..add(42)..error("b")..add("foo")..close();
- actualEvents = new Events.capture(c.stream.transform(
+ actualEvents = new Events.capture(c.stream.asBroadcastStream().transform(
new StreamTransformer(
- handleData: (v, s) { s.addError(new AsyncError(v)); },
- handleError: (e, s) { s.add(e.error); },
+ handleData: (v, s) { s.addError(v); },
+ handleError: (e, s) { s.add(e); },
handleDone: (s) {
s.add("foo");
@@ -108,7 +116,7 @@
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test multiple filters.
- c = new StreamController.broadcast();
+ c = new StreamController();
sentEvents = new Events()..add(42)
..add("snugglefluffy")
..add(7)
@@ -117,20 +125,20 @@
..close();
expectedEvents = new Events()..add(42)..error("not FormatException");
actualEvents = new Events.capture(
- c.stream.where((v) => v is String)
+ c.stream.asBroadcastStream().where((v) => v is String)
.map((v) => int.parse(v))
- .handleError((v) {
- if (v.error is! FormatException) throw v;
+ .handleError((error) {
+ if (error is! FormatException) throw error;
})
.where((v) => v > 10),
- unsubscribeOnError: true);
+ cancelOnError: true);
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
// Test subscription changes while firing.
- c = new StreamController.broadcast();
+ c = new StreamController();
var sink = c.sink;
- var stream = c.stream;
+ var stream = c.stream.asBroadcastStream();
var counter = 0;
var subscription = stream.listen(null);
subscription.onData((data) {
@@ -169,7 +177,7 @@
// Test automatic unsubscription on error.
c = new StreamController();
expectedEvents = new Events()..add(42)..error("error");
- actualEvents = new Events.capture(c.stream, unsubscribeOnError: true);
+ actualEvents = new Events.capture(c.stream, cancelOnError: true);
Events sentEvents =
new Events()..add(42)..error("error")..add("Are you there?");
sentEvents.replay(c);
@@ -178,7 +186,7 @@
// Test manual unsubscription.
c = new StreamController();
expectedEvents = new Events()..add(42)..error("error")..add(37);
- actualEvents = new Events.capture(c.stream, unsubscribeOnError: false);
+ actualEvents = new Events.capture(c.stream, cancelOnError: false);
expectedEvents.replay(c);
actualEvents.subscription.cancel();
c.add("Are you there"); // Not sent to actualEvents.
@@ -206,12 +214,12 @@
c = new StreamController();
expectedEvents = new Events()..add("ab")..error("[foo]");
sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
- actualEvents = new Events.capture(c.stream.handleError((v) {
- if (v.error is String) {
- throw new AsyncError("[${v.error}]",
- "other stack");
+ actualEvents = new Events.capture(c.stream.handleError((error) {
+ if (error is String) {
+ // TODO(floitsch): this error originally changed the stack trace.
+ throw "[${error}]";
}
- }), unsubscribeOnError: true);
+ }), cancelOnError: true);
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
@@ -262,8 +270,8 @@
Future<bool> contains = c.stream.contains("b");
contains.then((var c) {
Expect.fail("no value expected");
- }).catchError((AsyncError e) {
- Expect.equals("FAIL", e.error);
+ }).catchError((error) {
+ Expect.equals("FAIL", error);
});
sentEvents.replay(c);
}
@@ -275,8 +283,8 @@
new Events()..error("a")..add(42)..error("b")..add("foo")..close();
actualEvents = new Events.capture(c.stream.transform(
new StreamTransformer(
- handleData: (v, s) { s.addError(new AsyncError(v)); },
- handleError: (e, s) { s.add(e.error); },
+ handleData: (v, s) { s.addError(v); },
+ handleError: (e, s) { s.add(e); },
handleDone: (s) {
s.add("foo");
s.close();
@@ -296,11 +304,11 @@
actualEvents = new Events.capture(
c.stream.where((v) => v is String)
.map((v) => int.parse(v))
- .handleError((v) {
- if (v.error is! FormatException) throw v;
+ .handleError((error) {
+ if (error is! FormatException) throw error;
})
.where((v) => v > 10),
- unsubscribeOnError: true);
+ cancelOnError: true);
sentEvents.replay(c);
Expect.listEquals(expectedEvents.events, actualEvents.events);
@@ -387,16 +395,14 @@
}
testClosed() {
- for (StreamController c in [new StreamController(),
- new StreamController.broadcast()]) {
- Expect.isFalse(c.isClosed);
- c.add(42);
- Expect.isFalse(c.isClosed);
- c.addError("bad");
- Expect.isFalse(c.isClosed);
- c.close();
- Expect.isTrue(c.isClosed);
- }
+ StreamController c = new StreamController();
+ Expect.isFalse(c.isClosed);
+ c.add(42);
+ Expect.isFalse(c.isClosed);
+ c.addError("bad");
+ Expect.isFalse(c.isClosed);
+ c.close();
+ Expect.isTrue(c.isClosed);
}
main() {
diff --git a/tests/lib/async/stream_event_transform_test.dart b/tests/lib/async/stream_event_transform_test.dart
index 78c79cd..87f114c 100644
--- a/tests/lib/async/stream_event_transform_test.dart
+++ b/tests/lib/async/stream_event_transform_test.dart
@@ -10,15 +10,15 @@
import 'event_helper.dart';
void handleData(int data, EventSink<int> sink) {
- sink.addError(new AsyncError("$data"));
+ sink.addError("$data");
sink.add(data + 1);
}
-void handleError(AsyncError e, EventSink<int> sink) {
- String value = e.error;
+void handleError(error, EventSink<int> sink) {
+ String value = error;
int data = int.parse(value);
sink.add(data);
- sink.addError(new AsyncError("${data + 1}"));
+ sink.addError("${data + 1}");
}
void handleDone(EventSink<int> sink) {
@@ -28,15 +28,14 @@
class EventTransformer extends StreamEventTransformer<int,int> {
void handleData(int data, EventSink<int> sink) {
- sink.addError(new AsyncError("$data"));
+ sink.addError("$data");
sink.add(data + 1);
}
- void handleError(AsyncError e, EventSink<int> sink) {
- String value = e.error;
+ void handleError(String value, EventSink<int> sink) {
int data = int.parse(value);
sink.add(data);
- sink.addError(new AsyncError("${data + 1}"));
+ sink.addError("${data + 1}");
}
void handleDone(EventSink<int> sink) {
diff --git a/tests/lib/async/stream_single_test.dart b/tests/lib/async/stream_single_test.dart
index 3bc889a..fe0b384 100644
--- a/tests/lib/async/stream_single_test.dart
+++ b/tests/lib/async/stream_single_test.dart
@@ -22,14 +22,14 @@
test("single empty", () {
StreamController c = new StreamController();
Future f = c.stream.single;
- f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+ f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
new Events.fromIterable([]).replay(c);
});
test("single error", () {
StreamController c = new StreamController();
Future f = c.stream.single;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..close();
errorEvents.replay(c);
});
@@ -37,7 +37,7 @@
test("single error 2", () {
StreamController c = new StreamController();
Future f = c.stream.single;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..error("error")..error("error2")..close();
errorEvents.replay(c);
});
@@ -45,7 +45,7 @@
test("single error 3", () {
StreamController c = new StreamController();
Future f = c.stream.single;
- f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+ f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
Events errorEvents = new Events()..add(499)..error("error")..close();
errorEvents.replay(c);
});
diff --git a/tests/lib/async/stream_single_to_multi_subscriber_test.dart b/tests/lib/async/stream_single_to_multi_subscriber_test.dart
index 8424cb2..1f4d693 100644
--- a/tests/lib/async/stream_single_to_multi_subscriber_test.dart
+++ b/tests/lib/async/stream_single_to_multi_subscriber_test.dart
@@ -37,7 +37,7 @@
});
test("tomulti no-op", () {
- StreamController c = new StreamController<int>.broadcast();
+ StreamController c = new StreamController<int>();
Stream<int> multi = c.stream.asBroadcastStream();
Events expected = new Events.fromIterable([1, 2, 3, 4, 5]);
Events actual1 = new Events.capture(multi);
diff --git a/tests/lib/async/stream_state_helper.dart b/tests/lib/async/stream_state_helper.dart
index b982d9d..dbc645a 100644
--- a/tests/lib/async/stream_state_helper.dart
+++ b/tests/lib/async/stream_state_helper.dart
@@ -10,21 +10,23 @@
class StreamProtocolTest {
StreamController _controller;
+ Stream _controllerStream;
StreamSubscription _subscription;
List<Event> _expectations = new List<Event>();
int _nextExpectationIndex = 0;
Function _onComplete;
StreamProtocolTest([bool broadcast = false]) {
+ _controller = new StreamController(
+ onListen: _onSubcription,
+ onPause: _onPause,
+ onResume: _onPause,
+ onCancel: _onSubcription);
+ // TODO(lrn): Make it work with multiple subscribers too.
if (broadcast) {
- _controller = new StreamController.broadcast(
- onPauseStateChange: _onPause,
- onSubscriptionStateChange: _onSubcription);
- // TODO(lrn): Make it work with multiple subscribers too.
+ _controllerStream = _controller.stream.asBroadcastStream();
} else {
- _controller = new StreamController(
- onPauseStateChange: _onPause,
- onSubscriptionStateChange: _onSubcription);
+ _controllerStream = _controller.stream;
}
_onComplete = expectAsync0((){
_onComplete = null; // Being null marks the test to be complete.
@@ -36,15 +38,15 @@
void error(var error) { _controller.addError(error); }
void close() { _controller.close(); }
- void subscribe({bool unsubscribeOnError : false}) {
+ void subscribe({bool cancelOnError : false}) {
// TODO(lrn): Handle more subscriptions (e.g., a subscription-id
// per subscription, and an id on event _expectations).
if (_subscription != null) throw new StateError("Already subscribed");
- _subscription = _controller.stream.listen(_onData,
- onError: _onError,
- onDone: _onDone,
- unsubscribeOnError:
- unsubscribeOnError);
+ _subscription = _controllerStream.listen(_onData,
+ onError: _onError,
+ onDone: _onDone,
+ cancelOnError:
+ cancelOnError);
}
void pause([Future resumeSignal]) {
@@ -73,11 +75,11 @@
});
}
- void _onError(AsyncError error) {
+ void _onError(error) {
_withNextExpectation((Event expect) {
if (!expect.matchError(error)) {
_fail("Expected: $expect\n"
- "Found : [Data: ${error.error}]");
+ "Found : [Data: ${error}]");
}
});
}
@@ -190,7 +192,7 @@
if (_action != null) _action();
return true;
}
- bool matchError(AsyncError e) {
+ bool matchError(e) {
if (!_testError(e)) return false;
if (_action != null) _action();
return true;
@@ -233,7 +235,7 @@
class ErrorEvent extends Event {
final error;
ErrorEvent(this.error, void action()) : super(action);
- bool _testError(AsyncError error) => this.error == error.error;
+ bool _testError(error) => this.error == error;
String toString() => "[Error: $error]";
}
@@ -270,8 +272,8 @@
_actual = "*[Data $data]";
return true;
}
- bool _testError(AsyncError error) {
- _actual = "*[Error ${error.error}]";
+ bool _testError(error) {
+ _actual = "*[Error ${error}]";
return true;
}
bool _testDone() {
diff --git a/tests/lib/async/stream_state_nonzero_timer_test.dart b/tests/lib/async/stream_state_nonzero_timer_test.dart
index d05f9fa..868f760 100644
--- a/tests/lib/async/stream_state_nonzero_timer_test.dart
+++ b/tests/lib/async/stream_state_nonzero_timer_test.dart
@@ -15,7 +15,8 @@
main() {
mainTest(false);
- mainTest(true);
+ // TODO(floitsch): reenable?
+ // mainTest(true);
}
mainTest(bool broadcast) {
diff --git a/tests/lib/async/stream_state_test.dart b/tests/lib/async/stream_state_test.dart
index f27697b..d6d873f 100644
--- a/tests/lib/async/stream_state_test.dart
+++ b/tests/lib/async/stream_state_test.dart
@@ -12,7 +12,8 @@
main() {
mainTest(false);
- mainTest(true);
+ // TODO(floitsch): reenable?
+ // mainTest(true);
}
mainTest(bool broadcast) {
@@ -58,7 +59,7 @@
..expectData(42)
..expectError("bad")
..expectSubscription(false, !broadcast);
- t..subscribe(unsubscribeOnError: true)
+ t..subscribe(cancelOnError: true)
..add(42)
..error("bad")
..add(43)
@@ -73,7 +74,7 @@
..expectData(43)
..expectDone()
..expectSubscription(false, false);
- t..subscribe(unsubscribeOnError: false)
+ t..subscribe(cancelOnError: false)
..add(42)
..error("bad")
..add(43)
diff --git a/tests/lib/async/stream_subscription_as_future_test.dart b/tests/lib/async/stream_subscription_as_future_test.dart
new file mode 100644
index 0000000..5be8f79
--- /dev/null
+++ b/tests/lib/async/stream_subscription_as_future_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the Stream.single method.
+library stream_single_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+ test("subscription.asStream success", () {
+ Stream stream = new Stream.fromIterable([1, 2, 3]);
+ var output = [];
+ var subscription = stream.listen((x) { output.add(x); });
+ subscription.asFuture(output).then(expectAsync1((o) {
+ Expect.listEquals([1, 2, 3], o);
+ }));
+ });
+
+ test("subscription.asStream success2", () {
+ StreamController controller = new StreamController();
+ [1, 2, 3].forEach(controller.add);
+ controller.close();
+ Stream stream = controller.stream;
+ var output = [];
+ var subscription = stream.listen((x) { output.add(x); });
+ subscription.asFuture(output).then(expectAsync1((o) {
+ Expect.listEquals([1, 2, 3], o);
+ }));
+ });
+
+ test("subscription.asStream success 3", () {
+ Stream stream = new Stream.fromIterable([1, 2, 3]).map((x) => x);
+ var output = [];
+ var subscription = stream.listen((x) { output.add(x); });
+ subscription.asFuture(output).then(expectAsync1((o) {
+ Expect.listEquals([1, 2, 3], o);
+ }));
+ });
+
+ test("subscription.asStream failure", () {
+ StreamController controller = new StreamController();
+ [1, 2, 3].forEach(controller.add);
+ controller.addError("foo");
+ controller.close();
+ Stream stream = controller.stream;
+ var output = [];
+ var subscription = stream.listen((x) { output.add(x); });
+ subscription.asFuture(output).catchError(expectAsync1((error) {
+ Expect.equals(error, "foo");
+ }));
+ });
+
+ test("subscription.asStream failure2", () {
+ Stream stream = new Stream.fromIterable([1, 2, 3, 4])
+ .map((x) {
+ if (x == 4) throw "foo";
+ return x;
+ });
+ var output = [];
+ var subscription = stream.listen((x) { output.add(x); });
+ subscription.asFuture(output).catchError(expectAsync1((error) {
+ Expect.equals(error, "foo");
+ }));
+ });
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 33c57ac..5c2c79f 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// TODO(rmacnak): Move the existing mirror tests here (a place for
+// TODO(rmacnak): Move the existing mirror tests here (a place for
// cross-implementation tests).
library MirrorsTest;
@@ -11,48 +11,50 @@
var topLevelField;
-class Class {
+class Class<T> {
Class() { this.field = "default value"; }
Class.withInitialValue(this.field);
var field;
static var staticField;
}
+typedef Typedef();
+
testFieldAccess(mirrors) {
var instance = new Class();
- var libMirror = mirrors.libraries["MirrorsTest"];
- var classMirror = libMirror.classes["Class"];
+ var libMirror = mirrors.libraries[const Symbol("MirrorsTest")];
+ var classMirror = libMirror.classes[const Symbol("Class")];
var instMirror = reflect(instance);
- libMirror.setFieldAsync('topLevelField', 42);
- var future = libMirror.getFieldAsync('topLevelField');
+ libMirror.setFieldAsync(new Symbol('topLevelField'), 42);
+ var future = libMirror.getFieldAsync(new Symbol('topLevelField'));
future.then(expectAsync1((resultMirror) {
expect(resultMirror.reflectee, equals(42));
- expect(topLevelField, equals(42));
- }));
-
- classMirror.setFieldAsync('staticField', 43);
- future = classMirror.getFieldAsync('staticField');
- future.then(expectAsync1((resultMirror) {
- expect(resultMirror.reflectee, equals(43));
- expect(Class.staticField, equals(43));
+ expect(topLevelField, equals(42));
}));
- instMirror.setFieldAsync('field', 44);
- future = instMirror.getFieldAsync('field');
+ classMirror.setFieldAsync(new Symbol('staticField'), 43);
+ future = classMirror.getFieldAsync(new Symbol('staticField'));
+ future.then(expectAsync1((resultMirror) {
+ expect(resultMirror.reflectee, equals(43));
+ expect(Class.staticField, equals(43));
+ }));
+
+ instMirror.setFieldAsync(new Symbol('field'), 44);
+ future = instMirror.getFieldAsync(new Symbol('field'));
future.then(expectAsync1((resultMirror) {
expect(resultMirror.reflectee, equals(44));
- expect(instance.field, equals(44));
+ expect(instance.field, equals(44));
}));
}
testClosureMirrors(mirrors) {
var closure = (x, y, z) { return x + y + z; };
-
+
var mirror = reflect(closure);
expect(mirror is ClosureMirror, equals(true));
-
+
var funcMirror = mirror.function;
expect(funcMirror is MethodMirror, equals(true));
expect(funcMirror.parameters.length, equals(3));
@@ -64,17 +66,17 @@
}
testInvokeConstructor(mirrors) {
- var libMirror = mirrors.libraries["MirrorsTest"];
- var classMirror = libMirror.classes["Class"];
-
- var future = classMirror.newInstanceAsync('', []);
+ var libMirror = mirrors.libraries[const Symbol("MirrorsTest")];
+ var classMirror = libMirror.classes[const Symbol("Class")];
+
+ var future = classMirror.newInstanceAsync(new Symbol(''), []);
future.then(expectAsync1((resultMirror) {
var instance = resultMirror.reflectee;
expect(instance is Class, equals(true));
expect(instance.field, equals("default value"));
}));
- future = classMirror.newInstanceAsync('withInitialValue', [45]);
+ future = classMirror.newInstanceAsync(new Symbol('withInitialValue'), [45]);
future.then(expectAsync1((resultMirror) {
var instance = resultMirror.reflectee;
expect(instance is Class, equals(true));
@@ -82,11 +84,42 @@
}));
}
+testNames(mirrors) {
+ var libMirror = mirrors.libraries[const Symbol('MirrorsTest')];
+ var classMirror = libMirror.classes[const Symbol('Class')];
+ var typedefMirror = libMirror.members[const Symbol('Typedef')];
+ var methodMirror = libMirror.functions[const Symbol('testNames')];
+ var variableMirror = classMirror.variables[const Symbol('field')];
+
+ expect(libMirror.simpleName, equals(const Symbol('MirrorsTest')));
+ expect(libMirror.qualifiedName, equals(const Symbol('MirrorsTest')));
+
+ expect(classMirror.simpleName, equals(const Symbol('Class')));
+ expect(classMirror.qualifiedName, equals(const Symbol('MirrorsTest.Class')));
+
+ TypeVariableMirror typeVariable = classMirror.typeVariables.values.single;
+ expect(typeVariable.simpleName, equals(const Symbol('T')));
+ expect(typeVariable.qualifiedName,
+ equals(const Symbol('MirrorsTest.Class.T')));
+
+ expect(typedefMirror.simpleName, equals(const Symbol('Typedef')));
+ expect(typedefMirror.qualifiedName,
+ equals(const Symbol('MirrorsTest.Typedef')));
+
+ expect(methodMirror.simpleName, equals(const Symbol('testNames')));
+ expect(methodMirror.qualifiedName,
+ equals(const Symbol('MirrorsTest.testNames')));
+
+ expect(variableMirror.simpleName, equals(const Symbol('field')));
+ expect(variableMirror.qualifiedName,
+ equals(const Symbol('MirrorsTest.Class.field')));
+}
+
main() {
var mirrors = currentMirrorSystem();
test("Test field access", () { testFieldAccess(mirrors); });
test("Test closure mirrors", () { testClosureMirrors(mirrors); });
test("Test invoke constructor", () { testInvokeConstructor(mirrors); });
+ test("Test simple and qualifiedName", () { testNames(mirrors); });
}
-
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index bc1f246..9fa6349 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -6,6 +6,7 @@
library DartDebugger;
+import "dart:async";
import "dart:io";
import "dart:math";
import "dart:utf";
@@ -458,11 +459,16 @@
},
onError: (e) {
print("Error '$e' detected in input stream from debug target");
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
close(killDebugee: true);
});
},
- onError: (asyncErr) {
- error("Error while connecting to debugee: $asyncErr");
+ onError: (e) {
+ String msg = "Error while connecting to debugee: $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ error(msg);
close(killDebugee: true);
});
}
@@ -518,6 +524,8 @@
onError: (e) {
if (++retries >= 3) {
print('unable to find unused port: $e');
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
return -1;
} else {
// Retry with another random port.
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index d8c9ebb..562b91e 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -41,7 +41,7 @@
}
// 4.0e40 is larger than the largest representable float.
- floatArray.setRange(1, 2, const [8.0, 4.0e40]);
+ floatArray.setRange(1, 3, const [8.0, 4.0e40]);
Expect.equals(20, floatArray[0]);
Expect.equals(8, floatArray[1]);
Expect.equals(double.INFINITY, floatArray[2]);
@@ -59,7 +59,7 @@
});
Expect.throws(() {
- floatArray.setRange(3, 1, list);
+ floatArray.setRange(3, 4, list);
});
}
@@ -125,7 +125,7 @@
}
// Unlike Float32Array we can properly represent 4.0e40
- floatArray.setRange(1, 2, const [8.0, 4.0e40]);
+ floatArray.setRange(1, 3, const [8.0, 4.0e40]);
Expect.equals(20, floatArray[0]);
Expect.equals(8, floatArray[1]);
Expect.equals(4.0e40, floatArray[2]);
@@ -143,7 +143,7 @@
});
Expect.throws(() {
- floatArray.setRange(3, 1, list);
+ floatArray.setRange(3, 4, list);
});
}
diff --git a/tests/standalone/io/dart_std_io_pipe_test.dart b/tests/standalone/io/dart_std_io_pipe_test.dart
index bdbffeb..e3dfec0 100644
--- a/tests/standalone/io/dart_std_io_pipe_test.dart
+++ b/tests/standalone/io/dart_std_io_pipe_test.dart
@@ -25,7 +25,7 @@
RandomAccessFile pipeOut = new File(fileName).openSync();
int length = pipeOut.lengthSync();
List data = new List<int>(length);
- pipeOut.readListSync(data, 0, length);
+ pipeOut.readIntoSync(data, 0, length);
Expect.equals(content, new String.fromCharCodes(data));
pipeOut.closeSync();
}
@@ -93,7 +93,7 @@
});
future.catchError((error) {
dir.deleteSync(recursive: true);
- Expect.fail(error.error.toString());
+ Expect.fail(error.toString());
});
}
diff --git a/tests/standalone/io/directory_error_test.dart b/tests/standalone/io/directory_error_test.dart
index 33418ef..123954c 100644
--- a/tests/standalone/io/directory_error_test.dart
+++ b/tests/standalone/io/directory_error_test.dart
@@ -35,8 +35,8 @@
Expect.throws(() => inNonExistent.createSync(),
(e) => checkCreateInNonExistentFileException(e));
- inNonExistent.create().catchError((e) {
- checkCreateInNonExistentFileException(e.error);
+ inNonExistent.create().catchError((error) {
+ checkCreateInNonExistentFileException(error);
done();
});
}
@@ -62,8 +62,8 @@
Expect.throws(() => nonExistent.createTempSync(),
(e) => checkCreateTempInNonExistentFileException(e));
- nonExistent.createTemp().catchError((e) {
- checkCreateTempInNonExistentFileException(e.error);
+ nonExistent.createTemp().catchError((error) {
+ checkCreateTempInNonExistentFileException(error);
done();
});
}
@@ -84,8 +84,8 @@
Expect.throws(() => nonExistent.deleteSync(),
(e) => checkDeleteNonExistentFileException(e));
- nonExistent.delete().catchError((e) {
- checkDeleteNonExistentFileException(e.error);
+ nonExistent.delete().catchError((error) {
+ checkDeleteNonExistentFileException(error);
done();
});
}
@@ -107,8 +107,8 @@
Expect.throws(() => nonExistent.deleteSync(recursive: true),
(e) => checkDeleteRecursivelyNonExistentFileException(e));
- nonExistent.delete(recursive: true).catchError((e) {
- checkDeleteRecursivelyNonExistentFileException(e.error);
+ nonExistent.delete(recursive: true).catchError((error) {
+ checkDeleteRecursivelyNonExistentFileException(error);
done();
});
}
@@ -130,9 +130,8 @@
}
-bool checkAsyncListNonExistentFileException(e) {
- Expect.isTrue(e is AsyncError);
- return checkListNonExistentFileException(e.error);
+bool checkAsyncListNonExistentFileException(error) {
+ return checkListNonExistentFileException(error);
}
@@ -155,8 +154,8 @@
(e) => e is DirectoryIOException);
var renameDone = nonExistent.rename(newPath);
renameDone.then((ignore) => Expect.fail('rename non existent'))
- .catchError((e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ .catchError((error) {
+ Expect.isTrue(error is DirectoryIOException);
done();
});
}
@@ -171,8 +170,8 @@
(e) => e is DirectoryIOException);
var renameDone = d.rename(newPath);
renameDone.then((ignore) => Expect.fail('rename file as directory'))
- .catchError((e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ .catchError((error) {
+ Expect.isTrue(error is DirectoryIOException);
done();
});
}
@@ -187,8 +186,8 @@
(e) => e is DirectoryIOException);
var renameDone = temp1.rename(fileName);
renameDone.then((ignore) => Expect.fail('rename dir overwrite file'))
- .catchError((e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ .catchError((error) {
+ Expect.isTrue(error is DirectoryIOException);
temp1.deleteSync(recursive: true);
done();
});
diff --git a/tests/standalone/io/directory_fuzz_test.dart b/tests/standalone/io/directory_fuzz_test.dart
index c1dadef..dda9fe3 100644
--- a/tests/standalone/io/directory_fuzz_test.dart
+++ b/tests/standalone/io/directory_fuzz_test.dart
@@ -51,7 +51,7 @@
futures.add(doItAsync(() {
return d.exists().then((res) {
if (!res) return d.delete(recursive: true);
- return new Future.immediate(true);
+ return new Future.value(true);
});
}));
typeMapping.forEach((k2, v2) {
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index decf05d..d9ca0de 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -89,9 +89,8 @@
setupListerHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
- onError: (e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is DirectoryIOException);
+ onError: (error) {
+ Expect.isTrue(error is DirectoryIOException);
});
}
new Directory("").createTemp().then((d) {
@@ -109,9 +108,8 @@
setupListHandlers(Stream<FileSystemEntity> stream) {
stream.listen(
(_) => Expect.fail("Listing of non-existing directory should fail"),
- onError: (e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is DirectoryIOException);
+ onError: (error) {
+ Expect.isTrue(error is DirectoryIOException);
if (++errors == 2) {
d.delete(recursive: true).then((_) {
port.close();
@@ -141,8 +139,8 @@
setupFutureHandlers(future) {
future.then((ignore) {
Expect.fail("Deletion of non-existing directory should fail");
- }).catchError((e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is DirectoryIOException);
});
}
@@ -169,8 +167,8 @@
}
var long = new Directory("${buffer.toString()}");
var errors = 0;
- onError(e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ onError(error) {
+ Expect.isTrue(error is DirectoryIOException);
if (++errors == 2) {
d.delete(recursive: true).then((ignore) => port.close());
}
@@ -555,8 +553,8 @@
file.create().then((_) {
subDir.create()
.then((_) { Expect.fail("dir create should fail on existing file"); })
- .catchError((e) {
- Expect.isTrue(e.error is DirectoryIOException);
+ .catchError((error) {
+ Expect.isTrue(error is DirectoryIOException);
temp.delete(recursive: true).then((_) {
port.close();
});
diff --git a/tests/standalone/io/echo_server_stream_test.dart b/tests/standalone/io/echo_server_stream_test.dart
index dfd264d..4c00422 100644
--- a/tests/standalone/io/echo_server_stream_test.dart
+++ b/tests/standalone/io/echo_server_stream_test.dart
@@ -57,7 +57,10 @@
}
void errorHandler(e) {
- Expect.fail("Socket error $e");
+ String msg = "Socket error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
}
void connectHandler() {
@@ -115,7 +118,7 @@
int bytesRead;
bytesRead = data.length;
if (bytesRead > 0) {
- buffer.setRange(offset, data.length, data);
+ buffer.setRange(offset, offset + data.length, data);
offset += bytesRead;
for (int i = 0; i < offset; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
@@ -128,7 +131,10 @@
}
void errorHandler(e) {
- Expect.fail("Socket error $e");
+ String msg = "Socket error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
}
connection.listen(dataReceived, onError: errorHandler);
diff --git a/tests/standalone/io/file_error_test.dart b/tests/standalone/io/file_error_test.dart
index e1741fd..16c0e24 100644
--- a/tests/standalone/io/file_error_test.dart
+++ b/tests/standalone/io/file_error_test.dart
@@ -53,8 +53,8 @@
var openFuture = file.open(mode: FileMode.READ);
openFuture.then((raf) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkOpenNonExistentFileException(e.error);
+ .catchError((error) {
+ checkOpenNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -75,8 +75,8 @@
var delete = file.delete();
delete.then((ignore) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkDeleteNonExistentFileException(e.error);
+ .catchError((error) {
+ checkDeleteNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -97,8 +97,8 @@
var lenFuture = file.length();
lenFuture.then((len) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkLengthNonExistentFileException(e.error);
+ .catchError((error) {
+ checkLengthNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -134,8 +134,8 @@
var create = file.create();
create.then((ignore) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkCreateInNonExistentDirectoryException(e.error);
+ .catchError((error) {
+ checkCreateInNonExistentDirectoryException(error);
p.toSendPort().send(null);
});
}
@@ -165,8 +165,8 @@
var fullPathFuture = file.fullPath();
fullPathFuture.then((path) => Expect.fail("Unreachable code $path"))
- .catchError((e) {
- checkFullPathOnNonExistentDirectoryException(e.error);
+ .catchError((error) {
+ checkFullPathOnNonExistentDirectoryException(error);
p.toSendPort().send(null);
});
}
@@ -197,8 +197,8 @@
var dirFuture = file.directory();
dirFuture.then((directory) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkDirectoryInNonExistentDirectoryException(e.error);
+ .catchError((error) {
+ checkDirectoryInNonExistentDirectoryException(error);
p.toSendPort().send(null);
});
}
@@ -218,8 +218,8 @@
var readAsBytesFuture = file.readAsBytes();
readAsBytesFuture.then((data) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkOpenNonExistentFileException(e.error);
+ .catchError((error) {
+ checkOpenNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -239,8 +239,8 @@
var readAsStringFuture = file.readAsString(encoding: Encoding.ASCII);
readAsStringFuture.then((data) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkOpenNonExistentFileException(e.error);
+ .catchError((error) {
+ checkOpenNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -260,8 +260,8 @@
var readAsLinesFuture = file.readAsLines(encoding: Encoding.ASCII);
readAsLinesFuture.then((data) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkOpenNonExistentFileException(e.error);
+ .catchError((error) {
+ checkOpenNonExistentFileException(error);
p.toSendPort().send(null);
});
}
@@ -300,25 +300,25 @@
(e) => checkWriteReadOnlyFileException(e));
var writeByteFuture = openedFile.writeByte(0);
- writeByteFuture.catchError((e) {
- checkWriteReadOnlyFileException(e.error);
+ writeByteFuture.catchError((error) {
+ checkWriteReadOnlyFileException(error);
openedFile.close().then((ignore) => port.send(null));
});
});
}
-testWriteListToReadOnlyFile() {
+testWriteFromToReadOnlyFile() {
createTestFile((file, port) {
var openedFile = file.openSync(mode: FileMode.READ);
List data = [0, 1, 2, 3];
// Writing to read only file should throw an exception.
- Expect.throws(() => openedFile.writeListSync(data, 0, data.length),
+ Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkWriteReadOnlyFileException(e));
- var writeListFuture = openedFile.writeList(data, 0, data.length);
- writeListFuture.catchError((e) {
- checkWriteReadOnlyFileException(e.error);
+ var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
+ writeFromFuture.catchError((error) {
+ checkWriteReadOnlyFileException(error);
openedFile.close().then((ignore) => port.send(null));
});
});
@@ -337,8 +337,8 @@
var truncateFuture = openedFile.truncate(0);
truncateFuture.then((ignore) => Expect.fail("Unreachable code"))
- .catchError((e) {
- checkWriteReadOnlyFileException(e.error);
+ .catchError((error) {
+ checkWriteReadOnlyFileException(error);
openedFile.close().then((ignore) => port.send(null));
});
});
@@ -361,9 +361,9 @@
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeByteSync(0),
(e) => checkFileClosedException(e));
- Expect.throws(() => openedFile.writeListSync(data, 0, data.length),
+ Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
(e) => checkFileClosedException(e));
- Expect.throws(() => openedFile.readListSync(data, 0, data.length),
+ Expect.throws(() => openedFile.readIntoSync(data, 0, data.length),
(e) => checkFileClosedException(e));
Expect.throws(() => openedFile.writeStringSync("Hello"),
(e) => checkFileClosedException(e));
@@ -380,8 +380,8 @@
var errorCount = 0;
- _errorHandler(e) {
- checkFileClosedException(e.error);
+ _errorHandler(error) {
+ checkFileClosedException(error);
if (--errorCount == 0) {
port.send(null);
}
@@ -395,12 +395,12 @@
writeByteFuture.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
- var readListFuture = openedFile.readList(data, 0, data.length);
- readListFuture.then((bytesRead) => Expect.fail("Unreachable code"))
+ var readIntoFuture = openedFile.readInto(data, 0, data.length);
+ readIntoFuture.then((bytesRead) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
- var writeListFuture = openedFile.writeList(data, 0, data.length);
- writeListFuture.then((ignore) => Expect.fail("Unreachable code"))
+ var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
+ writeFromFuture.then((ignore) => Expect.fail("Unreachable code"))
.catchError(_errorHandler);
errorCount++;
var writeStringFuture = openedFile.writeString("Hello");
@@ -436,8 +436,8 @@
openedFile.close().then((ignore) {
var closeFuture = openedFile.close();
closeFuture.then((ignore) => null)
- .catchError((e) {
- Expect.isTrue(e.error is FileIOException);
+ .catchError((error) {
+ Expect.isTrue(error is FileIOException);
port.send(null);
});
});
@@ -486,7 +486,7 @@
testReadAsTextNonExistent();
testReadAsLinesNonExistent();
testWriteByteToReadOnlyFile();
- testWriteListToReadOnlyFile();
+ testWriteFromToReadOnlyFile();
testTruncateReadOnlyFile();
testOperateOnClosedFile();
testRepeatedlyCloseFile();
diff --git a/tests/standalone/io/file_fuzz_test.dart b/tests/standalone/io/file_fuzz_test.dart
index b210bff..3013a01 100644
--- a/tests/standalone/io/file_fuzz_test.dart
+++ b/tests/standalone/io/file_fuzz_test.dart
@@ -80,8 +80,8 @@
doItSync(() => opened.writeStringSync(p[0], p[1]));
}
for (var p in typePermutations(3)) {
- doItSync(() => opened.readListSync(p[0], p[1], p[2]));
- doItSync(() => opened.writeListSync(p[0], p[1], p[2]));
+ doItSync(() => opened.readIntoSync(p[0], p[1], p[2]));
+ doItSync(() => opened.writeFromSync(p[0], p[1], p[2]));
}
opened.closeSync();
}
@@ -108,8 +108,8 @@
futures.add(doItAsync(() => opened.writeString(p[0], p[1])));
}
for (var p in typePermutations(3)) {
- futures.add(doItAsync(() => opened.readList(p[0], p[1], p[2])));
- futures.add(doItAsync(() => opened.writeList(p[0], p[1], p[2])));
+ futures.add(doItAsync(() => opened.readInto(p[0], p[1], p[2])));
+ futures.add(doItAsync(() => opened.writeFrom(p[0], p[1], p[2])));
}
}
Future.wait(futures).then((ignore) {
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index 1406290..5f7f73f 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_test.dart
@@ -22,10 +22,10 @@
var readFuture = file.read(arg);
readFuture.then((bytes) {
Expect.fail('exception expected');
- }).catchError((e) {
+ }).catchError((error) {
errors++;
- Expect.isTrue(e.error is FileIOException);
- Expect.isTrue(e.error.toString().contains('Invalid arguments'));
+ Expect.isTrue(error is FileIOException);
+ Expect.isTrue(error.toString().contains('Invalid arguments'));
file.close().then((ignore) {
Expect.equals(1, errors);
port.close();
@@ -33,12 +33,12 @@
});
}
-void testReadListInvalidArgs(buffer, offset, length) {
+void testReadIntoInvalidArgs(buffer, start, end) {
var port = new ReceivePort();
String filename = getFilename("tests/vm/data/fixed_length_file");
var file = (new File(filename)).openSync();
try {
- file.readListSync(buffer, offset, length);
+ file.readIntoSync(buffer, start, end);
Expect.fail('exception expected');
} catch (e) {
Expect.isTrue(e is FileIOException);
@@ -46,13 +46,13 @@
}
var errors = 0;
- var readListFuture = file.readList(buffer, offset, length);
- readListFuture.then((bytes) {
+ var readIntoFuture = file.readInto(buffer, start, end);
+ readIntoFuture.then((bytes) {
Expect.fail('exception expected');
- }).catchError((e) {
+ }).catchError((error) {
errors++;
- Expect.isTrue(e.error is FileIOException);
- Expect.isTrue(e.error.toString().contains('Invalid arguments'));
+ Expect.isTrue(error is FileIOException);
+ Expect.isTrue(error.toString().contains('Invalid arguments'));
file.close().then((ignore) {
Expect.equals(1, errors);
port.close();
@@ -75,33 +75,33 @@
var writeByteFuture = file.writeByte(value);
writeByteFuture.then((ignore) {
Expect.fail('exception expected');
- }).catchError((s) {
- Expect.isTrue(s.error is FileIOException);
- Expect.isTrue(s.error.toString().contains('Invalid argument'));
+ }).catchError((error) {
+ Expect.isTrue(error is FileIOException);
+ Expect.isTrue(error.toString().contains('Invalid argument'));
file.close().then((ignore) {
port.close();
});
});
}
-void testWriteListInvalidArgs(buffer, offset, bytes) {
+void testWriteFromInvalidArgs(buffer, start, end) {
var port = new ReceivePort();
String filename = getFilename("tests/vm/data/fixed_length_file");
var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
try {
- file.writeListSync(buffer, offset, bytes);
+ file.writeFromSync(buffer, start, end);
Expect.fail('exception expected');
} catch (e) {
Expect.isTrue(e is FileIOException);
Expect.isTrue(e.toString().contains('Invalid arguments'));
}
- var writeListFuture = file.writeList(buffer, offset, bytes);
- writeListFuture.then((ignore) {
+ var writeFromFuture = file.writeFrom(buffer, start, end);
+ writeFromFuture.then((ignore) {
Expect.fail('exception expected');
- }).catchError((s) {
- Expect.isTrue(s.error is FileIOException);
- Expect.isTrue(s.error.toString().contains('Invalid arguments'));
+ }).catchError((error) {
+ Expect.isTrue(error is FileIOException);
+ Expect.isTrue(error.toString().contains('Invalid arguments'));
file.close().then((ignore) {
port.close();
});
@@ -122,8 +122,8 @@
var writeStringFuture = file.writeString(string, encoding: encoding);
writeStringFuture.then((ignore) {
Expect.fail('exception expected');
- }).catchError((s) {
- Expect.isTrue(s.error is FileIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is FileIOException);
file.close().then((ignore) {
port.close();
});
@@ -136,12 +136,12 @@
main() {
testReadInvalidArgs('asdf');
- testReadListInvalidArgs(12, 0, 1);
- testReadListInvalidArgs(new List(10), '0', 1);
- testReadListInvalidArgs(new List(10), 0, '1');
+ testReadIntoInvalidArgs(12, 0, 1);
+ testReadIntoInvalidArgs(new List(10), '0', 1);
+ testReadIntoInvalidArgs(new List(10), 0, '1');
testWriteByteInvalidArgs('asdf');
- testWriteListInvalidArgs(12, 0, 1);
- testWriteListInvalidArgs(new List(10), '0', 1);
- testWriteListInvalidArgs(new List(10), 0, '1');
+ testWriteFromInvalidArgs(12, 0, 1);
+ testWriteFromInvalidArgs(new List(10), '0', 1);
+ testWriteFromInvalidArgs(new List(10), 0, '1');
testWriteStringInvalidArgs("Hello, world", 42);
}
diff --git a/tests/standalone/io/file_system_delete_test.dart b/tests/standalone/io/file_system_delete_test.dart
index 84847bf..cf1d801 100644
--- a/tests/standalone/io/file_system_delete_test.dart
+++ b/tests/standalone/io/file_system_delete_test.dart
@@ -7,7 +7,7 @@
import "dart:io";
Future throws(callback()) {
- return new Future.immediate(null)
+ return new Future.value()
.then((_) => callback())
.then((_) { throw "Expected error"; },
onError: (_) {});
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index a4dc4ec..9ca0fe4 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -152,10 +152,12 @@
}
position += d.length;
},
- onError: (e) {
+ onError: (error) {
print('Error on input in testReadWriteStreamLargeFile');
- print('with error $e');
- throw e;
+ print('with error $error');
+ var trace = getAttachedStackTrace(error);
+ if (trace != null) print("StackTrace: $trace");
+ throw error;
},
onDone: () {
Expect.equals(expectedLength, position);
@@ -167,6 +169,8 @@
.catchError((e) {
print('Exception while deleting ReadWriteStreamLargeFile file');
print('Exception $e');
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
});
});
});
@@ -203,9 +207,9 @@
File file = new File(filename);
file.open(mode: READ).then((RandomAccessFile file) {
List<int> buffer = new List<int>(10);
- file.readList(buffer, 0, 5).then((bytes_read) {
+ file.readInto(buffer, 0, 5).then((bytes_read) {
Expect.equals(5, bytes_read);
- file.readList(buffer, 5, 5).then((bytes_read) {
+ file.readInto(buffer, 5, 10).then((bytes_read) {
Expect.equals(5, bytes_read);
Expect.equals(47, buffer[0]); // represents '/' in the file.
Expect.equals(47, buffer[1]); // represents '/' in the file.
@@ -229,9 +233,9 @@
RandomAccessFile raf = (new File(filename)).openSync();
List<int> buffer = new List<int>(42);
int bytes_read = 0;
- bytes_read = raf.readListSync(buffer, 0, 12);
+ bytes_read = raf.readIntoSync(buffer, 0, 12);
Expect.equals(12, bytes_read);
- bytes_read = raf.readListSync(buffer, 12, 30);
+ bytes_read = raf.readIntoSync(buffer, 12, 42);
Expect.equals(30, bytes_read);
Expect.equals(47, buffer[0]); // represents '/' in the file.
Expect.equals(47, buffer[1]); // represents '/' in the file.
@@ -265,7 +269,7 @@
final File file = new File(inFilename);
file.open(mode: READ).then((openedFile) {
List<int> buffer1 = new List<int>(42);
- openedFile.readList(buffer1, 0, 42).then((bytes_read) {
+ openedFile.readInto(buffer1, 0, 42).then((bytes_read) {
Expect.equals(42, bytes_read);
openedFile.close().then((ignore) {
// Write the contents of the file just read into another file.
@@ -278,12 +282,12 @@
Expect.fail("Not a full path");
}
file2.open(mode: WRITE).then((openedFile2) {
- openedFile2.writeList(buffer1, 0, bytes_read).then((ignore) {
+ openedFile2.writeFrom(buffer1, 0, bytes_read).then((ignore) {
openedFile2.close().then((ignore) {
List<int> buffer2 = new List<int>(bytes_read);
final File file3 = new File(outFilename);
file3.open(mode: READ).then((openedFile3) {
- openedFile3.readList(buffer2, 0, 42).then((bytes_read) {
+ openedFile3.readInto(buffer2, 0, 42).then((bytes_read) {
Expect.equals(42, bytes_read);
openedFile3.close().then((ignore) {
// Now compare the two buffers to check if they
@@ -322,17 +326,17 @@
Expect.isTrue(new File(filename).existsSync());
List<int> buffer = content.codeUnits;
RandomAccessFile openedFile = file.openSync(mode: WRITE);
- openedFile.writeListSync(buffer, 0, buffer.length);
+ openedFile.writeFromSync(buffer, 0, buffer.length);
openedFile.closeSync();
// Reopen the file in write mode to ensure that we overwrite the content.
openedFile = (new File(filename)).openSync(mode: WRITE);
- openedFile.writeListSync(buffer, 0, buffer.length);
+ openedFile.writeFromSync(buffer, 0, buffer.length);
Expect.equals(content.length, openedFile.lengthSync());
openedFile.closeSync();
// Open the file in append mode and ensure that we do not overwrite
// the existing content.
openedFile = (new File(filename)).openSync(mode: APPEND);
- openedFile.writeListSync(buffer, 0, buffer.length);
+ openedFile.writeFromSync(buffer, 0, buffer.length);
Expect.equals(content.length * 2, openedFile.lengthSync());
openedFile.closeSync();
file.deleteSync();
@@ -405,7 +409,7 @@
List<int> buffer1 = new List<int>(42);
int bytes_read = 0;
int bytes_written = 0;
- bytes_read = file.readListSync(buffer1, 0, 42);
+ bytes_read = file.readIntoSync(buffer1, 0, 42);
Expect.equals(42, bytes_read);
file.closeSync();
// Write the contents of the file just read into another file.
@@ -418,12 +422,50 @@
}
Expect.isTrue(new File(path).existsSync());
RandomAccessFile openedFile = outFile.openSync(mode: WRITE);
- openedFile.writeListSync(buffer1, 0, bytes_read);
+ openedFile.writeFromSync(buffer1, 0, bytes_read);
openedFile.closeSync();
// Now read the contents of the file just written.
List<int> buffer2 = new List<int>(bytes_read);
openedFile = (new File(outFilename)).openSync();
- bytes_read = openedFile.readListSync(buffer2, 0, 42);
+ bytes_read = openedFile.readIntoSync(buffer2, 0, 42);
+ Expect.equals(42, bytes_read);
+ openedFile.closeSync();
+ // Now compare the two buffers to check if they are identical.
+ Expect.equals(buffer1.length, buffer2.length);
+ for (int i = 0; i < buffer1.length; i++) {
+ Expect.equals(buffer1[i], buffer2[i]);
+ }
+ // Delete the output file.
+ outFile.deleteSync();
+ Expect.isFalse(outFile.existsSync());
+ }
+
+ static void testReadWriteNoArgsSync() {
+ // Read a file.
+ String inFilename = getFilename("tests/vm/data/fixed_length_file");
+ RandomAccessFile file = (new File(inFilename)).openSync();
+ List<int> buffer1 = new List<int>(42);
+ int bytes_read = 0;
+ int bytes_written = 0;
+ bytes_read = file.readIntoSync(buffer1);
+ Expect.equals(42, bytes_read);
+ file.closeSync();
+ // Write the contents of the file just read into another file.
+ String outFilename = tempDirectory.path + "/out_read_write_sync";
+ File outFile = new File(outFilename);
+ outFile.createSync();
+ String path = outFile.fullPathSync();
+ if (path[0] != '/' && path[0] != '\\' && path[1] != ':') {
+ Expect.fail("Not a full path");
+ }
+ Expect.isTrue(new File(path).existsSync());
+ RandomAccessFile openedFile = outFile.openSync(mode: WRITE);
+ openedFile.writeFromSync(buffer1);
+ openedFile.closeSync();
+ // Now read the contents of the file just written.
+ List<int> buffer2 = new List<int>(bytes_read);
+ openedFile = (new File(outFilename)).openSync();
+ bytes_read = openedFile.readIntoSync(buffer2, 0);
Expect.equals(42, bytes_read);
openedFile.closeSync();
// Now compare the two buffers to check if they are identical.
@@ -471,18 +513,18 @@
file.create().then((ignore) {
file.open(mode: WRITE).then((RandomAccessFile openedFile) {
// Write bytes from 0 to 7.
- openedFile.writeList([0], 0, 1);
- openedFile.writeList(const [1], 0, 1);
- openedFile.writeList(new MyListOfOneElement(2), 0, 1);
+ openedFile.writeFrom([0], 0, 1);
+ openedFile.writeFrom(const [1], 0, 1);
+ openedFile.writeFrom(new MyListOfOneElement(2), 0, 1);
var x = 12345678901234567890123456789012345678901234567890;
var y = 12345678901234567890123456789012345678901234567893;
- openedFile.writeList([y - x], 0, 1);
- openedFile.writeList([260], 0, 1); // 260 = 256 + 4 = 0x104.
- openedFile.writeList(const [261], 0, 1);
- openedFile.writeList(new MyListOfOneElement(262), 0, 1);
+ openedFile.writeFrom([y - x], 0, 1);
+ openedFile.writeFrom([260], 0, 1); // 260 = 256 + 4 = 0x104.
+ openedFile.writeFrom(const [261], 0, 1);
+ openedFile.writeFrom(new MyListOfOneElement(262), 0, 1);
x = 12345678901234567890123456789012345678901234567890;
y = 12345678901234567890123456789012345678901234568153;
- openedFile.writeList([y - x], 0, 1).then((ignore) {
+ openedFile.writeFrom([y - x], 0, 1).then((ignore) {
openedFile.close().then((ignore) {
// Check the written bytes.
final File file2 = new File(fileName);
@@ -490,7 +532,7 @@
var length = openedFile2.lengthSync();
Expect.equals(8, length);
List data = new List(length);
- openedFile2.readListSync(data, 0, length);
+ openedFile2.readIntoSync(data, 0, length);
for (var i = 0; i < data.length; i++) {
Expect.equals(i, data[i]);
}
@@ -594,10 +636,10 @@
input.position().then((position) {
Expect.equals(0, position);
List<int> buffer = new List<int>(100);
- input.readList(buffer, 0, 12).then((bytes_read) {
+ input.readInto(buffer, 0, 12).then((bytes_read) {
input.position().then((position) {
Expect.equals(12, position);
- input.readList(buffer, 12, 6).then((bytes_read) {
+ input.readInto(buffer, 12, 18).then((bytes_read) {
input.position().then((position) {
Expect.equals(18, position);
input.setPosition(8).then((ignore) {
@@ -618,9 +660,9 @@
RandomAccessFile input = (new File(filename)).openSync();
Expect.equals(0, input.positionSync());
List<int> buffer = new List<int>(100);
- input.readListSync(buffer, 0, 12);
+ input.readIntoSync(buffer, 0, 12);
Expect.equals(12, input.positionSync());
- input.readListSync(buffer, 12, 6);
+ input.readIntoSync(buffer, 12, 18);
Expect.equals(18, input.positionSync());
input.setPositionSync(8);
Expect.equals(8, input.positionSync());
@@ -631,7 +673,7 @@
File file = new File(tempDirectory.path + "/out_truncate");
List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
file.open(mode: WRITE).then((RandomAccessFile openedFile) {
- openedFile.writeList(buffer, 0, 10).then((ignore) {
+ openedFile.writeFrom(buffer, 0, 10).then((ignore) {
openedFile.length().then((length) {
Expect.equals(10, length);
openedFile.truncate(5).then((ignore) {
@@ -657,7 +699,7 @@
File file = new File(tempDirectory.path + "/out_truncate_sync");
List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
RandomAccessFile openedFile = file.openSync(mode: WRITE);
- openedFile.writeListSync(buffer, 0, 10);
+ openedFile.writeFromSync(buffer, 0, 10);
Expect.equals(10, openedFile.lengthSync());
openedFile.truncateSync(5);
Expect.equals(5, openedFile.lengthSync());
@@ -705,7 +747,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(100);
- openedFile.readListSync(buffer, 0, 10);
+ openedFile.readIntoSync(buffer, 0, 10);
} on FileIOException catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -716,7 +758,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(100);
- openedFile.writeListSync(buffer, 0, 10);
+ openedFile.writeFromSync(buffer, 0, 10);
} on FileIOException catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -782,7 +824,7 @@
RandomAccessFile openedFile = file.openSync(mode: WRITE);
try {
List<int> buffer = new List<int>(10);
- openedFile.readListSync(buffer, 0, 12);
+ openedFile.readIntoSync(buffer, 0, 12);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -793,7 +835,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.readListSync(buffer, 6, 6);
+ openedFile.readIntoSync(buffer, 6, 12);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -804,7 +846,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.readListSync(buffer, -1, 1);
+ openedFile.readIntoSync(buffer, -1, 1);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -815,7 +857,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.readListSync(buffer, 0, -1);
+ openedFile.readIntoSync(buffer, 0, -1);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -826,7 +868,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.writeListSync(buffer, 0, 12);
+ openedFile.writeFromSync(buffer, 0, 12);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -837,7 +879,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.writeListSync(buffer, 6, 6);
+ openedFile.writeFromSync(buffer, 6, 12);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -848,7 +890,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.writeListSync(buffer, -1, 1);
+ openedFile.writeFromSync(buffer, -1, 1);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -859,7 +901,7 @@
exceptionCaught = false;
try {
List<int> buffer = new List<int>(10);
- openedFile.writeListSync(buffer, 0, -1);
+ openedFile.writeFromSync(buffer, 0, -1);
} on RangeError catch (ex) {
exceptionCaught = true;
} on Exception catch (ex) {
@@ -1218,6 +1260,7 @@
createTempDirectory(() {
testReadWrite();
testReadWriteSync();
+ testReadWriteNoArgsSync();
testReadWriteStream();
testReadEmptyFileSync();
testReadEmptyFile();
diff --git a/tests/standalone/io/file_typed_data_test.dart b/tests/standalone/io/file_typed_data_test.dart
index 027c191..2c00cef 100644
--- a/tests/standalone/io/file_typed_data_test.dart
+++ b/tests/standalone/io/file_typed_data_test.dart
@@ -10,18 +10,18 @@
import 'dart:isolate';
import 'dart:typeddata';
-void testWriteUint8ListAndView() {
+void testWriteInt8ListAndView() {
ReceivePort port = new ReceivePort();
- Uint8List list = new Uint8List(8);
+ Int8List list = new Int8List(8);
for (int i = 0; i < 8; i++) list[i] = i;
- var view = new Uint8List.view(list.buffer, 2, 4);
+ var view = new Int8List.view(list.buffer, 2, 4);
new Directory('').createTemp().then((temp) {
var file = new File("${temp.path}/test");
file.open(mode: FileMode.WRITE).then((raf) {
- return raf.writeList(list, 0, 8);
+ return raf.writeFrom(list, 0, 8);
}).then((raf) {
- return raf.writeList(view, 0, 4);
+ return raf.writeFrom(view, 0, 4);
}).then((raf) {
return raf.close();
}).then((_) {
@@ -37,6 +37,254 @@
}
+void testWriteUint8ListAndView() {
+ ReceivePort port = new ReceivePort();
+ Uint8List list = new Uint8List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Uint8List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ Expect.listEquals(expected, content);
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteUint8ClampedListAndView() {
+ ReceivePort port = new ReceivePort();
+ Uint8ClampedList list = new Uint8ClampedList(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Uint8ClampedList.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ Expect.listEquals(expected, content);
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteInt16ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Int16List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Int16List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Int16List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteUint16ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Uint16List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Uint16List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Uint16List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteInt32ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Int32List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Int32List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Int32List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteUint32ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Uint32List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Uint32List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Uint32List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteInt64ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Int64List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Int64List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ // return raf.writeList(view, 0, 4);
+ //}).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ //expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Int64List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
+void testWriteUint64ListAndView() {
+ ReceivePort port = new ReceivePort();
+ var list = new Uint64List(8);
+ for (int i = 0; i < 8; i++) list[i] = i;
+ var view = new Uint64List.view(list.buffer, 2, 4);
+
+ new Directory('').createTemp().then((temp) {
+ var file = new File("${temp.path}/test");
+ file.open(mode: FileMode.WRITE).then((raf) {
+ return raf.writeFrom(list, 0, 8);
+ }).then((raf) {
+ return raf.writeFrom(view, 0, 4);
+ }).then((raf) {
+ return raf.close();
+ }).then((_) {
+ var expected = [];
+ expected.addAll(list);
+ expected.addAll(view);
+ var content = file.readAsBytesSync();
+ var typed_data_content = new Uint8List(content.length);
+ for (int i = 0; i < content.length; i++) {
+ typed_data_content[i] = content[i];
+ }
+ Expect.listEquals(expected, new Uint64List.view(typed_data_content));
+ temp.deleteSync(recursive: true);
+ port.close();
+ });
+ });
+}
+
+
main() {
+ testWriteInt8ListAndView();
testWriteUint8ListAndView();
+ testWriteUint8ClampedListAndView();
+ testWriteInt16ListAndView();
+ testWriteUint16ListAndView();
+ testWriteInt32ListAndView();
+ testWriteUint32ListAndView();
+ testWriteInt64ListAndView();
+ testWriteUint64ListAndView();
}
diff --git a/tests/standalone/io/http_10_test.dart b/tests/standalone/io/http_10_test.dart
index 0c79981..9250a36 100644
--- a/tests/standalone/io/http_10_test.dart
+++ b/tests/standalone/io/http_10_test.dart
@@ -8,6 +8,7 @@
// VMOptions=--short_socket_read --short_socket_write
import "package:expect/expect.dart";
+import "dart:async";
import "dart:isolate";
import "dart:io";
@@ -25,14 +26,19 @@
Expect.equals("1.0", request.protocolVersion);
response.done
.then((_) => Expect.fail("Unexpected response completion"))
- .catchError((e) => Expect.isTrue(e.error is HttpException));
+ .catchError((error) => Expect.isTrue(error is HttpException));
response.write("Z");
response.write("Z");
response.close();
Expect.throws(() => response.write("x"),
(e) => e is StateError);
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
int count = 0;
makeRequest() {
@@ -77,7 +83,12 @@
response.close();
});
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
int count = 0;
makeRequest() {
@@ -124,7 +135,12 @@
response.write("Z");
response.close();
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
Socket.connect("127.0.0.1", server.port).then((socket) {
void sendRequest() {
@@ -174,7 +190,12 @@
response.write("Z");
response.close();
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
int count = 0;
makeRequest() {
diff --git a/tests/standalone/io/http_auth_test.dart b/tests/standalone/io/http_auth_test.dart
index bd5e2c0..ef400f4 100644
--- a/tests/standalone/io/http_auth_test.dart
+++ b/tests/standalone/io/http_auth_test.dart
@@ -220,7 +220,7 @@
Uri.parse("http://127.0.0.1/basic"),
"test",
new HttpClientBasicCredentials("test", "test"));
- return new Future.immediate(true);
+ return new Future.value(true);
};
HttpClientConnection conn =
@@ -243,7 +243,7 @@
Uri.parse("http://127.0.0.1/digest"),
"test",
new HttpClientDigestCredentials("test", "test"));
- return new Future.immediate(true);
+ return new Future.value(true);
};
HttpClientConnection conn =
diff --git a/tests/standalone/io/http_body_test.dart b/tests/standalone/io/http_body_test.dart
index c25406e..ae0d128 100644
--- a/tests/standalone/io/http_body_test.dart
+++ b/tests/standalone/io/http_body_test.dart
@@ -98,13 +98,20 @@
Expect.equals(type, body.type);
switch (type) {
case "text":
+ Expect.equals(body.mimeType, "text/plain");
Expect.equals(expectedBody, body.body);
break;
case "json":
+ Expect.equals(body.mimeType, "application/json");
Expect.mapEquals(expectedBody, body.body);
break;
+ case "binary":
+ Expect.equals(body.mimeType, null);
+ Expect.listEquals(expectedBody, body.body);
+ break;
+
default:
Expect.fail("bad body type");
}
@@ -116,8 +123,10 @@
var client = new HttpClient();
client.post("127.0.0.1", server.port, "/")
.then((request) {
- request.headers.contentType =
- new ContentType.fromString(mimeType);
+ if (mimeType != null) {
+ request.headers.contentType =
+ new ContentType.fromString(mimeType);
+ }
request.add(content);
return request.close();
})
@@ -152,6 +161,8 @@
null,
"json",
true);
+
+ test(null, "body".codeUnits, "body".codeUnits, "binary");
}
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index c42b8d3..4efd9af 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import "dart:async";
import "dart:isolate";
import "dart:io";
@@ -19,8 +20,8 @@
.then((_) {
Expect.fail("Unexpected successful response completion");
})
- .catchError((e) {
- Expect.isTrue(e.error is HttpException);
+ .catchError((error) {
+ Expect.isTrue(error is HttpException);
});
// write with content length 0 closes the connection and
// reports an error.
@@ -35,7 +36,10 @@
(e) => e is StateError);
},
onError: (e) {
- Expect.fail("Unexpected server error $e");
+ String msg = "Unexpected server error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
int count = 0;
@@ -61,8 +65,11 @@
});
})
.catchError((e) {
- Expect.fail("Unexpected error $e");
- });
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
}
});
}
@@ -92,8 +99,8 @@
.then((_) {
Expect.fail("Unexpected successful response completion");
})
- .catchError((e) {
- Expect.isTrue(e.error is HttpException, "[$e]");
+ .catchError((error) {
+ Expect.isTrue(error is HttpException, "[$error]");
if (++serverCount == totalConnections) {
server.close();
}
@@ -103,7 +110,12 @@
(e) => e is StateError);
});
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
int clientCount = 0;
HttpClient client = new HttpClient();
@@ -168,7 +180,12 @@
(e) => e is StateError);
});
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
int count = 0;
HttpClient client = new HttpClient();
@@ -201,7 +218,12 @@
}
});
})
- .catchError((e) => Expect.fail("Unexpected error $e"));
+ .catchError((e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
}
});
}
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 3f2d0cf..e3dc5ba 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -4,8 +4,10 @@
import "package:expect/expect.dart";
import "dart:async";
+import 'dart:crypto';
import "dart:io";
import "dart:uri";
+import 'dart:utf';
class Server {
HttpServer server;
@@ -48,8 +50,10 @@
},
onDone: () {
String path = request.uri.path.substring(1);
- String content = "$path$path$path";
- Expect.equals(content, body.toString());
+ if (path != "A") {
+ String content = "$path$path$path";
+ Expect.equals(content, body.toString());
+ }
response.write(request.uri.path);
response.close();
});
@@ -76,9 +80,21 @@
HttpServer server;
HttpClient client;
int requestCount = 0;
+ String username;
+ String password;
ProxyServer() : client = new HttpClient();
+ authenticationRequired(request) {
+ request.fold(null, (x, y) {}).then((_) {
+ var response = request.response;
+ response.headers.set(HttpHeaders.PROXY_AUTHENTICATE,
+ "Basic, realm=realm");
+ response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED;
+ response.close();
+ });
+ }
+
Future<ProxyServer> start() {
var x = new Completer();
HttpServer.bind().then((s) {
@@ -86,6 +102,25 @@
x.complete(this);
server.listen((HttpRequest request) {
requestCount++;
+ if (username != null && password != null) {
+ if (request.headers[HttpHeaders.PROXY_AUTHORIZATION] == null) {
+ authenticationRequired(request);
+ return;
+ } else {
+ Expect.equals(
+ 1, request.headers[HttpHeaders.PROXY_AUTHORIZATION].length);
+ String authorization =
+ request.headers[HttpHeaders.PROXY_AUTHORIZATION][0];
+ List<String> tokens = authorization.split(" ");
+ Expect.equals("Basic", tokens[0]);
+ String auth =
+ CryptoUtils.bytesToBase64(encodeUtf8("$username:$password"));
+ if (auth != tokens[1]) {
+ authenticationRequired(request);
+ return;
+ }
+ }
+ }
// Open the connection from the proxy.
client.openUrl(request.method, request.uri)
.then((HttpClientRequest clientRequest) {
@@ -362,10 +397,151 @@
});
}
+
+int testProxyAuthenticateCount = 0;
+void testProxyAuthenticate() {
+ setupProxyServer().then((proxyServer) {
+ proxyServer.username = "test";
+ proxyServer.password = "test";
+ setupServer(1).then((server) {
+ setupServer(1, secure: true).then((secureServer) {
+ HttpClient client = new HttpClient();
+
+ Completer step1 = new Completer();
+ Completer step2 = new Completer();
+
+ // Test with no authentication.
+ client.findProxy = (Uri uri) {
+ return "PROXY localhost:${proxyServer.port}";
+ };
+
+ const int loopCount = 2;
+ for (int i = 0; i < loopCount; i++) {
+ test(bool secure) {
+ String url = secure
+ ? "https://localhost:${secureServer.port}/$i"
+ : "http://127.0.0.1:${server.port}/$i";
+
+ client.postUrl(Uri.parse(url))
+ .then((HttpClientRequest clientRequest) {
+ String content = "$i$i$i";
+ clientRequest.write(content);
+ return clientRequest.close();
+ })
+ .then((HttpClientResponse response) {
+ response.listen((_) {}, onDone: () {
+ testProxyAuthenticateCount++;
+ Expect.equals(HttpStatus.PROXY_AUTHENTICATION_REQUIRED,
+ response.statusCode);
+ if (testProxyAuthenticateCount == loopCount * 2) {
+ Expect.equals(0, server.requestCount);
+ Expect.equals(0, secureServer.requestCount);
+ step1.complete(null);
+ }
+ });
+ });
+ }
+
+ test(false);
+ test(true);
+ }
+
+ step1.future.then((_) {
+ testProxyAuthenticateCount = 0;
+ client.findProxy = (Uri uri) {
+ return "PROXY test:test@localhost:${proxyServer.port}";
+ };
+
+ for (int i = 0; i < loopCount; i++) {
+ test(bool secure) {
+ String url = secure
+ ? "https://localhost:${secureServer.port}/$i"
+ : "http://127.0.0.1:${server.port}/$i";
+
+ client.postUrl(Uri.parse(url))
+ .then((HttpClientRequest clientRequest) {
+ String content = "$i$i$i";
+ clientRequest.write(content);
+ return clientRequest.close();
+ })
+ .then((HttpClientResponse response) {
+ response.listen((_) {}, onDone: () {
+ testProxyAuthenticateCount++;
+ Expect.equals(HttpStatus.OK, response.statusCode);
+ if (testProxyAuthenticateCount == loopCount * 2) {
+ Expect.equals(loopCount, server.requestCount);
+ Expect.equals(loopCount, secureServer.requestCount);
+ step2.complete(null);
+ }
+ });
+ });
+ }
+
+ test(false);
+ test(true);
+ }
+ });
+
+ step2.future.then((_) {
+ testProxyAuthenticateCount = 0;
+ client.findProxy = (Uri uri) {
+ return "PROXY localhost:${proxyServer.port}";
+ };
+
+ client.authenticateProxy = (host, port, scheme, realm) {
+ client.addProxyCredentials(
+ "localhost",
+ proxyServer.port,
+ "realm",
+ new HttpClientBasicCredentials("test", "test"));
+ return new Future.value(true);
+ };
+
+ for (int i = 0; i < loopCount; i++) {
+ test(bool secure) {
+ String url = secure
+ ? "https://localhost:${secureServer.port}/A"
+ : "http://127.0.0.1:${server.port}/A";
+
+ client.postUrl(Uri.parse(url))
+ .then((HttpClientRequest clientRequest) {
+ String content = "$i$i$i";
+ clientRequest.write(content);
+ return clientRequest.close();
+ })
+ .then((HttpClientResponse response) {
+ response.listen((_) {}, onDone: () {
+ testProxyAuthenticateCount++;
+ Expect.equals(HttpStatus.OK, response.statusCode);
+ if (testProxyAuthenticateCount == loopCount * 2) {
+ Expect.equals(loopCount * 2, server.requestCount);
+ Expect.equals(loopCount * 2, secureServer.requestCount);
+ proxyServer.shutdown();
+ server.shutdown();
+ secureServer.shutdown();
+ client.close();
+ }
+ });
+ });
+ }
+ test(false);
+ test(true);
+ }
+ });
+
+ });
+ });
+ });
+}
+
int testRealProxyDoneCount = 0;
void testRealProxy() {
setupServer(1).then((server) {
HttpClient client = new HttpClient();
+ client.addProxyCredentials("localhost",
+ 8080,
+ "test",
+ new HttpClientBasicCredentials("test", "test"));
List<String> proxy =
["PROXY localhost:8080",
@@ -389,8 +565,45 @@
})
.then((HttpClientResponse response) {
response.listen((_) {}, onDone: () {
- testRealProxyDoneCount++;
- if (testRealProxyDoneCount == proxy.length) {
+ if (++testRealProxyDoneCount == proxy.length) {
+ Expect.equals(proxy.length, server.requestCount);
+ server.shutdown();
+ client.close();
+ }
+ });
+ });
+ }
+ });
+}
+
+int testRealProxyAuthDoneCount = 0;
+void testRealProxyAuth() {
+ setupServer(1).then((server) {
+ HttpClient client = new HttpClient();
+
+ List<String> proxy =
+ ["PROXY test:test@localhost:8080",
+ "PROXY test:test@localhost:8080; PROXY hede.hule.hest:8080",
+ "PROXY hede.hule.hest:8080; PROXY test:test@localhost:8080",
+ "PROXY test:test@localhost:8080; DIRECT"];
+
+ client.findProxy = (Uri uri) {
+ // Pick the proxy configuration based on the request path.
+ int index = int.parse(uri.path.substring(1));
+ return proxy[index];
+ };
+
+ for (int i = 0; i < proxy.length; i++) {
+ client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/$i"))
+ .then((HttpClientRequest clientRequest) {
+ String content = "$i$i$i";
+ clientRequest.contentLength = content.length;
+ clientRequest.write(content);
+ return clientRequest.close();
+ })
+ .then((HttpClientResponse response) {
+ response.listen((_) {}, onDone: () {
+ if (++testRealProxyAuthDoneCount == proxy.length) {
Expect.equals(proxy.length, server.requestCount);
server.shutdown();
client.close();
@@ -415,7 +628,9 @@
testProxy();
testProxyChain();
testProxyFromEnviroment();
+ testProxyAuthenticate();
// This test is not normally run. It can be used for locally testing
// with a real proxy server (e.g. Apache).
//testRealProxy();
+ //testRealProxyAuth();
}
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index f146083..adcd6c3 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -329,8 +329,8 @@
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
.then((HttpClientRequest request) => request.close())
- .catchError((e) {
- Expect.equals(5, e.error.redirects.length);
+ .catchError((error) {
+ Expect.equals(5, error.redirects.length);
server.close();
client.close();
}, test: (e) => e is RedirectLimitExceededException);
@@ -344,8 +344,8 @@
int redirectCount = 0;
client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
.then((HttpClientRequest request) => request.close())
- .catchError((e) {
- Expect.equals(2, e.error.redirects.length);
+ .catchError((error) {
+ Expect.equals(2, error.redirects.length);
server.close();
client.close();
}, test: (e) => e is RedirectLoopException);
diff --git a/tests/standalone/io/http_server_early_client_close_test.dart b/tests/standalone/io/http_server_early_client_close_test.dart
index 5a58899..aade9d2 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -39,17 +39,17 @@
calledOnRequest = true;
request.listen(
(_) {},
- onError: (e) {
+ onError: (error) {
Expect.isFalse(calledOnError);
- Expect.equals(exception, e.error.message);
+ Expect.equals(exception, error.message);
calledOnError = true;
port.close();
c.complete(null);
});
},
- onError: (e) {
+ onError: (error) {
Expect.isFalse(calledOnError);
- Expect.equals(exception, e.error.message);
+ Expect.equals(exception, error.message);
Expect.equals(expectRequest, calledOnRequest);
calledOnError = true;
port.close();
diff --git a/tests/standalone/io/http_server_early_server_close_test.dart b/tests/standalone/io/http_server_early_server_close_test.dart
index d5de5d9..2a1c3db 100644
--- a/tests/standalone/io/http_server_early_server_close_test.dart
+++ b/tests/standalone/io/http_server_early_server_close_test.dart
@@ -13,7 +13,10 @@
server.listen((HttpRequest request) {
Timer.run(server.close);
}, onError: (e) {
- Expect.fail("No server errors expected: $e");
+ String msg = "No server errors expected: $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
return server.port;
});
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index 51ad60d..ac019c8 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -33,7 +33,7 @@
client.close();
},
onError: (error) {
- Expect.isTrue(error.error is HttpParserException);
+ Expect.isTrue(error is HttpParserException);
});
})
.catchError((error) {
@@ -50,13 +50,28 @@
server.close();
});
});
+
+ testServerRequest((server, request) {
+ new File("__not_exitsing_file_").openRead().pipe(request.response)
+ .catchError((e) {
+ server.close();
+ });
+ });
+
+ testServerRequest((server, request) {
+ request.response.done.then((_) {
+ server.close();
+ });
+ request.response.contentLength = 0;
+ request.response.close();
+ });
}
void testResponseAddStream() {
int bytes = new File(new Options().script).lengthSync();
testServerRequest((server, request) {
- request.response.writeStream(new File(new Options().script).openRead())
+ request.response.addStream(new File(new Options().script).openRead())
.then((response) {
response.close();
response.done.then((_) => server.close());
@@ -64,9 +79,9 @@
}, bytes: bytes);
testServerRequest((server, request) {
- request.response.writeStream(new File(new Options().script).openRead())
+ request.response.addStream(new File(new Options().script).openRead())
.then((response) {
- request.response.writeStream(new File(new Options().script).openRead())
+ request.response.addStream(new File(new Options().script).openRead())
.then((response) {
response.close();
response.done.then((_) => server.close());
@@ -76,13 +91,27 @@
testServerRequest((server, request) {
var controller = new StreamController();
- request.response.writeStream(controller.stream)
+ request.response.addStream(controller.stream)
.then((response) {
response.close();
response.done.then((_) => server.close());
});
controller.close();
}, bytes: 0);
+
+ testServerRequest((server, request) {
+ request.response.addStream(new File("__not_exitsing_file_").openRead())
+ .catchError((e) {
+ server.close();
+ });
+ });
+
+ testServerRequest((server, request) {
+ new File("__not_exitsing_file_").openRead().pipe(request.response)
+ .catchError((e) {
+ server.close();
+ });
+ });
}
void testBadResponseAdd() {
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index 4724467..bd8362e 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import "dart:async";
import "dart:io";
import "dart:isolate";
@@ -29,8 +30,11 @@
onDone();
});
})
- .catchError((error) {
- Expect.fail("Unexpected error in Http Client: $error");
+ .catchError((e) {
+ String msg = "Unexpected error in Http Client: $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
}
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
index 490152e..fbefbeb 100644
--- a/tests/standalone/io/https_server_test.dart
+++ b/tests/standalone/io/https_server_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
+import "dart:async";
import "dart:io";
import "dart:uri";
import "dart:isolate";
@@ -43,8 +44,11 @@
onDone();
});
})
- .catchError((error) {
- Expect.fail("Unexpected error in Https client: $error");
+ .catchError((e) {
+ String msg = "Unexpected error in Https client: $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
});
}
diff --git a/tests/standalone/io/io_sink_test.dart b/tests/standalone/io/io_sink_test.dart
new file mode 100644
index 0000000..1c96448
--- /dev/null
+++ b/tests/standalone/io/io_sink_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+import "dart:isolate";
+
+class TestConsumer implements StreamConsumer {
+ final List expected;
+ final List received = [];
+
+ var closePort;
+
+ int addStreamCount = 0;
+ int expcetedAddStreamCount;
+
+ TestConsumer(this.expected,
+ {close: true,
+ this.expcetedAddStreamCount: -1}) {
+ if (close) closePort = new ReceivePort();
+ }
+
+ Future addStream(Stream stream) {
+ addStreamCount++;
+ return stream.fold(
+ received,
+ (list, value) {
+ list.addAll(value);
+ return list;
+ })
+ .then((_) {});
+ }
+
+ Future close() {
+ return new Future.value()
+ .then((_) {
+ if (closePort != null) closePort.close();
+ Expect.listEquals(expected, received);
+ if (expcetedAddStreamCount >= 0) {
+ Expect.equals(expcetedAddStreamCount, addStreamCount);
+ }
+ });
+ }
+}
+
+void testClose() {
+ var sink = new IOSink(new TestConsumer([], expcetedAddStreamCount: 0));
+ sink.close();
+}
+
+void testAddClose() {
+ var sink = new IOSink(new TestConsumer([0]));
+ sink.add([0]);
+ sink.close();
+
+ sink = new IOSink(new TestConsumer([0, 1, 2]));
+ sink.add([0]);
+ sink.add([1]);
+ sink.add([2]);
+ sink.close();
+}
+
+void testAddStreamClose() {
+ {
+ var sink = new IOSink(new TestConsumer([0]));
+ var controller = new StreamController();
+ sink.addStream(controller.stream)
+ .then((_) {
+ sink.close();
+ });
+ controller.add([0]);
+ controller.close();
+ }
+ {
+ var sink = new IOSink(new TestConsumer([0, 1, 2]));
+ var controller = new StreamController();
+ sink.addStream(controller.stream)
+ .then((_) {
+ sink.close();
+ });
+ controller.add([0]);
+ controller.add([1]);
+ controller.add([2]);
+ controller.close();
+ }
+}
+
+void testAddStreamAddClose() {
+ {
+ var sink = new IOSink(new TestConsumer([0, 1]));
+ var controller = new StreamController();
+ sink.addStream(controller.stream)
+ .then((_) {
+ sink.add([1]);
+ sink.close();
+ });
+ controller.add([0]);
+ controller.close();
+ }
+}
+
+void main() {
+ testClose();
+ testAddClose();
+ testAddStreamClose();
+ testAddStreamAddClose();
+}
diff --git a/tests/standalone/io/process_start_exception_test.dart b/tests/standalone/io/process_start_exception_test.dart
index f7a0a66..a1f891e 100644
--- a/tests/standalone/io/process_start_exception_test.dart
+++ b/tests/standalone/io/process_start_exception_test.dart
@@ -13,9 +13,9 @@
Process.start("__path_to_something_that_should_not_exist__",
const []);
processFuture.then((p) => Expect.fail('got process despite start error'))
- .catchError((e) {
- Expect.isTrue(e.error is ProcessException);
- Expect.equals(2, e.error.errorCode, e.error.toString());
+ .catchError((error) {
+ Expect.isTrue(error is ProcessException);
+ Expect.equals(2, error.errorCode, error.toString());
});
}
@@ -25,9 +25,9 @@
const []);
processFuture.then((result) => Expect.fail("exit handler called"))
- .catchError((e) {
- Expect.isTrue(e.error is ProcessException);
- Expect.equals(2, e.error.errorCode, e.error.toString());
+ .catchError((error) {
+ Expect.isTrue(error is ProcessException);
+ Expect.equals(2, error.errorCode, error.toString());
});
}
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index 3b3079c..cc8a86e 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -42,16 +42,16 @@
// Bind to a unknown DNS name.
RawSecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
Expect.fail("Failure expected");
- }).catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
// Bind to an unavaliable IP-address.
RawSecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
Expect.fail("Failure expected");
- }).catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
@@ -70,9 +70,9 @@
t.close();
port.toSendPort().send(1);
})
- .catchError((e) {
+ .catchError((error) {
Expect.notEquals('windows', Platform.operatingSystem);
- Expect.isTrue(e.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
s.close();
port.toSendPort().send(1);
});
@@ -101,16 +101,14 @@
.then((clientEnd) {
Expect.fail("No client connection expected.");
})
- .catchError((e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
});
server.listen((serverEnd) {
Expect.fail("No server connection expected.");
},
- onError: (e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is SocketIOException);
+ onError: (error) {
+ Expect.isTrue(error is SocketIOException);
clientEndFuture.then((_) => port.close());
});
});
@@ -173,7 +171,7 @@
Expect.isTrue(client.available() > 0);
var buffer = client.read();
if (buffer != null) {
- data.setRange(bytesRead, buffer.length, buffer);
+ data.setRange(bytesRead, bytesRead + buffer.length, buffer);
bytesRead += buffer.length;
for (var value in buffer) {
Expect.isTrue(value is int);
@@ -220,7 +218,8 @@
Expect.isTrue(socket.available() > 0);
var buffer = socket.read();
if (buffer != null) {
- dataReceived.setRange(bytesRead, buffer.length, buffer);
+ int endIndex = bytesRead + buffer.length;
+ dataReceived.setRange(bytesRead, endIndex, buffer);
bytesRead += buffer.length;
}
break;
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index d703112..cfd93cb 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -100,8 +100,11 @@
default: throw "Unexpected event $event";
}
},
- onError: (AsyncError a) {
- Expect.fail("onError handler of RawSecureSocket stream hit: $a");
+ onError: (e) {
+ String msg = "onError handler of RawSecureSocket stream hit: $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
});
});
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index 02254b4..33b092f 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -71,8 +71,11 @@
default: throw "Unexpected event $event";
}
},
- onError: (AsyncError a) {
- Expect.fail("onError handler of RawSecureSocket stream hit: $a");
+ onError: (e) {
+ String msg = "onError handler of RawSecureSocket stream hit $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
});
});
});
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index b619668..23fc6a5 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -34,16 +34,16 @@
// Bind to a unknown DNS name.
RawServerSocket.bind("ko.faar.__hest__")
.then((_) { Expect.fail("Failure expected"); } )
- .catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
// Bind to an unavaliable IP-address.
RawServerSocket.bind("8.8.8.8")
.then((_) { Expect.fail("Failure expected"); } )
- .catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
@@ -59,9 +59,9 @@
Expect.equals(s.port, t.port);
port.toSendPort().send(1);
})
- .catchError((e) {
+ .catchError((error) {
Expect.notEquals('windows', Platform.operatingSystem);
- Expect.isTrue(e.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
});
@@ -166,7 +166,7 @@
Expect.isTrue(bytesWritten == 0);
Expect.isTrue(client.available() > 0);
var buffer = client.read();
- data.setRange(bytesRead, buffer.length, buffer);
+ data.setRange(bytesRead, bytesRead + buffer.length, buffer);
bytesRead += buffer.length;
if (bytesRead == data.length) {
verifyTestData(data);
@@ -202,7 +202,7 @@
case RawSocketEvent.READ:
Expect.isTrue(socket.available() > 0);
var buffer = socket.read();
- data.setRange(bytesRead, buffer.length, buffer);
+ data.setRange(bytesRead, bytesRead + buffer.length, buffer);
bytesRead += buffer.length;
break;
case RawSocketEvent.WRITE:
diff --git a/tests/standalone/io/read_into_const_list_test.dart b/tests/standalone/io/read_into_const_list_test.dart
index e1ed587..5bc1c6b 100644
--- a/tests/standalone/io/read_into_const_list_test.dart
+++ b/tests/standalone/io/read_into_const_list_test.dart
@@ -20,7 +20,7 @@
File file = new File(filename);
file.open().then((input) {
try {
- input.readListSync(a, 0, 1);
+ input.readIntoSync(a, 0, 1);
Expect.fail("no exception thrown");
} catch (e) {
Expect.isTrue(e is UnsupportedError);
diff --git a/tests/standalone/io/secure_no_builtin_roots_database_test.dart b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
index 078ba70..8c647d0 100644
--- a/tests/standalone/io/secure_no_builtin_roots_database_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
@@ -15,8 +15,7 @@
.then((request) => request.close())
.then((response) => Expect.fail("Unexpected successful connection"))
.catchError((error) {
- Expect.isTrue(error is AsyncError);
- Expect.isTrue(error.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
keepAlive.close();
client.close();
});
diff --git a/tests/standalone/io/secure_no_builtin_roots_test.dart b/tests/standalone/io/secure_no_builtin_roots_test.dart
index a93404c..c411e62 100644
--- a/tests/standalone/io/secure_no_builtin_roots_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_test.dart
@@ -15,8 +15,7 @@
.then((request) => request.close())
.then((response) => Expect.fail("Unexpected successful connection"))
.catchError((error) {
- Expect.isTrue(error is AsyncError);
- Expect.isTrue(error.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
keepAlive.close();
client.close();
});
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index da71e0d..dbe0355 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -42,16 +42,16 @@
// Bind to a unknown DNS name.
SecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
Expect.fail("Failure expected");
- }).catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
// Bind to an unavaliable IP-address.
SecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
Expect.fail("Failure expected");
- }).catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ }).catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
@@ -69,9 +69,9 @@
s.close();
t.close();
port.toSendPort().send(1);
- }).catchError((e) {
+ }).catchError((error) {
Expect.notEquals('windows', Platform.operatingSystem);
- Expect.isTrue(e.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
s.close();
port.toSendPort().send(1);
});
@@ -100,16 +100,14 @@
.then((clientEnd) {
Expect.fail("No client connection expected.");
})
- .catchError((e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
});
server.listen((serverEnd) {
Expect.fail("No server connection expected.");
},
- onError: (e) {
- Expect.isTrue(e is AsyncError);
- Expect.isTrue(e.error is SocketIOException);
+ onError: (error) {
+ Expect.isTrue(error is SocketIOException);
clientEndFuture.then((_) => port.close());
});
});
@@ -167,7 +165,7 @@
client.listen(
(buffer) {
Expect.isTrue(bytesWritten == 0);
- data.setRange(bytesRead, buffer.length, buffer);
+ data.setRange(bytesRead, bytesRead + buffer.length, buffer);
bytesRead += buffer.length;
if (bytesRead == data.length) {
verifyTestData(data);
@@ -189,7 +187,7 @@
socket.close(); // Can also be delayed.
socket.listen(
(List<int> buffer) {
- dataReceived.setRange(bytesRead, buffer.length, buffer);
+ dataReceived.setRange(bytesRead, bytesRead + buffer.length, buffer);
bytesRead += buffer.length;
},
onDone: () {
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index 09a5852..61e5af8 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -56,7 +56,12 @@
Expect.equals(9, body[body.length - 1]);
server.close();
},
- onError: (e) => Expect.fail("Unexpected error $e"));
+ onError: (e) {
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ });
});
});
}
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index c82f3fb..81c1b14 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -164,7 +164,7 @@
client.listen(
(data) => Expect.fail("Unexpected data"),
onError: (error) {
- Expect.isTrue(error.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
errors++;
},
onDone: () {
@@ -184,7 +184,7 @@
Expect.fail("Expected error");
},
onError: (error) {
- Expect.isTrue(error.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
port.close();
});
});
diff --git a/tests/standalone/io/socket_many_connections_test.dart b/tests/standalone/io/socket_many_connections_test.dart
index b10ad71..c6c557e 100644
--- a/tests/standalone/io/socket_many_connections_test.dart
+++ b/tests/standalone/io/socket_many_connections_test.dart
@@ -80,7 +80,10 @@
}
void errorHandler(e) {
- print("Socket error $e");
+ String msg = "Socket error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ print(msg);
connection.close();
}
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index a405c05..1385b67 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -34,16 +34,16 @@
// Bind to a unknown DNS name.
ServerSocket.bind("ko.faar.__hest__")
.then((_) { Expect.fail("Failure expected"); } )
- .catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
// Bind to an unavaliable IP-address.
ServerSocket.bind("8.8.8.8")
.then((_) { Expect.fail("Failure expected"); } )
- .catchError((e) {
- Expect.isTrue(e.error is SocketIOException);
+ .catchError((error) {
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
@@ -59,9 +59,9 @@
Expect.equals(s.port, t.port);
port.toSendPort().send(1);
})
- .catchError((e) {
+ .catchError((error) {
Expect.notEquals('windows', Platform.operatingSystem);
- Expect.isTrue(e.error is SocketIOException);
+ Expect.isTrue(error is SocketIOException);
port.toSendPort().send(1);
});
});
diff --git a/tests/standalone/io/stdout_stderr_test.dart b/tests/standalone/io/stdout_stderr_test.dart
index 4775891..ccd1550 100644
--- a/tests/standalone/io/stdout_stderr_test.dart
+++ b/tests/standalone/io/stdout_stderr_test.dart
@@ -17,16 +17,18 @@
sink.add([101, 108, 108, 111, 10]);
var controller = new StreamController();
- sink.writeStream(controller.stream);
+ var future = sink.addStream(controller.stream);
controller.add([72, 101, 108]);
controller.add([108, 111, 10]);
controller.close();
- controller = new StreamController();
- controller.stream.pipe(sink);
- controller.add([72, 101, 108]);
- controller.add([108, 111, 10]);
- controller.close();
+ future.then((_) {
+ controller = new StreamController();
+ controller.stream.pipe(sink);
+ controller.add([72, 101, 108]);
+ controller.add([108, 111, 10]);
+ controller.close();
+ });
}
main() {
diff --git a/tests/standalone/io/stream_pipe_test.dart b/tests/standalone/io/stream_pipe_test.dart
index c029e0b..75f7981 100644
--- a/tests/standalone/io/stream_pipe_test.dart
+++ b/tests/standalone/io/stream_pipe_test.dart
@@ -39,9 +39,9 @@
var data2 = new List<int>(count);
if (file1Offset != 0) file1.setPositionSync(file1Offset);
if (file2Offset != 0) file2.setPositionSync(file2Offset);
- var read1 = file1.readListSync(data1, 0, count);
+ var read1 = file1.readIntoSync(data1, 0, count);
Expect.equals(count, read1);
- var read2 = file2.readListSync(data2, 0, count);
+ var read2 = file2.readIntoSync(data2, 0, count);
Expect.equals(count, read2);
for (var i = 0; i < count; i++) {
if (data1[i] != data2[i]) {
@@ -100,7 +100,7 @@
var dstFile = new File(dstFileName);
dstFile.createSync();
var output = dstFile.openWrite();
- output.writeStream(srcStream).then((_) {
+ output.addStream(srcStream).then((_) {
output.add([32]);
output.close();
output.done.then((_) {
@@ -114,7 +114,7 @@
count: srcLength));
dst.setPositionSync(srcLength);
var data = new List<int>(1);
- var read2 = dst.readListSync(data, 0, 1);
+ var read2 = dst.readIntoSync(data, 0, 1);
Expect.equals(32, data[0]);
src.closeSync();
dst.closeSync();
@@ -143,9 +143,9 @@
var dstFile = new File(dstFileName);
dstFile.createSync();
var output = dstFile.openWrite();
- output.writeStream(srcStream).then((_) {
+ output.addStream(srcStream).then((_) {
var srcStream2 = srcFile.openRead();
- output.writeStream(srcStream2).then((_) {
+ output.addStream(srcStream2).then((_) {
output.close();
output.done.then((_) {
var src = srcFile.openSync();
diff --git a/tests/standalone/io/string_transformer_test.dart b/tests/standalone/io/string_transformer_test.dart
index a15633d..a7dd544 100644
--- a/tests/standalone/io/string_transformer_test.dart
+++ b/tests/standalone/io/string_transformer_test.dart
@@ -197,9 +197,9 @@
onDone: () {
Expect.equals(1, errors);
},
- onError: (e) {
+ onError: (error) {
errors++;
- Expect.isTrue(e.error is TestException);
+ Expect.isTrue(error is TestException);
});
controller.addError(new TestException());
controller.close();
@@ -222,7 +222,7 @@
Expect.fail("data not expected");
},
onError: (error) {
- Expect.isTrue(error.error is FormatException);
+ Expect.isTrue(error is FormatException);
});
}
diff --git a/tests/standalone/io/testing_server.dart b/tests/standalone/io/testing_server.dart
index 79ab136..79f0175 100644
--- a/tests/standalone/io/testing_server.dart
+++ b/tests/standalone/io/testing_server.dart
@@ -13,7 +13,10 @@
void onConnection(Socket connection); // Abstract.
void errorHandlerServer(e) {
- Expect.fail("Server socket error $e");
+ String msg = "Server socket error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
}
void dispatch(message, SendPort replyTo) {
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index 54a7c12..eb15db0 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -51,7 +51,10 @@
}
void onError(e) {
- Expect.fail("Unexpected error $e");
+ String msg = "Unexpected error $e";
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
}
}
@@ -90,7 +93,7 @@
frame[frameIndex++] = count >> ((7 - i) * 8) & 0xFF;
}
}
- frame.setRange(frameIndex, count, data, offset);
+ frame.setRange(frameIndex, frameIndex + count, data, offset);
return frame;
}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f17fa0f..b67e5bf 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -4,6 +4,10 @@
package/invalid_uri_test: Fail, OK # Fails intentionally
+[ $runtime == vm ]
+io/test_runner_test: Fail # Fails because checked-in dart executable is not up to date.
+io/skipping_dart2js_compilations_test: Fail # Fails because checked-in dart executable is not up to date.
+
[ $runtime == vm && ( $system == windows ) ]
io/raw_socket_test: Pass, Fail # Issue 8901
io/http_shutdown_test: Pass, Fail # Issue 9101
diff --git a/tests/standalone/typed_data_test.dart b/tests/standalone/typed_data_test.dart
index 62c4425..11e3366 100644
--- a/tests/standalone/typed_data_test.dart
+++ b/tests/standalone/typed_data_test.dart
@@ -161,7 +161,7 @@
Expect.equals(20 + i, list[i]);
}
- typed_data.setRange(1, 2, const [8, 9]);
+ typed_data.setRange(1, 3, const [8, 9]);
Expect.equals(20, typed_data[0]);
Expect.equals(8, typed_data[1]);
Expect.equals(9, typed_data[2]);
@@ -182,7 +182,7 @@
});
Expect.throws(() {
- typed_data.setRange(3, 1, list);
+ typed_data.setRange(3, 4, list);
});
}
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index c4d6603..87f1b4e 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -61,7 +61,9 @@
class JSNumber {}
class JSNull {}
class JSBool {}
- var getInterceptor;""";
+ getInterceptor(o){}
+ getDispatchProperty(o) {}
+ setDispatchProperty(o, v) {}""";
} else if (uri.path.endsWith('js_helper.dart')) {
source = 'library jshelper; class JSInvocationMirror {} '
'class ConstantMap {} class TypeImpl {}';
@@ -95,7 +97,7 @@
if (code == null) {
throw 'Compilation failed';
}
- }, onError: (AsyncError e) {
+ }, onError: (e) {
throw 'Compilation failed';
});
}
diff --git a/tests/utils/recursive_import_test.dart b/tests/utils/recursive_import_test.dart
index 2c707e7..b6e95f3 100644
--- a/tests/utils/recursive_import_test.dart
+++ b/tests/utils/recursive_import_test.dart
@@ -114,7 +114,7 @@
// first time.
Expect.equals(2 * (count - 1), warningCount);
Expect.equals(1, errorCount);
- }, onError: (AsyncError e) {
+ }, onError: (e) {
throw 'Compilation failed';
});
}
diff --git a/tools/VERSION b/tools/VERSION
index 971672e..08711a3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 4
-BUILD 6
-PATCH 1
+BUILD 7
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 3de5b93..44163fe 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -223,7 +223,9 @@
# TODO(kasperl): Consider running peg and css tests too.
extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
extras_flags = flags
- if system == 'linux' and runtime == 'd8':
+ if (system == 'linux'
+ and runtime == 'd8'
+ and not '--host-checked' in extras_flags):
# Run the extra tests in checked mode, but only on linux/d8.
# Other systems have less resources and tend to time out.
extras_flags = extras_flags + ['--host-checked']
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 942b57c..be09394 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -50,11 +50,14 @@
# ....util/
# ......analyzer/
# ........dart_analyzer.jar
+# ......dartanalyzer/
+# ........dartanalyzer.jar
# ........(third-party libraries for dart_analyzer)
# ......pub/
# ......(more will come here)
+import glob
import optparse
import os
import re
@@ -113,7 +116,7 @@
def CopyDartScripts(home, sdk_root):
# TODO(dgrove) - add pub once issue 6619 is fixed
- for executable in ['dart2js', 'dartdoc']:
+ for executable in ['dart2js', 'dartanalyzer', 'dartdoc']:
CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
os.path.join(sdk_root, 'bin'))
@@ -262,6 +265,16 @@
src_file = join(ANALYZER_HOME, 'util', 'analyzer', jarToCopy)
copyfile(src_file, dest_file)
+ # Create and copy dartanalyzer into 'util'
+ DARTANALYZER_SRC = join(HOME, build_dir, 'dartanalyzer')
+ DARTANALYZER_DEST = join(UTIL, 'dartanalyzer')
+ os.makedirs(DARTANALYZER_DEST)
+
+ jarFiles = glob.glob(join(DARTANALYZER_SRC, '*.jar'))
+
+ for jarFile in jarFiles:
+ copyfile(jarFile, join(DARTANALYZER_DEST, os.path.basename(jarFile)))
+
# Create and populate util/pub.
copytree(join(HOME, 'utils', 'pub'), join(UTIL, 'pub'),
ignore=ignore_patterns('.svn', 'sdk'))
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index e79e294..4174700 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -575,6 +575,7 @@
},
onError: (err) {
print("Error in debug connection: $err");
+ // TODO(floitsch): do we want to print the stack trace?
quitShell();
});
stdinSubscription = stdin.transform(new StringDecoder())
diff --git a/tools/dom/docs/lib/docs.dart b/tools/dom/docs/lib/docs.dart
index 1b38913..8856b73 100644
--- a/tools/dom/docs/lib/docs.dart
+++ b/tools/dom/docs/lib/docs.dart
@@ -64,7 +64,7 @@
}
Future<bool> _exportJsonToFile(Map convertedJson, Path jsonPath) {
- return new Future.of(() {
+ return new Future.sync(() {
final jsonFile = new File.fromPath(jsonPath);
var writeJson = prettySerialize(convertedJson);
@@ -106,7 +106,8 @@
// Remove interface name from Dom Name.
if (memberDomName.indexOf('.') >= 0) {
- memberDomName = memberDomName.slice(memberDomName.indexOf('.') + 1);
+ memberDomName =
+ memberDomName.substring(memberDomName.indexOf('.') + 1);
}
if (!memberComment.isEmpty) {
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index 6af0d7d..914b7ca 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -132,7 +132,7 @@
_logger.info('Flush...')
emitters.Flush()
- monitored.FinishMonitoring()
+ monitored.FinishMonitoring(dart2js_output_dir)
def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
library_dir = os.path.dirname(library_path)
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 60565a1..f61f33d 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -83,6 +83,7 @@
self._database = database
self._imported_interfaces = []
self._impl_stmts = []
+ self.conditionals_met = set()
def _resolve_type_defs(self, idl_file):
type_def_map = {}
@@ -473,11 +474,15 @@
conditional = node.ext_attrs['Conditional']
if conditional.find('&') != -1:
for condition in conditional.split('&'):
+ condition = condition.strip()
+ self.conditionals_met.add(condition)
if not enabled(condition):
return False
return True
for condition in conditional.split('|'):
+ condition = condition.strip()
+ self.conditionals_met.add(condition)
if enabled(condition):
return True
return False
diff --git a/tools/dom/scripts/fremontcutbuilder.py b/tools/dom/scripts/fremontcutbuilder.py
index bb82b26..6ccfefb 100755
--- a/tools/dom/scripts/fremontcutbuilder.py
+++ b/tools/dom/scripts/fremontcutbuilder.py
@@ -10,86 +10,79 @@
import os.path
import sys
-# TODO(antonm): most probably should go away or be autogenerated on IDLs roll.
-DEFAULT_FEATURE_DEFINES = [
- # Enabled Chrome WebKit build.
- 'ENABLE_3D_PLUGIN',
- 'ENABLE_3D_RENDERING',
- 'ENABLE_ACCELERATED_2D_CANVAS',
+FEATURE_DISABLED = [
'ENABLE_BATTERY_STATUS',
+ 'ENABLE_CSS3_CONDITIONAL_RULES',
+ 'ENABLE_CSS_DEVICE_ADAPTATION',
+ 'ENABLE_CUSTOM_SCHEME_HANDLER',
+ 'ENABLE_ENCRYPTED_MEDIA_V2',
+ 'ENABLE_INSPECTOR', # Internal DevTools API.
+ 'ENABLE_MEDIA_CAPTURE', # Only enabled on Android.
+ 'ENABLE_MICRODATA',
+ 'ENABLE_ORIENTATION_EVENTS', # Only enabled on Android.
+ 'ENABLE_PROXIMITY_EVENTS',
+ 'ENABLE_SPEECH_SYNTHESIS',
+ 'ENABLE_WEBVTT_REGIONS',
+ 'ENABLE_XHR_TIMEOUT',
+]
+
+FEATURE_DEFINES = [
'ENABLE_BLOB',
- 'ENABLE_BLOB_SLICE',
'ENABLE_CALENDAR_PICKER',
- 'ENABLE_CHANNEL_MESSAGING',
+ 'ENABLE_CANVAS_PATH',
+ 'ENABLE_CANVAS_PROXY',
'ENABLE_CSS_FILTERS',
- 'ENABLE_CSS_IMAGE_SET',
+ 'ENABLE_CSS_REGIONS',
'ENABLE_CSS_SHADERS',
- 'ENABLE_DART',
- 'ENABLE_DATA_TRANSFER_ITEMS',
+ 'ENABLE_CUSTOM_ELEMENTS',
'ENABLE_DATALIST_ELEMENT',
- 'ENABLE_DETAILS',
'ENABLE_DETAILS_ELEMENT',
'ENABLE_DEVICE_ORIENTATION',
+ 'ENABLE_DIALOG_ELEMENT',
'ENABLE_DIRECTORY_UPLOAD',
'ENABLE_DOWNLOAD_ATTRIBUTE',
'ENABLE_ENCRYPTED_MEDIA',
'ENABLE_FILE_SYSTEM',
'ENABLE_FILTERS',
- 'ENABLE_FULLSCREEN_API',
+ 'ENABLE_FONT_LOAD_EVENTS',
'ENABLE_GAMEPAD',
'ENABLE_GEOLOCATION',
- 'ENABLE_GESTURE_EVENTS',
- 'ENABLE_INDEXED_DATABASE',
'ENABLE_INPUT_SPEECH',
- 'ENABLE_INPUT_TYPE_COLOR',
- 'ENABLE_INPUT_TYPE_DATE',
'ENABLE_JAVASCRIPT_DEBUGGER',
- 'ENABLE_JAVASCRIPT_I18N_API',
'ENABLE_LEGACY_NOTIFICATIONS',
- 'ENABLE_LINK_PREFETCH',
- 'ENABLE_MEDIA_SOURCE',
'ENABLE_MEDIA_STATISTICS',
'ENABLE_MEDIA_STREAM',
'ENABLE_METER_ELEMENT',
- 'ENABLE_METER_TAG',
- 'ENABLE_MHTML',
+ 'ENABLE_NAVIGATOR_CONTENT_UTILS',
'ENABLE_NOTIFICATIONS',
- 'ENABLE_OVERFLOW_SCROLLING',
'ENABLE_PAGE_POPUP',
- 'ENABLE_PAGE_VISIBILITY_API',
+ 'ENABLE_PERFORMANCE_TIMELINE',
'ENABLE_POINTER_LOCK',
'ENABLE_PROGRESS_ELEMENT',
- 'ENABLE_PROGRESS_TAG',
'ENABLE_QUOTA',
- 'ENABLE_REGISTER_PROTOCOL_HANDLER',
'ENABLE_REQUEST_ANIMATION_FRAME',
- 'ENABLE_RUBY',
- 'ENABLE_SANDBOX',
+ 'ENABLE_REQUEST_AUTOCOMPLETE',
+ 'ENABLE_RESOURCE_TIMING',
'ENABLE_SCRIPTED_SPEECH',
'ENABLE_SHADOW_DOM',
'ENABLE_SHARED_WORKERS',
- 'ENABLE_SMOOTH_SCROLLING',
'ENABLE_SQL_DATABASE',
'ENABLE_STYLE_SCOPED',
'ENABLE_SVG',
'ENABLE_SVG_FONTS',
'ENABLE_TOUCH_EVENTS',
- 'ENABLE_V8_SCRIPT_DEBUG_SERVER',
+ 'ENABLE_USER_TIMING',
'ENABLE_VIDEO',
'ENABLE_VIDEO_TRACK',
- 'ENABLE_VIEWPORT',
- 'ENABLE_WEBGL',
'ENABLE_WEB_AUDIO',
- 'ENABLE_WEB_INTENTS',
+ 'ENABLE_WEBGL',
'ENABLE_WEB_SOCKETS',
'ENABLE_WEB_TIMING',
'ENABLE_WORKERS',
- 'ENABLE_XHR_RESPONSE_BLOB',
'ENABLE_XSLT',
]
-def build_database(idl_files, database_dir, feature_defines=None,
- parallel=False):
+def build_database(idl_files, database_dir, parallel=False):
"""This code reconstructs the FremontCut IDL database from W3C,
WebKit and Dart IDL files."""
current_dir = os.path.dirname(__file__)
@@ -109,13 +102,11 @@
# TODO(vsm): Reconcile what is exposed here and inside WebKit code
# generation. We need to recheck this periodically for now.
webkit_defines = [ 'LANGUAGE_DART', 'LANGUAGE_JAVASCRIPT' ]
- if feature_defines is None:
- feature_defines = DEFAULT_FEATURE_DEFINES
webkit_options = databasebuilder.DatabaseBuilderOptions(
idl_syntax=idlparser.WEBKIT_SYNTAX,
# TODO(vsm): What else should we define as on when processing IDL?
- idl_defines=webkit_defines + feature_defines,
+ idl_defines=webkit_defines + FEATURE_DEFINES,
source='WebKit',
source_attributes={'revision': webkit_revision})
@@ -142,6 +133,20 @@
# Cleanup:
builder.normalize_annotations(['WebKit', 'Dart'])
+ conditionals_met = set(
+ 'ENABLE_' + conditional for conditional in builder.conditionals_met)
+ known_conditionals = set(FEATURE_DEFINES + FEATURE_DISABLED)
+
+ unused_conditionals = known_conditionals - conditionals_met
+ if unused_conditionals:
+ raise Exception('There are some unused conditionals %s' %
+ sorted(unused_conditionals))
+
+ unknown_conditionals = conditionals_met - known_conditionals
+ if unknown_conditionals:
+ raise Exception('There are some unknown conditionals %s' %
+ sorted(unknown_conditionals))
+
db.Save()
return db
@@ -159,8 +164,15 @@
if not os.path.exists(webcore_dir):
raise RuntimeError('directory not found: %s' % webcore_dir)
+ DIRS_TO_IGNORE = [
+ 'bindings', # Various test IDLs
+ 'testing', # IDLs to expose testing APIs
+ 'networkinfo', # Not yet used in Blink yet
+ 'vibration', # Not yet used in Blink yet
+ ]
+
def visitor(arg, dir_name, names):
- if os.path.basename(dir_name) in ['bindings', 'testing']:
+ if os.path.basename(dir_name) in DIRS_TO_IGNORE:
names[:] = [] # Do not go underneath
for name in names:
file_name = os.path.join(dir_name, name)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 1ab6c53..630a034 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -101,7 +101,7 @@
# DOMWindow aliased with global scope.
'Window': '@*DOMWindow',
-})
+}, dart2jsOnly=True)
def IsRegisteredType(type_name):
return type_name in _idl_type_registry
@@ -528,7 +528,7 @@
# Should be either a DOMString, an Array of DOMStrings or null.
'IDBAny get IDBObjectStore.keyPath': None,
-})
+}, dart2jsOnly=True)
def FindConversion(idl_type, direction, interface, member):
table = dart2js_conversions
@@ -696,7 +696,7 @@
'XMLHttpRequest.response': [
"@Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')",
],
-})
+}, dart2jsOnly=True)
_indexed_db_annotations = [
"@SupportedBrowser(SupportedBrowser.CHROME)",
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 7f64f1b..0f06390 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -113,10 +113,6 @@
'*.webkitfullscreenchange': ('fullscreenChange', 'Event'),
'*.webkitfullscreenerror': ('fullscreenError', 'Event'),
'AudioContext.complete': ('complete', 'Event'),
- 'BatteryManager.chargingchange': ('chargingChange', 'Event'),
- 'BatteryManager.chargingtimechange': ('chargingTimeChange', 'Event'),
- 'BatteryManager.dischargingtimechange': ('dischargingTimeChange', 'Event'),
- 'BatteryManager.levelchange': ('levelChange', 'Event'),
'DOMApplicationCache.cached': ('cached', 'Event'),
'DOMApplicationCache.checking': ('checking', 'Event'),
'DOMApplicationCache.downloading': ('downloading', 'Event'),
diff --git a/tools/dom/scripts/monitored.py b/tools/dom/scripts/monitored.py
index 06dc4dd..9d0c8da 100644
--- a/tools/dom/scripts/monitored.py
+++ b/tools/dom/scripts/monitored.py
@@ -8,21 +8,24 @@
_monitored_values = []
-def FinishMonitoring():
+def FinishMonitoring(includeDart2jsOnly):
for value in _monitored_values:
+ if value._dart2jsOnly and not includeDart2jsOnly:
+ continue
value.CheckUsage()
class MonitoredCollection(object):
- def __init__(self, name):
+ def __init__(self, name, dart2jsOnly):
self.name = name
self._used_keys = set()
+ self._dart2jsOnly = dart2jsOnly
_monitored_values.append(self)
class Dict(MonitoredCollection):
"""Wrapper for a dict that reports unused keys."""
- def __init__(self, name, map):
- super(Dict, self).__init__(name)
+ def __init__(self, name, map, dart2jsOnly=False):
+ super(Dict, self).__init__(name, dart2jsOnly)
self._map = map
def __getitem__(self, key):
@@ -52,8 +55,8 @@
class Set(MonitoredCollection):
"""Wrapper for a set that reports unused keys."""
- def __init__(self, name, a_set):
- super(Set, self).__init__(name)
+ def __init__(self, name, a_set, dart2jsOnly=False):
+ super(Set, self).__init__(name, dart2jsOnly)
self._set = a_set
def __contains__(self, key):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 4d813a4..3cb9d4b 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -74,7 +74,7 @@
'Window.open',
'Window.requestAnimationFrame',
# 'WorkerContext.indexedDB', # Workers
- ])
+ ], dart2jsOnly=True)
_js_custom_constructors = monitored.Set('systemhtml._js_custom_constructors', [
'AudioContext',
@@ -84,7 +84,7 @@
'RTCPeerConnection',
'RTCSessionDescription',
'SpeechRecognition',
- ])
+ ], dart2jsOnly=True)
# Classes that offer only static methods, and therefore we should suppress
# constructor creation.
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index f5a9407..788b179 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -19,9 +19,9 @@
bool get isBroadcast => true;
StreamSubscription<T> listen(void onData(T event),
- { void onError(AsyncError error),
- void onDone(),
- bool unsubscribeOnError}) {
+ { void onError(error),
+ void onDone(),
+ bool cancelOnError}) {
return new _EventStreamSubscription<T>(
this._target, this._eventType, onData, this._useCapture);
@@ -63,7 +63,7 @@
}
/// Has no effect.
- void onError(void handleError(AsyncError error)) {}
+ void onError(void handleError(error)) {}
/// Has no effect.
void onDone(void handleDone()) {}
@@ -97,6 +97,12 @@
_target.$dom_removeEventListener(_eventType, _onData, _useCapture);
}
}
+
+ Future asFuture([var futureValue]) {
+ // We just need a future that will never succeed or fail.
+ Completer completer = new Completer();
+ return completer.future;
+ }
}
diff --git a/tools/dom/src/KeyboardEventStream.dart b/tools/dom/src/KeyboardEventStream.dart
index 48dbdba..6f08c70 100644
--- a/tools/dom/src/KeyboardEventStream.dart
+++ b/tools/dom/src/KeyboardEventStream.dart
@@ -28,7 +28,7 @@
static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
/** Controller to produce KeyEvents for the stream. */
- final StreamController _controller = new StreamController.broadcast();
+ final StreamController _controller = new StreamController();
static const _EVENT_TYPE = 'KeyEvent';
diff --git a/tools/dom/src/ModelTreeObserver.dart b/tools/dom/src/ModelTreeObserver.dart
index f055795..8e0bb41a 100644
--- a/tools/dom/src/ModelTreeObserver.dart
+++ b/tools/dom/src/ModelTreeObserver.dart
@@ -79,14 +79,14 @@
// Catch and report them a global exceptions.
try {
if (node._hasLocalModel != true && node._model != model &&
- node._modelChangedStream != null) {
+ node._modelChangedStreams != null &&
+ !node._modelChangedStreams.isEmpty) {
node._model = model;
- node._modelChangedStream.add(node);
+ node._modelChangedStreams.toList()
+ .forEach((controller) => controller.add(node));
}
- } on AsyncError catch (e) {
- e.throwDelayed();
} catch (e, s) {
- new AsyncError(e, s).throwDelayed();
+ new Future.error(e, s);
}
for (var child = node.$dom_firstChild; child != null;
child = child.nextNode) {
diff --git a/tools/dom/src/WrappedList.dart b/tools/dom/src/WrappedList.dart
index c20cfd5..7a4ec30 100644
--- a/tools/dom/src/WrappedList.dart
+++ b/tools/dom/src/WrappedList.dart
@@ -104,6 +104,12 @@
void insert(int index, E element) => _list.insert(index, element);
+ void insertAll(int index, Iterable<E> iterable) =>
+ _list.insertAll(index, iterable);
+
+ void setAll(int index, Iterable<E> iterable) =>
+ _list.setAll(index, iterable);
+
E removeAt(int index) => _list.removeAt(index);
E removeLast() => _list.removeLast();
@@ -112,14 +118,18 @@
Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
- void setRange(int start, int length, List<E> from, [int startFrom]) {
- _list.setRange(start, length, from, startFrom);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ _list.setRange(start, end, iterable, skipCount);
}
- void removeRange(int start, int length) { _list.removeRange(start, length); }
+ void removeRange(int start, int end) { _list.removeRange(start, end); }
- void insertRange(int start, int length, [E fill]) {
- _list.insertRange(start, length, fill);
+ void replaceRange(int start, int end, Iterable<E> iterable) {
+ _list.replaceRange(start, end, iterable);
+ }
+
+ void fillRange(int start, int end, [E fillValue]) {
+ _list.fillRange(start, end, fillValue);
}
Map<int, E> asMap() => _list.asMap();
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 4ab1438..d3055a3 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -11,6 +11,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index eedcc3c..2f001d2 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index a229e0a..9016bcc 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
diff --git a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
index 4d1ccdf..4b24fa5 100644
--- a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
@@ -5,6 +5,7 @@
library dart.dom.web_gl;
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
index 6a599c1..6e50a6e05 100644
--- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -16,6 +16,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName;
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 72e2df7..eb2d73c 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -10,6 +10,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:isolate';
diff --git a/tools/dom/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
index 13f2891..863fc5f 100644
--- a/tools/dom/templates/html/dartium/svg_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
index 5c1f4dd..919ef20 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
index fb6d6b0..18615a1 100644
--- a/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
index bfb9155..b78b476 100644
--- a/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
@@ -16,6 +16,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:_collection-dev';
import 'dart:html';
import 'dart:html_common';
import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 13eaa30..9fd0d99 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -166,8 +166,16 @@
return _childElements.fold(initialValue, combine);
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
+ throw new UnimplementedError();
+ }
+
+ void replaceRange(int start, int end, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void fillRange(int start, int end, [Element fillValue]) {
throw new UnimplementedError();
}
@@ -188,11 +196,7 @@
_childElements.retainWhere(test);
}
- void removeRange(int start, int rangeLength) {
- throw new UnimplementedError();
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnimplementedError();
}
@@ -225,6 +229,14 @@
}
}
+ void insertAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Element> iterable) {
+ throw new UnimplementedError();
+ }
+
void clear() {
// It is unclear if we want to keep non element nodes?
_element.text = '';
@@ -309,16 +321,12 @@
throw new UnsupportedError('');
}
- void setRange(int start, int rangeLength, List from,
- [int startFrom = 0]) {
+ void setRange(int start, int end, Iterable<Element> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError('');
}
- void removeRange(int start, int rangeLength) {
- throw new UnsupportedError('');
- }
-
- void insertRange(int start, int rangeLength, [initialValue = null]) {
+ void removeRange(int start, int end) {
throw new UnsupportedError('');
}
diff --git a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
index 19447c2..c4fec21 100644
--- a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
@@ -54,21 +54,20 @@
int watchId;
var controller;
controller = new StreamController<Geoposition>(
- onSubscriptionStateChange: () {
- if (controller.hasListener) {
- assert(watchId == null);
- watchId = $dom_watchPosition(
- (position) {
- controller.add(_ensurePosition(position));
- },
- (error) {
- controller.addError(error);
- },
- options);
- } else {
- assert(watchId != null);
- $dom_clearWatch(watchId);
- }
+ onListen: () {
+ assert(watchId == null);
+ watchId = $dom_watchPosition(
+ (position) {
+ controller.add(_ensurePosition(position));
+ },
+ (error) {
+ controller.addError(error);
+ },
+ options);
+ },
+ onCancel: () {
+ assert(watchId != null);
+ $dom_clearWatch(watchId);
});
return controller.stream;
diff --git a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
index 3464b5b..164cefa 100644
--- a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
@@ -10,7 +10,7 @@
try {
return _completeRequest($dom_delete());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -19,7 +19,7 @@
try {
return _completeRequest($dom_update(value));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
index 01031d6..b64989c 100644
--- a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
@@ -24,7 +24,7 @@
{int version, void onUpgradeNeeded(VersionChangeEvent),
void onBlocked(Event)}) {
if ((version == null) != (onUpgradeNeeded == null)) {
- return new Future.immediateError(new ArgumentError(
+ return new Future.error(new ArgumentError(
'version and onUpgradeNeeded must be specified together'));
}
try {
@@ -43,7 +43,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -58,7 +58,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -71,7 +71,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
index 08c5d07..f184d02 100644
--- a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
@@ -16,7 +16,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -27,7 +27,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -38,7 +38,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
index 5343411..4251ff5 100644
--- a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
@@ -17,7 +17,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -26,7 +26,7 @@
try {
return _completeRequest($dom_clear());
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -35,7 +35,7 @@
try {
return _completeRequest($dom_delete(key_OR_keyRange));
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -50,7 +50,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -65,7 +65,7 @@
}
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
@@ -76,7 +76,7 @@
return _completeRequest(request);
} catch (e, stacktrace) {
- return new Future.immediateError(e, stacktrace);
+ return new Future.error(e, stacktrace);
}
}
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index cb664d6..af16447 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -82,6 +82,14 @@
}
}
+ void insertAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
+ void setAll(int index, Iterable<Node> iterable) {
+ throw new UnimplementedError();
+ }
+
Node removeLast() {
final result = last;
if (result != null) {
@@ -152,23 +160,28 @@
}
// FIXME: implement these.
- void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<Node> iterable,
+ [int skipCount = 0]) {
throw new UnsupportedError(
"Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError(
"Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [Node initialValue]) {
- throw new UnsupportedError(
- "Cannot insertRange on immutable List.");
- }
Iterable<Node> getRange(int start, int end) {
throw new UnimplementedError("NodeList.getRange");
}
+ void replaceRange(int start, int end, Iterable<Node> iterable) {
+ throw new UnimplementedError("NodeList.replaceRange");
+ }
+
+ void fillRange(int start, int end, [Node fillValue]) {
+ throw new UnimplementedError("NodeList.fillRange");
+ }
+
List<Node> sublist(int start, [int end]) {
if (end == null) end == length;
return Lists.getRange(this, start, end, <Node>[]);
@@ -269,7 +282,7 @@
$endif
var _model;
bool _hasLocalModel;
- StreamController<Node> _modelChangedStream;
+ Set<StreamController<Node>> _modelChangedStreams;
/**
* The data model which is inherited through the tree.
@@ -286,7 +299,7 @@
@Experimental
get model {
// If we have a change handler then we've cached the model locally.
- if (_modelChangedStream != null) {
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
return _model;
}
// Otherwise start looking up the tree.
@@ -306,8 +319,8 @@
_ModelTreeObserver.initialize();
if (changed) {
- if (_modelChangedStream != null) {
- _modelChangedStream.add(this);
+ if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+ _modelChangedStreams.toList().forEach((stream) => stream.add(this));
}
// Propagate new model to all descendants.
_ModelTreeObserver.propagateModel(this, value, false);
@@ -336,12 +349,14 @@
* Get a stream of models, whenever the model changes.
*/
Stream<Node> get onModelChanged {
- if (_modelChangedStream == null) {
- // Ensure the model is cached locally to minimize change notifications.
- _model = model;
- _modelChangedStream = new StreamController.broadcast();
+ if (_modelChangedStreams == null) {
+ _modelChangedStreams = new Set<StreamController<Node>>();
}
- return _modelChangedStream.stream;
+ var controller;
+ controller = new StreamController(
+ onListen: () { _modelChangedStreams.add(controller); },
+ onCancel: () { _modelChangedStreams.remove(controller); });
+ return controller.stream;
}
/**
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 2d9493d..7d86600 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -315,7 +315,7 @@
const _BeforeUnloadEventStreamProvider(this._eventType);
Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
- var controller = new StreamController.broadcast();
+ var controller = new StreamController();
var stream = new _EventStream(e, _eventType, useCapture);
stream.listen((event) {
var wrapped = new _BeforeUnloadEvent(event);
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 8b85dab..8baaa09 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -143,6 +143,14 @@
throw new UnsupportedError("Cannot add to immutable List.");
}
+ void insertAll(int index, Iterable<$E> iterable) {
+ throw new UnsupportedError("Cannot add to immutable List.");
+ }
+
+ void setAll(int index, Iterable<$E> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
$E removeAt(int pos) {
throw new UnsupportedError("Cannot remove from immutable List.");
}
@@ -163,16 +171,20 @@
throw new UnsupportedError("Cannot remove from immutable List.");
}
- void setRange(int start, int rangeLength, List<$E> from, [int startFrom]) {
+ void setRange(int start, int end, Iterable<$E> iterable, [int skipCount]) {
throw new UnsupportedError("Cannot setRange on immutable List.");
}
- void removeRange(int start, int rangeLength) {
+ void removeRange(int start, int end) {
throw new UnsupportedError("Cannot removeRange on immutable List.");
}
- void insertRange(int start, int rangeLength, [$E initialValue]) {
- throw new UnsupportedError("Cannot insertRange on immutable List.");
+ void replaceRange(int start, int end, Iterable<$E> iterable) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
+ }
+
+ void fillRange(int start, int end, [$E fillValue]) {
+ throw new UnsupportedError("Cannot modify an immutable List.");
}
Iterable<$E> getRange(int start, int end) =>
diff --git a/tools/release/version.dart b/tools/release/version.dart
index 74e1e66..99b44bd 100644
--- a/tools/release/version.dart
+++ b/tools/release/version.dart
@@ -149,7 +149,7 @@
Future<int> getRevision() {
if (repositoryType == RepositoryType.UNKNOWN) {
- return new Future.immediate(0);
+ return new Future.value(0);
}
var isSvn = repositoryType == RepositoryType.SVN;
var command = isSvn ? "svn" : "git";
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index abb1fe7..67e1716 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -30,6 +30,7 @@
_updatingProcess = Process.run('python', _getUpdateCommand);
_updatingProcess.then(_onUpdatedHandler).catchError((e) {
print("Error starting $script process: $e");
+ // TODO(floitsch): should we print the stacktrace?
return false;
});
}
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index feffa4c..cc1e414 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -142,7 +142,7 @@
}
},
onError: (e) {
- DebugLogger.error('HttpServer: an error occured: $e');
+ DebugLogger.error('HttpServer: an error occured', e);
});
_serverList.add(httpServer);
});
@@ -186,7 +186,7 @@
response.headers.set("Access-Control-Allow-Origin", "*");
request.pipe(response).catchError((e) {
DebugLogger.warning(
- 'HttpServer: error while closing the response stream: $e');
+ 'HttpServer: error while closing the response stream', e);
});
}
@@ -196,12 +196,11 @@
websocket.send(data);
websocket.close();
}, onError: (e) {
- DebugLogger.warning(
- 'HttpServer: error while echoing to WebSocket: $e');
+ DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
});
}).catchError((e) {
DebugLogger.warning(
- 'HttpServer: error while transforming to WebSocket: $e');
+ 'HttpServer: error while transforming to WebSocket', e);
});
}
@@ -286,7 +285,7 @@
response.close();
response.done.catchError((e) {
DebugLogger.warning(
- 'HttpServer: error while closing the response stream: $e');
+ 'HttpServer: error while closing the response stream', e);
});
}
@@ -336,7 +335,7 @@
}
file.openRead().pipe(response).catchError((e) {
DebugLogger.warning(
- 'HttpServer: error while closing the response stream: $e');
+ 'HttpServer: error while closing the response stream', e);
});
}
@@ -352,7 +351,7 @@
response.close();
response.done.catchError((e) {
DebugLogger.warning(
- 'HttpServer: error while closing the response stream: $e');
+ 'HttpServer: error while closing the response stream', e);
});
}
}
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 5eac74a..659fef5 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -344,8 +344,8 @@
void allDone() {
if (_printSummary) {
- print('\n=== Failure summary:\n');
if (!_failureSummary.isEmpty) {
+ print('\n=== Failure summary:\n');
for (String line in _failureSummary) {
print(line);
}
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 5dd8e19..231cdb5 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -984,6 +984,7 @@
timeoutTimer = new Timer(new Duration(seconds: testCase.timeout),
timeoutHandler);
}).catchError((e) {
+ // TODO(floitsch): should we try to report the stacktrace?
print("Process error:");
print(" Command: $command");
print(" Error: $e");
@@ -1243,6 +1244,7 @@
});
callback();
}).catchError((e) {
+ // TODO(floitsch): should we try to report the stacktrace?
print("Process error:");
print(" Command: $_executable ${_batchArguments.join(' ')}");
print(" Error: $e");
@@ -1414,6 +1416,7 @@
}
});
}).catchError((e) {
+ // TODO(floitsch): should we try to report the stacktrace?
print("Error starting process:");
print(" Command: $cmd ${arg.join(' ')}");
print(" Error: $e");
@@ -1479,6 +1482,7 @@
stdoutStringStream.listen(seleniumServerHandler);
stderrStringStream.listen(seleniumServerHandler);
}).catchError((e) {
+ // TODO(floitsch): should we try to report the stacktrace?
print("Process error:");
print(" Command: java -jar $file");
print(" Error: $e");
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 6381a12..3a3de41 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -79,7 +79,7 @@
_pending++;
var handledTaskFuture = task.catchError((e) {
if (!wasCompleted) {
- _completer.completeError(e.error, e.stackTrace);
+ _completer.completeError(e);
wasCompleted = true;
}
}).then((_) {
@@ -1094,7 +1094,7 @@
}
if (executable.endsWith('.dart')) {
// Run the compiler script via the Dart VM.
- args.insertRange(0, 1, executable);
+ args.insert(0, executable);
executable = dartShellFileName;
}
if (['dart2js', 'dart2dart'].contains(configuration['compiler'])) {
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index dc79246..4ab769c 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -5,6 +5,7 @@
library utils;
import 'dart:io';
+import 'dart:async';
import 'dart:utf' as utf;
class DebugLogger {
@@ -27,15 +28,28 @@
}
}
- static void info(String msg) {
+ static String _formatErrorMessage(String msg, error) {
+ if (error == null) return msg;
+ msg += ": $error";
+ // TODO(floitsch): once the dart-executable that is bundled
+ // with the Dart sources is updated, uncomment the following
+ // lines.
+ // var trace = getAttachedStackTrace(error);
+ // if (trace != null) msg += "\nStackTrace: $trace";
+ return msg;
+ }
+ static void info(String msg, [error]) {
+ msg = _formatErrorMessage(msg, error);
_print("Info: $msg");
}
- static void warning(String msg) {
+ static void warning(String msg, [error]) {
+ msg = _formatErrorMessage(msg, error);
_print("Warning: $msg");
}
- static void error(String msg) {
+ static void error(String msg, [error]) {
+ msg = _formatErrorMessage(msg, error);
_print("Error: $msg");
}
diff --git a/tools/version.dart b/tools/version.dart
index eb10ac7..6972667 100644
--- a/tools/version.dart
+++ b/tools/version.dart
@@ -4,6 +4,7 @@
// BSD-style license that can be found in the LICENSE file.
import "dart:io";
+import "dart:async" show getAttachedStackTrace;
import "release/version.dart";
void main() {
@@ -14,6 +15,8 @@
print(currentVersion);
}).catchError((e) {
print("Could not create version number, failed with: $e");
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
return true;
});
}
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index b7783b4..233f9be 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -155,6 +155,8 @@
.then((_) => print(apidoc.status))
.catchError((e) {
print('Error: generation failed: ${e}');
+ var trace = getAttachedStackTrace(e);
+ if (trace != null) print("StackTrace: $trace");
apidoc.cleanup();
exit(1);
})
diff --git a/utils/apidoc/mdn/extract.dart b/utils/apidoc/mdn/extract.dart
index 65d753b..2e2d766 100644
--- a/utils/apidoc/mdn/extract.dart
+++ b/utils/apidoc/mdn/extract.dart
@@ -1,3 +1,8 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
import 'dart:html';
import 'dart:json' as json;
@@ -477,7 +482,7 @@
}
}
-class PostOrderTraversal extends Iterable<Node> {
+class PostOrderTraversal extends IterableBase<Node> {
final Node _node;
PostOrderTraversal(this._node);
diff --git a/utils/lib/file_system_vm.dart b/utils/lib/file_system_vm.dart
index 7c09b70..d84d081 100644
--- a/utils/lib/file_system_vm.dart
+++ b/utils/lib/file_system_vm.dart
@@ -21,7 +21,7 @@
var file = (new File(filename)).openSync();
var length = file.lengthSync();
var buffer = new List<int>(length);
- var bytes = file.readListSync(buffer, 0, length);
+ var bytes = file.readIntoSync(buffer, 0, length);
file.closeSync();
return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
}
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 1948ba1..8fa94df 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -83,18 +83,18 @@
return location;
}).then((location) => client.get(location))
.then(handleJsonSuccess);
- }).catchError((asyncError) {
- if (asyncError.error is! PubHttpException) throw asyncError;
- var url = asyncError.error.response.request.url;
+ }).catchError((error) {
+ if (error is! PubHttpException) throw error;
+ var url = error.response.request.url;
if (urisEqual(url, cloudStorageUrl)) {
// TODO(nweiz): the response may have XML-formatted information about
// the error. Try to parse that out once we have an easily-accessible
// XML parser.
throw 'Failed to upload the package.';
} else if (urisEqual(Uri.parse(url.origin), Uri.parse(server.origin))) {
- handleJsonError(asyncError.error.response);
+ handleJsonError(error.response);
} else {
- throw asyncError;
+ throw error;
}
});
}
diff --git a/utils/pub/command_uploader.dart b/utils/pub/command_uploader.dart
index 673a4bd..5bb05f2 100644
--- a/utils/pub/command_uploader.dart
+++ b/utils/pub/command_uploader.dart
@@ -59,7 +59,7 @@
exit(exit_codes.USAGE);
}
- return new Future.of(() {
+ return new Future.sync(() {
var package = commandOptions['package'];
if (package != null) return package;
return new Entrypoint(path.current, cache).root.name;
@@ -76,9 +76,8 @@
return client.delete(url);
}
});
- }).then(handleJsonSuccess).catchError((asyncError) {
- if (asyncError.error is! PubHttpException) throw asyncError;
- handleJsonError(asyncError.error.response);
- });
+ }).then(handleJsonSuccess)
+ .catchError((error) => handleJsonError(error.response),
+ test: (e) => e is PubHttpException);
}
}
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index db6ad47..fe058c4 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -71,7 +71,7 @@
if (pendingOrCompleted != null) return pendingOrCompleted;
var packageDir = path.join(packagesDir, id.name);
- var future = new Future.of(() {
+ var future = new Future.sync(() {
ensureDir(path.dirname(packageDir));
if (entryExists(packageDir)) {
@@ -102,7 +102,7 @@
/// directory, respecting the [LockFile] if present. Returns a [Future] that
/// completes when all dependencies are installed.
Future installDependencies() {
- return new Future.of(() {
+ return new Future.sync(() {
return resolveVersions(cache.sources, root, loadLockFile());
}).then(_installDependencies);
}
@@ -119,7 +119,7 @@
/// other dependencies as specified by the [LockFile] if possible. Returns a
/// [Future] that completes when all dependencies are installed.
Future updateDependencies(List<String> dependencies) {
- return new Future.of(() {
+ return new Future.sync(() {
var solver = new VersionSolver(cache.sources, root, loadLockFile());
for (var dependency in dependencies) {
solver.useLatestVersion(dependency);
@@ -131,10 +131,10 @@
/// Removes the old packages directory, installs all dependencies listed in
/// [packageVersions], and writes a [LockFile].
Future _installDependencies(List<PackageId> packageVersions) {
- return new Future.of(() {
+ return new Future.sync(() {
cleanDir(packagesDir);
return Future.wait(packageVersions.map((id) {
- if (id.isRoot) return new Future.immediate(id);
+ if (id.isRoot) return new Future.value(id);
return install(id);
}).toList());
}).then((ids) {
@@ -148,13 +148,13 @@
/// reached packages. This should only be called after the lockfile has been
/// successfully generated.
Future<List<Pubspec>> walkDependencies() {
- return new Future.of(() {
+ return new Future.sync(() {
var lockFile = loadLockFile();
var group = new FutureGroup<Pubspec>();
var visited = new Set<String>();
// Include the root package in the results.
- group.add(new Future.immediate(root.pubspec));
+ group.add(new Future.value(root.pubspec));
visitPackage(Pubspec pubspec) {
for (var ref in pubspec.dependencies) {
@@ -166,7 +166,7 @@
visited.add(ref.name);
var future;
if (ref.name == root.name) {
- future = new Future<Pubspec>.immediate(root.pubspec);
+ future = new Future<Pubspec>.value(root.pubspec);
} else {
future = cache.describe(id);
}
diff --git a/utils/pub/error_group.dart b/utils/pub/error_group.dart
index b5f8f8e..694638c 100644
--- a/utils/pub/error_group.dart
+++ b/utils/pub/error_group.dart
@@ -103,7 +103,7 @@
///
/// If all members of [this] have already completed successfully or with an
/// error, it's a [StateError] to try to signal an error.
- void signalError(AsyncError error) {
+ void signalError(var error) {
if (_isDone) {
throw new StateError("Can't signal errors on a complete ErrorGroup.");
}
@@ -113,7 +113,7 @@
/// Signal an error internally. This is just like [signalError], but instead
/// of throwing an error if [this] is complete, it just does nothing.
- void _signalError(AsyncError error) {
+ void _signalError(var error) {
if (_isDone) return;
var caught = false;
@@ -181,12 +181,12 @@
_completer.future.catchError((_) {});
}
- Future then(onValue(value), {onError(AsyncError asyncError)}) {
+ Future then(onValue(value), {onError(error)}) {
_hasListeners = true;
return _completer.future.then(onValue, onError: onError);
}
- Future catchError(onError(AsyncError asyncError), {bool test(Object error)}) {
+ Future catchError(onError(error), {bool test(Object error)}) {
_hasListeners = true;
return _completer.future.catchError(onError, test: test);
}
@@ -203,8 +203,8 @@
/// Signal that an error from [_group] should be propagated through [this],
/// unless it's already complete.
- void _signalError(AsyncError error) {
- if (!_isDone) _completer.completeError(error.error, error.stackTrace);
+ void _signalError(var error) {
+ if (!_isDone) _completer.completeError(error);
_isDone = true;
}
}
@@ -225,6 +225,10 @@
/// The underlying [StreamController] for [this].
final StreamController _controller;
+ /// The controller's [Stream]. May be different than `_controller.stream` if
+ /// the wrapped stream is a broadcasting stream.
+ Stream _stream;
+
/// The [StreamSubscription] that connects the wrapped [Stream] to
/// [_controller].
StreamSubscription _subscription;
@@ -235,9 +239,10 @@
/// Creates a new [_ErrorGroupFuture] that's a child of [_group] and wraps
/// [inner].
_ErrorGroupStream(this._group, Stream inner)
- : _controller = inner.isBroadcast ?
- new StreamController.broadcast() :
- new StreamController() {
+ : _controller = new StreamController() {
+ this._stream = inner.isBroadcast
+ ? _controller.stream.asBroadcastStream()
+ : _controller.stream;
_subscription = inner.listen((v) {
_controller.add(v);
}, onError: (e) {
@@ -250,22 +255,22 @@
}
StreamSubscription listen(void onData(value),
- {void onError(AsyncError error), void onDone(),
- bool unsubscribeOnError}) {
- return _controller.stream.listen(onData,
+ {void onError(var error), void onDone(),
+ bool cancelOnError}) {
+ return _stream.listen(onData,
onError: onError,
onDone: onDone,
- unsubscribeOnError: true);
+ cancelOnError: true);
}
/// Signal that an error from [_group] should be propagated through [this],
/// unless it's already complete.
- void _signalError(AsyncError e) {
+ void _signalError(var e) {
if (_isDone) return;
_subscription.cancel();
// Call these asynchronously to work around issue 7913.
- new Future.immediate(null).then((_) {
- _controller.addError(e.error, e.stackTrace);
+ new Future.value().then((_) {
+ _controller.addError(e);
_controller.close();
});
}
diff --git a/utils/pub/git.dart b/utils/pub/git.dart
index 53ecbe7..8d996229 100644
--- a/utils/pub/git.dart
+++ b/utils/pub/git.dart
@@ -13,7 +13,7 @@
/// Tests whether or not the git command-line app is available for use.
Future<bool> get isInstalled {
if (_isGitInstalledCache != null) {
- return new Future.immediate(_isGitInstalledCache);
+ return new Future.value(_isGitInstalledCache);
}
return _gitCommand.then((git) => git != null);
@@ -44,7 +44,7 @@
/// found on the user's PATH.
Future<String> get _gitCommand {
if (_gitCommandCache != null) {
- return new Future.immediate(_gitCommandCache);
+ return new Future.value(_gitCommandCache);
}
return _tryGitCommand("git").then((success) {
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index cea2bac..c98616d 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -123,7 +123,7 @@
/// future that completes once this is finished and throws an exception if it
/// fails.
Future _ensureRepoCache(PackageId id) {
- return new Future.of(() {
+ return new Future.sync(() {
var path = _repoCachePath(id);
if (!entryExists(path)) return _clone(_getUrl(id), path, mirror: true);
return git.run(["fetch"], workingDir: path).then((result) => null);
@@ -143,12 +143,12 @@
/// the working tree, but instead makes the repository a local mirror of the
/// remote repository. See the manpage for `git clone` for more information.
Future _clone(String from, String to, {bool mirror: false}) {
- return new Future.of(() {
+ return new Future.sync(() {
// Git on Windows does not seem to automatically create the destination
// directory.
ensureDir(to);
var args = ["clone", from, to];
- if (mirror) args.insertRange(1, 1, "--mirror");
+ if (mirror) args.insert(1, "--mirror");
return git.run(args);
}).then((result) => null);
}
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 0ed4e0c..5a4106e 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -63,7 +63,7 @@
/// Downloads a package from the site and unpacks it.
Future<bool> install(PackageId id, String destPath) {
- return new Future.of(() {
+ return new Future.sync(() {
var url = _makeVersionUrl(id, (server, package, version) =>
"$server/packages/$package/versions/$version.tar.gz");
log.io("Install package from $url.");
@@ -98,7 +98,7 @@
return '%${match[0].codeUnitAt(0)}';
});
- return new Future.immediate(
+ return new Future.value(
path.join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}"));
}
@@ -130,23 +130,23 @@
/// When an error occurs trying to read something about [package] from [url],
/// this tries to translate into a more user friendly error message. Always
/// throws an error, either the original one or a better one.
- void _throwFriendlyError(AsyncError asyncError, package, url) {
- if (asyncError.error is PubHttpException &&
- asyncError.error.response.statusCode == 404) {
+ void _throwFriendlyError(error, package, url) {
+ if (error is PubHttpException &&
+ error.response.statusCode == 404) {
throw 'Could not find package "$package" at $url.';
}
- if (asyncError.error is TimeoutException) {
+ if (error is TimeoutException) {
throw 'Timed out trying to find package "$package" at $url.';
}
- if (asyncError.error is io.SocketIOException) {
+ if (error is io.SocketIOException) {
throw 'Got socket error trying to find package "$package" at $url.\n'
- '${asyncError.error.osError}';
+ '${error.osError}';
}
// Otherwise re-throw the original exception.
- throw asyncError;
+ throw error;
}
}
diff --git a/utils/pub/http.dart b/utils/pub/http.dart
index dadc4b1..8df0575 100644
--- a/utils/pub/http.dart
+++ b/utils/pub/http.dart
@@ -61,21 +61,21 @@
return http.Response.fromStream(streamedResponse).then((response) {
throw new PubHttpException(response);
});
- }).catchError((asyncError) {
- if (asyncError.error is SocketIOException &&
- asyncError.error.osError != null) {
- if (asyncError.error.osError.errorCode == 8 ||
- asyncError.error.osError.errorCode == -2 ||
- asyncError.error.osError.errorCode == -5 ||
- asyncError.error.osError.errorCode == 11001 ||
- asyncError.error.osError.errorCode == 11004) {
+ }).catchError((error) {
+ if (error is SocketIOException &&
+ error.osError != null) {
+ if (error.osError.errorCode == 8 ||
+ error.osError.errorCode == -2 ||
+ error.osError.errorCode == -5 ||
+ error.osError.errorCode == 11001 ||
+ error.osError.errorCode == 11004) {
throw 'Could not resolve URL "${request.url.origin}".';
- } else if (asyncError.error.osError.errorCode == -12276) {
+ } else if (error.osError.errorCode == -12276) {
throw 'Unable to validate SSL certificate for '
'"${request.url.origin}".';
}
}
- throw asyncError;
+ throw error;
}), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
}
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 8523d34..32c4574 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -69,7 +69,7 @@
String writeBinaryFile(String file, List<int> contents) {
log.io("Writing ${contents.length} bytes to binary file $file.");
new File(file).openSync(mode: FileMode.WRITE)
- ..writeListSync(contents, 0, contents.length)
+ ..writeFromSync(contents)
..closeSync();
log.fine("Wrote text file $file.");
return file;
@@ -284,10 +284,12 @@
/// A sink that writes to standard output. Errors piped to this stream will be
/// surfaced to the top-level error handler.
+// TODO: Unrequired wrapper, stdout is now an EventSink<List<int>>.
final EventSink<List<int>> stdoutSink = _wrapStdio(stdout, "stdout");
/// A sink that writes to standard error. Errors piped to this stream will be
/// surfaced to the top-level error handler.
+// TODO: Unrequired wrapper, stdout is now an EventSink<List<int>>.
final EventSink<List<int>> stderrSink = _wrapStdio(stderr, "stderr");
/// Wrap the standard output or error [stream] in a [EventSink]. Any errors are
@@ -297,7 +299,7 @@
pair.last.catchError((e) {
// This log may or may not work, depending on how the stream failed. Not
// much we can do about that.
- log.error("Error writing to $name: $e");
+ log.error("Error writing to $name", e);
exit(exit_codes.IO);
});
return pair.first;
@@ -341,17 +343,17 @@
/// true.
///
/// When an error occurs on [stream], that error is passed to [sink]. If
-/// [unsubscribeOnError] is true, [Future] will be completed successfully and no
+/// [cancelOnError] is true, [Future] will be completed successfully and no
/// more data or errors will be piped from [stream] to [sink]. If
-/// [unsubscribeOnError] and [closeSink] are both true, [sink] will then be
+/// [cancelOnError] and [closeSink] are both true, [sink] will then be
/// closed.
Future store(Stream stream, EventSink sink,
- {bool unsubscribeOnError: true, closeSink: true}) {
+ {bool cancelOnError: true, closeSink: true}) {
var completer = new Completer();
stream.listen(sink.add,
onError: (e) {
sink.addError(e);
- if (unsubscribeOnError) {
+ if (cancelOnError) {
completer.complete();
if (closeSink) sink.close();
}
@@ -359,7 +361,7 @@
onDone: () {
if (closeSink) sink.close();
completer.complete();
- }, unsubscribeOnError: unsubscribeOnError);
+ }, cancelOnError: cancelOnError);
return completer.future;
}
@@ -548,9 +550,9 @@
/// Returns a future that completes to the value that the future returned from
/// [fn] completes to.
Future withTempDir(Future fn(String path)) {
- return new Future.of(() {
+ return new Future.sync(() {
var tempDir = createTempDir();
- return new Future.of(() => fn(tempDir))
+ return new Future.sync(() => fn(tempDir))
.whenComplete(() => deleteEntry(tempDir));
});
}
@@ -668,7 +670,7 @@
}).catchError((e) {
// We don't have to worry about double-signaling here, since the store()
// above will only be reached if startProcess succeeds.
- controller.addError(e.error, e.stackTrace);
+ controller.addError(e);
controller.close();
});
return new ByteStream(controller.stream);
@@ -705,7 +707,7 @@
}).catchError((e) {
// We don't have to worry about double-signaling here, since the store()
// above will only be reached if everything succeeds.
- controller.addError(e.error, e.stackTrace);
+ controller.addError(e);
controller.close();
});
return new ByteStream(controller.stream);
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
index ec3fee9..891ba7d 100644
--- a/utils/pub/log.dart
+++ b/utils/pub/log.dart
@@ -57,7 +57,16 @@
}
/// Logs [message] at [Level.ERROR].
-void error(message) => write(Level.ERROR, message);
+void error(message, [error]) {
+ if (error != null) {
+ message = "$message: $error";
+ var trace = getAttachedStackTrace(error);
+ if (trace != null) {
+ message = "$message\nStackTrace: $trace";
+ }
+ }
+ write(Level.ERROR, message);
+}
/// Logs [message] at [Level.WARNING].
void warning(message) => write(Level.WARNING, message);
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 85bfed7..e4b8ee0 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -82,21 +82,21 @@
// Be sure to save the credentials even when an error happens.
_saveCredentials(cache, client.credentials);
});
- }).catchError((asyncError) {
- if (asyncError.error is ExpirationException) {
+ }).catchError((error) {
+ if (error is ExpirationException) {
log.error("Pub's authorization to upload packages has expired and "
"can't be automatically refreshed.");
return withClient(cache, fn);
- } else if (asyncError.error is AuthorizationException) {
+ } else if (error is AuthorizationException) {
var message = "OAuth2 authorization failed";
- if (asyncError.error.description != null) {
- message = "$message (${asyncError.error.description})";
+ if (error.description != null) {
+ message = "$message (${error.description})";
}
log.error("$message.");
clearCredentials(cache);
return withClient(cache, fn);
} else {
- throw asyncError;
+ throw error;
}
});
}
@@ -104,7 +104,7 @@
/// Gets a new OAuth2 client. If saved credentials are available, those are
/// used; otherwise, the user is prompted to authorize the pub client.
Future<Client> _getClient(SystemCache cache) {
- return new Future.of(() {
+ return new Future.sync(() {
var credentials = _loadCredentials(cache);
if (credentials == null) return _authorize();
diff --git a/utils/pub/path_source.dart b/utils/pub/path_source.dart
index e849b6f..e4d1f02 100644
--- a/utils/pub/path_source.dart
+++ b/utils/pub/path_source.dart
@@ -25,7 +25,7 @@
final shouldCache = false;
Future<Pubspec> describe(PackageId id) {
- return new Future.of(() {
+ return new Future.sync(() {
_validatePath(id.name, id.description);
return new Pubspec.load(id.name, id.description["path"],
systemCache.sources);
@@ -40,7 +40,7 @@
}
Future<bool> install(PackageId id, String destination) {
- return new Future.of(() {
+ return new Future.sync(() {
try {
_validatePath(id.name, id.description);
} on FormatException catch(err) {
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 811c198..9af9c27 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -145,7 +145,7 @@
/// Checks that pub is running on a supported platform. If it isn't, it prints
/// an error message and exits. Completes when the validation is done.
Future validatePlatform() {
- return new Future.of(() {
+ return new Future.sync(() {
if (Platform.operatingSystem != 'windows') return;
return runProcess('ver', []).then((result) {
@@ -236,7 +236,9 @@
exit(exit_codes.USAGE);
}
- handleError(error, trace) {
+ handleError(error) {
+ var trace = getAttachedStackTrace(error);
+
// This is basically the top-level exception handler so that we don't
// spew a stack trace on our users.
var message;
@@ -265,7 +267,7 @@
exit(_chooseExitCode(error));
}
- new Future.of(() {
+ new Future.sync(() {
if (requiresEntrypoint) {
// TODO(rnystrom): Will eventually need better logic to walk up
// subdirectories until we hit one that looks package-like. For now,
@@ -277,8 +279,7 @@
if (commandFuture == null) return true;
return commandFuture;
- }).whenComplete(() => cache_.deleteTempDir()).catchError((asyncError) {
- var e = asyncError.error;
+ }).whenComplete(() => cache_.deleteTempDir()).catchError((e) {
if (e is PubspecNotFoundException && e.name == null) {
e = 'Could not find a file named "pubspec.yaml" in the directory '
'${path.current}.';
@@ -287,7 +288,7 @@
'${path.basename(path.current)}").';
}
- handleError(e, asyncError.stackTrace);
+ handleError(e);
}).then((_) {
// Explicitly exit on success to ensure that any dangling dart:io handles
// don't cause the process to never terminate.
diff --git a/utils/pub/safe_http_server.dart b/utils/pub/safe_http_server.dart
index 8843e48..79417bc 100644
--- a/utils/pub/safe_http_server.dart
+++ b/utils/pub/safe_http_server.dart
@@ -42,23 +42,22 @@
HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
- {void onError(AsyncError error), void onDone(),
- bool unsubscribeOnError: false}) {
+ {void onError(error), void onDone(),
+ bool cancelOnError: false}) {
var subscription;
subscription = super.listen((request) {
onData(new _HttpRequestWrapper(request));
- }, onError: (e) {
- var error = e.error;
+ }, onError: (error) {
// Ignore socket error 104, which is caused by a request being cancelled
// before it writes any headers. There's no reason to care about such
// requests.
if (error is SocketIOException && error.osError.errorCode == 104) return;
// Ignore any parsing errors, which come from malformed requests.
if (error is HttpParserException) return;
- // Manually handle unsubscribeOnError so the above (ignored) errors don't
+ // Manually handle cancelOnError so the above (ignored) errors don't
// cause unsubscription.
- if (unsubscribeOnError) subscription.cancel();
- if (onError != null) onError(e);
+ if (cancelOnError) subscription.cancel();
+ if (onError != null) onError(error);
}, onDone: onDone);
return subscription;
}
@@ -132,12 +131,8 @@
Future<Socket> detachSocket() => _inner.detachSocket();
HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
void add(List<int> data) => _inner.add(data);
- Future<HttpResponse> consume(Stream<List<int>> stream) =>
- _inner.consume(stream);
Future<HttpResponse> addStream(Stream<List<int>> stream) =>
_inner.addStream(stream);
- Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
- _inner.writeStream(stream);
Future close() => _inner.close();
void write(Object obj) => _inner.write(obj);
void writeAll(Iterable objects) => _inner.writeAll(objects);
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index adb9571..b5e5d53 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -154,7 +154,7 @@
///
/// This doesn't need to be implemented if [shouldCache] is false.
Future<String> systemCacheDirectory(PackageId id) {
- return new Future.immediateError(
+ return new Future.error(
"systemCacheDirectory() must be implemented if shouldCache is true.");
}
@@ -206,7 +206,7 @@
/// [descriptionsEqual].
///
/// By default, this just returns [id].
- Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);
+ Future<PackageId> resolveId(PackageId id) => new Future.value(id);
/// Returns the [Package]s that have been installed in the system cache.
List<Package> getCachedPackages() {
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 47c27fc..5e80e57 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -59,7 +59,7 @@
if (completed) return;
completed = true;
- _completer.completeError(e.error, e.stackTrace);
+ _completer.completeError(e);
}));
return task;
@@ -156,7 +156,7 @@
/// to [completer].
void chainToCompleter(Future future, Completer completer) {
future.then((value) => completer.complete(value),
- onError: (e) => completer.completeError(e.error, e.stackTrace));
+ onError: (e) => completer.completeError(e));
}
// TODO(nweiz): remove this when issue 7964 is fixed.
@@ -169,23 +169,24 @@
subscription.cancel();
completer.complete(value);
}, onError: (e) {
- completer.completeError(e.error, e.stackTrace);
+ completer.completeError(e);
}, onDone: () {
completer.completeError(new StateError("No elements"));
- }, unsubscribeOnError: true);
+ }, cancelOnError: true);
return completer.future;
}
/// Returns a wrapped version of [stream] along with a [StreamSubscription] that
/// can be used to control the wrapped stream.
Pair<Stream, StreamSubscription> streamWithSubscription(Stream stream) {
- var controller = stream.isBroadcast ?
- new StreamController.broadcast() :
- new StreamController();
+ var controller = new StreamController();
+ var controllerStream = stream.isBroadcast ?
+ controller.stream.asBroadcastStream() :
+ controller.stream;
var subscription = stream.listen(controller.add,
onError: controller.addError,
onDone: controller.close);
- return new Pair<Stream, StreamSubscription>(controller.stream, subscription);
+ return new Pair<Stream, StreamSubscription>(controllerStream, subscription);
}
// TODO(nweiz): remove this when issue 7787 is fixed.
@@ -248,7 +249,7 @@
Future<Iterable> futureWhere(Iterable iter, test(value)) {
return Future.wait(iter.map((e) {
var result = test(e);
- if (result is! Future) result = new Future.immediate(result);
+ if (result is! Future) result = new Future.value(result);
return result.then((result) => new Pair(e, result));
}))
.then((pairs) => pairs.where((pair) => pair.last))
@@ -342,7 +343,7 @@
if (object is Iterable) {
return Future.wait(object.map(awaitObject).toList());
}
- if (object is! Map) return new Future.immediate(object);
+ if (object is! Map) return new Future.value(object);
var pairs = <Future<Pair>>[];
object.forEach((key, value) {
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
index 1998c47..45a8fba 100644
--- a/utils/pub/validator/compiled_dartdoc.dart
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -20,7 +20,7 @@
: super(entrypoint);
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
for (var entry in listDir(entrypoint.root.dir, recursive: true)) {
if (path.basename(entry) != "nav.json") continue;
var dir = path.dirname(entry);
diff --git a/utils/pub/validator/dependency.dart b/utils/pub/validator/dependency.dart
index d66059d..711e82d 100644
--- a/utils/pub/validator/dependency.dart
+++ b/utils/pub/validator/dependency.dart
@@ -31,12 +31,12 @@
'package.\n'
'Pub enables "package:${entrypoint.root.name}" imports '
'implicitly.');
- return new Future.immediate(null);
+ return new Future.value();
}
if (dependency.constraint.isAny) _warnAboutConstraint(dependency);
- return new Future.immediate(null);
+ return new Future.value();
});
}
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 5d6628d..216f2bf 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -21,7 +21,7 @@
static final _PLURAL_NAMES = ["tools", "tests", "docs", "examples"];
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
for (var dir in listDir(entrypoint.root.dir)) {
if (!dirExists(dir)) continue;
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index 7ff06fc..2e72738 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -23,7 +23,7 @@
: super(entrypoint);
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
var libDir = path.join(entrypoint.root.dir, "lib");
if (!dirExists(libDir)) {
diff --git a/utils/pub/validator/license.dart b/utils/pub/validator/license.dart
index ffcbd10..50d1bfe 100644
--- a/utils/pub/validator/license.dart
+++ b/utils/pub/validator/license.dart
@@ -19,7 +19,7 @@
: super(entrypoint);
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
var licenseLike = new RegExp(
r"^([a-zA-Z0-9]+[-_])?(LICENSE|COPYING)(\..*)?$");
if (listDir(entrypoint.root.dir)
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 412d6c3..542d9fd 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -28,7 +28,7 @@
: super(entrypoint);
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
_checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"',
isPackage: true);
diff --git a/utils/pub/validator/pubspec_field.dart b/utils/pub/validator/pubspec_field.dart
index e87f38b..03a1b8e 100644
--- a/utils/pub/validator/pubspec_field.dart
+++ b/utils/pub/validator/pubspec_field.dart
@@ -56,6 +56,6 @@
errors.add('Your pubspec.yaml is missing a "version" field.');
}
- return new Future.immediate(null);
+ return new Future.value();
}
}
diff --git a/utils/pub/validator/utf8_readme.dart b/utils/pub/validator/utf8_readme.dart
index 8bf52a9..cbb85c4 100644
--- a/utils/pub/validator/utf8_readme.dart
+++ b/utils/pub/validator/utf8_readme.dart
@@ -20,7 +20,7 @@
: super(entrypoint);
Future validate() {
- return new Future.of(() {
+ return new Future.sync(() {
var readme = entrypoint.root.readmePath;
if (readme == null) return;
var bytes = readBinaryFile(readme);
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 5b055d8..36569ba 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -97,7 +97,7 @@
Future processNextWorkItem(_) {
while (true) {
// Stop if we are done.
- if (_work.isEmpty) return new Future.immediate(buildResults());
+ if (_work.isEmpty) return new Future.value(buildResults());
// If we appear to be stuck in a loop, then we probably have an unstable
// graph, bail. We guess this based on a rough heuristic that it should
@@ -284,8 +284,7 @@
Version version) {
// If there is no version, it means no package, so no dependencies.
if (version == null) {
- return new Future<Map<String, PackageRef>>.immediate(
- <String, PackageRef>{});
+ return new Future<Map<String, PackageRef>>.value(<String, PackageRef>{});
}
var id = new PackageId(package, source, version, description);
@@ -475,7 +474,7 @@
Future<Pubspec> load(PackageId id) {
// Complete immediately if it's already cached.
if (_pubspecs.containsKey(id)) {
- return new Future<Pubspec>.immediate(_pubspecs[id]);
+ return new Future<Pubspec>.value(_pubspecs[id]);
}
return id.describe().then((pubspec) {
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index 1efd7d1d..2fbc3cd 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -5,7 +5,7 @@
library command_line_config;
import 'dart:io';
-import 'dart:math';
+import 'dart:math' as math;
import 'package:pathos/path.dart' as path;
import 'package:unittest/unittest.dart';
@@ -92,7 +92,7 @@
if (stack.length == 0) return;
// Figure out the longest path so we know how much to pad.
- int longest = stack.map((frame) => frame.location.length).reduce(max);
+ int longest = stack.map((frame) => frame.location.length).reduce(math.max);
// Print out the stack trace nicely formatted.
for (var frame in stack) {
diff --git a/utils/tests/pub/error_group_test.dart b/utils/tests/pub/error_group_test.dart
index e7aa477..3460ddd 100644
--- a/utils/tests/pub/error_group_test.dart
+++ b/utils/tests/pub/error_group_test.dart
@@ -28,15 +28,15 @@
test('should pass signaled errors to .done', () {
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
});
test("shouldn't allow additional futures or streams once an error has been "
"signaled", () {
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
- expect(() => errorGroup.registerFuture(new Future.immediate(null)),
+ expect(() => errorGroup.registerFuture(new Future.value()),
throwsStateError);
expect(() => errorGroup.registerStream(new StreamController().stream),
throwsStateError);
@@ -63,7 +63,7 @@
"been called", () {
completer.complete('value');
- expect(() => errorGroup.registerFuture(new Future.immediate(null)),
+ expect(() => errorGroup.registerFuture(new Future.value()),
throwsStateError);
expect(() => errorGroup.registerStream(new StreamController().stream),
throwsStateError);
@@ -87,7 +87,7 @@
'and should ignore a subsequent value from that future', () {
expect(future, throwsFormatException);
// errorGroup shouldn't top-level the exception
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
completer.complete('value');
});
@@ -95,7 +95,7 @@
'and should ignore a subsequent exception from that future', () {
expect(future, throwsFormatException);
// errorGroup shouldn't top-level the exception
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
completer.completeError(new ArgumentError());
});
@@ -103,7 +103,7 @@
'future has a listener', () {
expect(future, throwsFormatException);
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
});
test("should complete .done if the future receives a value even if the "
@@ -131,7 +131,7 @@
"a listener",
() {
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
// A listener added afterwards should receive the exception
expect(errorGroup.done.catchError((_) {
@@ -192,7 +192,7 @@
expect(future1.then((_) {
// shouldn't cause a top-level exception
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
}), completes);
});
});
@@ -203,8 +203,8 @@
setUp(() {
errorGroup = new ErrorGroup();
- controller = new StreamController.broadcast();
- stream = errorGroup.registerStream(controller.stream);
+ controller = new StreamController();
+ stream = errorGroup.registerStream(controller.stream.asBroadcastStream());
});
test('should pass through values from the stream', () {
@@ -219,21 +219,21 @@
'listener', () {
expect(stream.first, throwsFormatException);
// errorGroup shouldn't top-level the exception
- controller.addError(new AsyncError(new FormatException()));
+ controller.addError(new FormatException());
});
test('should notify the error group of an exception from the stream even '
'if it has a listener', () {
expect(stream.first, throwsFormatException);
expect(errorGroup.done, throwsFormatException);
- controller.addError(new AsyncError(new FormatException()));
+ controller.addError(new FormatException());
});
test('should pass a signaled exception to the stream if it has a listener '
'and should unsubscribe that stream', () {
expect(stream.first, throwsFormatException);
// errorGroup shouldn't top-level the exception
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
expect(stream.first.catchError((_) {
controller.add('value');
@@ -245,46 +245,21 @@
'stream has a listener', () {
expect(stream.first, throwsFormatException);
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
});
- test("should complete .done when the stream is done even if the stream "
- "doesn't have a listener", () {
+ test("should see one value and complete .done when the stream is done even "
+ "if the stream doesn't have a listener", () {
expect(errorGroup.done, completes);
controller.add('value');
controller.close();
- // A listener added afterwards should see an empty stream, since it's not
- // single-subscription
+ // Now that broadcast controllers have been removed a listener should
+ // see the value that has been put into the controller.
expect(errorGroup.done.then((_) => stream.toList()),
- completion(isEmpty));
+ completion(equals(['value'])));
});
- test("should pipe an exception from the stream to .done if the stream "
- "doesn't have a listener", () {
- expect(errorGroup.done, throwsFormatException);
- controller.addError(new AsyncError(new FormatException()));
-
- // A listener added afterwards should see an empty stream, since it's not
- // single-subscription
- expect(errorGroup.done.catchError((_) {
- controller.add('value'); // should be ignored
- return stream.toList();
- }), completion(isEmpty));
- });
-
- test("should pass a signaled exception to .done if the stream doesn't "
- "have a listener",
- () {
- expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
-
- // A listener added afterwards should receive the exception
- expect(errorGroup.done.catchError((_) {
- controller.add('value'); // should be ignored
- return stream.toList();
- }), completion(isEmpty));
- });
});
group('with a single single-subscription stream', () {
@@ -311,7 +286,7 @@
test("should pipe an exception from the stream to .done if the stream "
"doesn't have a listener", () {
expect(errorGroup.done, throwsFormatException);
- controller.addError(new AsyncError(new FormatException()));
+ controller.addError(new FormatException());
// A listener added afterwards should receive the exception
expect(errorGroup.done.catchError((_) {
@@ -324,7 +299,7 @@
"have a listener",
() {
expect(errorGroup.done, throwsFormatException);
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
// A listener added afterwards should receive the exception
expect(errorGroup.done.catchError((_) {
@@ -342,10 +317,10 @@
setUp(() {
errorGroup = new ErrorGroup();
- controller1 = new StreamController.broadcast();
- controller2 = new StreamController.broadcast();
- stream1 = errorGroup.registerStream(controller1.stream);
- stream2 = errorGroup.registerStream(controller2.stream);
+ controller1 = new StreamController();
+ controller2 = new StreamController();
+ stream1 = errorGroup.registerStream(controller1.stream.asBroadcastStream());
+ stream2 = errorGroup.registerStream(controller2.stream.asBroadcastStream());
});
test("should pipe exceptions from one stream to the other and to .done",
@@ -354,7 +329,7 @@
expect(stream2.first, throwsFormatException);
expect(errorGroup.done, throwsFormatException);
- controller1.addError(new AsyncError(new FormatException()));
+ controller1.addError(new FormatException());
});
test("each future should be able to emit values independently", () {
@@ -373,7 +348,7 @@
expect(stream1.toList().then((_) {
// shouldn't cause a top-level exception
- controller2.addError(new AsyncError(new FormatException()));
+ controller2.addError(new FormatException());
}), completes);
});
@@ -384,7 +359,7 @@
expect(stream1.toList().then((_) {
// shouldn't cause a top-level exception
- errorGroup.signalError(new AsyncError(new FormatException()));
+ errorGroup.signalError(new FormatException());
}), completes);
});
});
@@ -397,8 +372,8 @@
setUp(() {
errorGroup = new ErrorGroup();
- controller = new StreamController.broadcast();
- stream = errorGroup.registerStream(controller.stream);
+ controller = new StreamController();
+ stream = errorGroup.registerStream(controller.stream.asBroadcastStream());
completer = new Completer();
future = errorGroup.registerFuture(completer.future);
});
@@ -408,7 +383,7 @@
expect(future, throwsFormatException);
expect(errorGroup.done, throwsFormatException);
- controller.addError(new AsyncError(new FormatException()));
+ controller.addError(new FormatException());
});
test("should pipe exceptions from the future to the stream", () {
@@ -436,7 +411,7 @@
expect(future.then((_) {
// shouldn't cause a top-level exception
- controller.addError(new AsyncError(new FormatException()));
+ controller.addError(new FormatException());
}), completes);
});
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 3ba46a4..ba04998 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -119,7 +119,7 @@
/// Closes [_server]. Returns a [Future] that will complete after the [_server]
/// is closed.
Future _closeServer() {
- if (_server == null) return new Future.immediate(null);
+ if (_server == null) return new Future.value();
_server.close();
_server = null;
_portCompleterCache = null;
@@ -356,7 +356,7 @@
'--trace'];
dartArgs.addAll(args);
- if (tokenEndpoint == null) tokenEndpoint = new Future.immediate(null);
+ if (tokenEndpoint == null) tokenEndpoint = new Future.value();
var optionsFuture = tokenEndpoint.then((tokenEndpoint) {
var options = new ProcessOptions();
options.workingDirectory = pathInSandbox(appPath);
@@ -588,7 +588,7 @@
return schedule(() {
var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));
- return new Future.of(() {
+ return new Future.sync(() {
var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
return validator.validate().then((_) {
return new Pair(validator.errors, validator.warnings);
diff --git a/utils/tests/pub/validator/dependency_test.dart b/utils/tests/pub/validator/dependency_test.dart
index de4d08e..4001330 100644
--- a/utils/tests/pub/validator/dependency_test.dart
+++ b/utils/tests/pub/validator/dependency_test.dart
@@ -38,9 +38,9 @@
expect(request.url.path, equals("/packages/foo.json"));
if (hostedVersions == null) {
- return new Future.immediate(new http.Response("not found", 404));
+ return new Future.value(new http.Response("not found", 404));
} else {
- return new Future.immediate(new http.Response(json.stringify({
+ return new Future.value(new http.Response(json.stringify({
"name": "foo",
"uploaders": ["nweiz@google.com"],
"versions": hostedVersions
diff --git a/utils/tests/pub/validator/size_test.dart b/utils/tests/pub/validator/size_test.dart
index 47c7d1e..3dd1e21 100644
--- a/utils/tests/pub/validator/size_test.dart
+++ b/utils/tests/pub/validator/size_test.dart
@@ -16,7 +16,7 @@
Function size(int size) {
return (entrypoint) =>
- new SizeValidator(entrypoint, new Future.immediate(size));
+ new SizeValidator(entrypoint, new Future.value(size));
}
main() {
diff --git a/utils/tests/pub/version_solver_test.dart b/utils/tests/pub/version_solver_test.dart
index 94a7c58..845f597 100644
--- a/utils/tests/pub/version_solver_test.dart
+++ b/utils/tests/pub/version_solver_test.dart
@@ -481,11 +481,11 @@
: _packages = <String, Map<Version, Package>>{};
Future<List<Version>> getVersions(String name, String description) {
- return new Future.of(() => _packages[description].keys.toList());
+ return new Future.sync(() => _packages[description].keys.toList());
}
Future<Pubspec> describe(PackageId id) {
- return new Future.of(() => _packages[id.name][id.version].pubspec);
+ return new Future.sync(() => _packages[id.name][id.version].pubspec);
}
Future<bool> install(PackageId id, String path) {
diff --git a/utils/tests/string_encoding/benchmark_runner.dart b/utils/tests/string_encoding/benchmark_runner.dart
index 0463030..f29c4f9 100644
--- a/utils/tests/string_encoding/benchmark_runner.dart
+++ b/utils/tests/string_encoding/benchmark_runner.dart
@@ -168,17 +168,16 @@
}
String _leftAlign(String s, int width) {
- List<int> outCodes = [];
- outCodes.insertRange(0, width, spaceChar);
+ List<int> outCodes = new List<int>.filled(width, spaceChar);
outCodes.setRange(0, Math.min(width, s.length), s.codeUnits);
return new String.fromCharCodes(outCodes);
}
String _rightAlign(String s, int width) {
- List<int> outCodes = [];
- outCodes.insertRange(0, width, spaceChar);
- outCodes.setRange(Math.max(0, width - s.length), Math.min(width, s.length),
- s.codeUnits);
+ List<int> outCodes = new List<int>.filled(width, spaceChar);
+ int fromIndex = Math.max(0, width - s.length);
+ int length = Math.min(width, s.length);
+ outCodes.setRange(fromIndex, fromIndex + length, s.codeUnits);
return new String.fromCharCodes(outCodes);
}