Version 1.10.0-dev.1.1
svn merge -c 45056 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45064 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45069 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 45071 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@45089 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index dac2bb5..58240c5 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/asserts.dart' as asserts;
+import 'package:path/path.dart' as pathos;
/**
* A [UriResolver] implementation for the `package:` scheme that uses a map of
@@ -78,17 +79,19 @@
String sourcePath = source.fullName;
Uri bestMatch;
int bestMatchLength = -1;
+ pathos.Context pathContext = resourceProvider.pathContext;
for (String pkgName in packageMap.keys) {
List<Folder> pkgFolders = packageMap[pkgName];
for (int i = 0; i < pkgFolders.length; i++) {
Folder pkgFolder = pkgFolders[i];
String pkgFolderPath = pkgFolder.path;
- // TODO(paulberry): figure out the right thing to do for Windows.
if (pkgFolderPath.length > bestMatchLength &&
- sourcePath.startsWith(pkgFolderPath + '/')) {
+ sourcePath.startsWith(pkgFolderPath + pathContext.separator)) {
String relPath = sourcePath.substring(pkgFolderPath.length + 1);
if (_isReversibleTranslation(pkgFolders, i, relPath)) {
- bestMatch = Uri.parse('$PACKAGE_SCHEME:$pkgName/$relPath');
+ List<String> relPathComponents = pathContext.split(relPath);
+ String relUriPath = pathos.posix.joinAll(relPathComponents);
+ bestMatch = Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
bestMatchLength = pkgFolderPath.length;
}
}
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 6ed6817..e4b0bb6 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -176,7 +176,7 @@
}
}
- void test_restoreAmbiguous() {
+ void test_restoreAbsolute_ambiguous() {
const file1 = '/foo1/lib/bar.dart';
const file2 = '/foo2/lib/bar.dart';
provider.newFile(file1, 'library bar');
@@ -200,7 +200,7 @@
expect(resolver.restoreAbsolute(source2), isNull);
}
- void test_restoreLongestMatch() {
+ void test_restoreAbsolute_longestMatch() {
const file1 = '/foo1/bar1/lib.dart';
const file2 = '/foo2/bar2/lib.dart';
provider.newFile(file1, 'library lib');
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 3350684..6f3d3fa2 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -328,6 +328,7 @@
new OptionHandler('--package-root=.+|-p.+', setPackageRoot),
new OptionHandler('--analyze-all', setAnalyzeAll),
new OptionHandler('--analyze-only', setAnalyzeOnly),
+ new OptionHandler('--no-source-maps', passThrough),
new OptionHandler('--analyze-signatures-only', setAnalyzeOnly),
new OptionHandler('--disable-native-live-type-analysis', passThrough),
new OptionHandler('--categories=.*', setCategories),
@@ -582,6 +583,9 @@
Disables dynamic generation of code in the generated output. This is
necessary to satisfy CSP restrictions (see http://www.w3.org/TR/CSP/).
+ --no-source-maps
+ Do not generate a source map file.
+
The following options are only used for compiler development and may
be removed in a future version:
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 3572ff4..dc22368 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -196,7 +196,9 @@
for (Element element in backend.generatedCode.keys) {
if (backend.isAccessibleByReflection(element)) {
bool shouldRetainMetadata = backend.retainMetadataOf(element);
- if (shouldRetainMetadata && element.isFunction) {
+ if (shouldRetainMetadata &&
+ (element.isFunction || element.isConstructor ||
+ element.isSetter)) {
FunctionElement function = element;
function.functionSignature.forEachParameter(
backend.retainMetadataOf);
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
index 163833b..2248dc6 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
@@ -3642,10 +3642,11 @@
future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
async_error_codes.SUCCESS),
onError: (dynamic error, StackTrace stackTrace) {
- ExceptionAndStackTrace wrapped =
+ ExceptionAndStackTrace wrappedException =
new ExceptionAndStackTrace(error, stackTrace);
- return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
- async_error_codes.ERROR)(wrapped);
+ Function wrapped =_wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
+ async_error_codes.ERROR);
+ wrapped(wrappedException);
});
return completer.future;
}
@@ -3714,7 +3715,7 @@
AsyncStarStreamController controller) {
if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
// This happens on return from the async* function.
- if (controller.cancelationCompleter != null) {
+ if (controller.isCanceled) {
controller.cancelationCompleter.complete();
} else {
controller.close();
@@ -3722,7 +3723,7 @@
return;
} else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
// The error is a js-error.
- if (controller.cancelationCompleter != null) {
+ if (controller.isCanceled) {
controller.cancelationCompleter.completeError(
unwrapException(object),
getTraceFromException(object));
@@ -3735,34 +3736,44 @@
}
if (object is IterationMarker) {
- if (controller.cancelationCompleter != null) {
- _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
- async_error_codes.STREAM_WAS_CANCELED)(null);
+ if (controller.isCanceled) {
+ Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
+ async_error_codes.STREAM_WAS_CANCELED);
+ wrapped(null);
return;
}
if (object.state == IterationMarker.YIELD_SINGLE) {
controller.add(object.value);
- // If the controller is paused we stop producing more values.
- if (controller.isPaused) {
- return;
- }
- // TODO(sigurdm): We should not suspend here according to the spec.
+
scheduleMicrotask(() {
- _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
- async_error_codes.SUCCESS)
- (null);
+ if (controller.isPaused) {
+ // We only suspend the thread inside the microtask in order to allow
+ // listeners on the output stream to pause in response to the just
+ // output value, and have the stream immediately stop producing.
+ controller.isSuspended = true;
+ return;
+ }
+ Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
+ async_error_codes.SUCCESS);
+ wrapped(null);
});
return;
} else if (object.state == IterationMarker.YIELD_STAR) {
Stream stream = object.value;
- controller.isAdding = true;
// Errors of [stream] are passed though to the main stream. (see
- // [AsyncStreamController.addStream].
+ // [AsyncStreamController.addStream]).
// TODO(sigurdm): The spec is not very clear here. Clarify with Gilad.
controller.addStream(stream).then((_) {
- controller.isAdding = false;
- _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
- async_error_codes.SUCCESS)(null);
+ // No check for isPaused here because the spec 17.16.2 only
+ // demands checks *before* each element in [stream] not after the last
+ // one. On the other hand we check for isCanceled, as that check happens
+ // after insertion of each element.
+ int errorCode = controller.isCanceled
+ ? async_error_codes.STREAM_WAS_CANCELED
+ : async_error_codes.SUCCESS;
+ Function wrapped = _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
+ errorCode);
+ wrapped(null);
});
return;
}
@@ -3772,11 +3783,11 @@
future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
async_error_codes.SUCCESS),
onError: (error, StackTrace stackTrace) {
- ExceptionAndStackTrace wrapped =
+ ExceptionAndStackTrace wrappedException =
new ExceptionAndStackTrace(error, stackTrace);
- return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
- async_error_codes.ERROR)
- (wrapped);
+ Function wrapped = _wrapJsFunctionForAsync(
+ bodyFunctionOrErrorCode, async_error_codes.ERROR);
+ return wrapped(wrappedException);
});
}
@@ -3784,46 +3795,79 @@
return controller.stream;
}
-/// A wrapper around a [StreamController] that remembers if that controller
-/// got a cancel.
+/// A wrapper around a [StreamController] that keeps track of the state of
+/// the execution of an async* function.
+/// It can be in 1 of 3 states:
///
-/// Also has a subSubscription that when not null will provide events for the
-/// stream, and will be paused and resumed along with this controller.
+/// - running/scheduled
+/// - suspended
+/// - canceled
+///
+/// If yielding while the subscription is paused it will become suspended. And
+/// only resume after the subscription is resumed or canceled.
class AsyncStarStreamController {
StreamController controller;
Stream get stream => controller.stream;
+
+ /// True when the async* function has yielded while being paused.
+ /// When true execution will only resume after a `onResume` or `onCancel`
+ /// event.
+ bool isSuspended = false;
+
+ bool get isPaused => controller.isPaused;
+
Completer cancelationCompleter = null;
+
+ /// True after the StreamSubscription has been cancelled.
+ /// When this is true, errors thrown from the async* body should go to the
+ /// [cancelationCompleter] instead of adding them to [controller], and
+ /// returning from the async function should complete [cancelationCompleter].
bool get isCanceled => cancelationCompleter != null;
- bool isAdding = false;
- bool isPaused = false;
+
add(event) => controller.add(event);
+
addStream(Stream stream) {
return controller.addStream(stream, cancelOnError: false);
}
+
addError(error, stackTrace) => controller.addError(error, stackTrace);
+
close() => controller.close();
AsyncStarStreamController(body) {
+
+ _resumeBody() {
+ scheduleMicrotask(() {
+ Function wrapped =
+ _wrapJsFunctionForAsync(body, async_error_codes.SUCCESS);
+ wrapped(null);
+ });
+ }
+
controller = new StreamController(
onListen: () {
- scheduleMicrotask(() {
- Function wrapped = _wrapJsFunctionForAsync(body,
- async_error_codes.SUCCESS);
- wrapped(null);
- });
- },
- onPause: () {
- isPaused = true;
+ _resumeBody();
}, onResume: () {
- isPaused = false;
- if (!isAdding) {
- asyncStarHelper(null, body, this);
+ // Only schedule again if the async* function actually is suspended.
+ // Resume directly instead of scheduling, so that the sequence
+ // `pause-resume-pause` will result in one extra event produced.
+ if (isSuspended) {
+ isSuspended = false;
+ _resumeBody();
}
}, onCancel: () {
+ // If the async* is finished we ignore cancel events.
if (!controller.isClosed) {
cancelationCompleter = new Completer();
- if (isPaused) asyncStarHelper(null, body, this);
-
+ if (isSuspended) {
+ // Resume the suspended async* function to run finalizers.
+ isSuspended = false;
+ scheduleMicrotask(() {
+ Function wrapped =_wrapJsFunctionForAsync(body,
+ async_error_codes.STREAM_WAS_CANCELED);
+ wrapped(null);
+ });
+ }
return cancelationCompleter.future;
}
});
diff --git a/tests/language/async_star_regression_23116_test.dart b/tests/language/async_star_regression_23116_test.dart
new file mode 100644
index 0000000..d1c6390
--- /dev/null
+++ b/tests/language/async_star_regression_23116_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for https://code.google.com/p/dart/issues/detail?id=23116
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import 'dart:async';
+
+Stream<int> foo(Completer completer, Future future) async* {
+ completer.complete(100);
+ int x = await future;
+ Expect.equals(42, x);
+}
+
+test() async {
+ Completer completer1 = new Completer();
+ Completer completer2 = new Completer();
+ StreamSubscription s = foo(completer1, completer2.future).listen((v) => null);
+ await completer1.future;
+ // At this moment foo is waiting on the given future.
+ s.pause();
+ // Ensure that execution of foo is not resumed - the future is not completed
+ // yet.
+ s.resume();
+ completer2.complete(42);
+}
+
+main() {
+ asyncStart();
+ test().then((_) => asyncEnd());
+}
diff --git a/tests/lib/mirrors/parameter_annotation_mirror_test.dart b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
index 1b2a451..be104e4 100644
--- a/tests/lib/mirrors/parameter_annotation_mirror_test.dart
+++ b/tests/lib/mirrors/parameter_annotation_mirror_test.dart
@@ -13,6 +13,11 @@
}
class Foo {
+ Foo(@ParameterAnnotation("vogel") p) {}
+ Foo.named(@ParameterAnnotation("hamster") p) {}
+ Foo.named2(@ParameterAnnotation("hamster") p,
+ @ParameterAnnotation("wurm") p2) {}
+
f1(@ParameterAnnotation("hest") p) {}
f2(@ParameterAnnotation("hest") @ParameterAnnotation("fisk") p) {}
f3(a, @ParameterAnnotation("fugl") p) {}
@@ -22,6 +27,8 @@
[@ParameterAnnotation("hval") p]) {}
f6({@ParameterAnnotation("fisk") z,
@ParameterAnnotation("hval") p}) {}
+
+ set s1(@ParameterAnnotation("cheval") p) {}
}
expectAnnotations(Type type, Symbol method, int parameterIndex,
@@ -39,6 +46,11 @@
}
main() {
+ expectAnnotations(Foo, #Foo, 0, ["vogel"]);
+ expectAnnotations(Foo, #Foo.named, 0, ["hamster"]);
+ expectAnnotations(Foo, #Foo.named2, 0, ["hamster"]);
+ expectAnnotations(Foo, #Foo.named2, 1, ["wurm"]);
+
expectAnnotations(Foo, #f1, 0, ["hest"]);
expectAnnotations(Foo, #f2, 0, ["hest", "fisk"]);
expectAnnotations(Foo, #f3, 0, []);
@@ -49,4 +61,6 @@
expectAnnotations(Foo, #f5, 1, ["hval"]);
expectAnnotations(Foo, #f6, 0, ["fisk"]);
expectAnnotations(Foo, #f6, 1, ["hval"]);
+
+ expectAnnotations(Foo, const Symbol('s1='), 0, ["cheval"]);
}
diff --git a/tools/VERSION b/tools/VERSION
index 0476332..c7af623 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 10
PATCH 0
PRERELEASE 1
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1