blob: da1f458e629a349abbc301c5a1220e2d313d601d [file] [log] [blame]
// Copyright (c) 2018, 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.
// This test carefully reproduces subtle situation when TFA fails to converge
// unless result types are saturated.
// * There is a loop in dependencies (or even multiple loops).
// * There is a recursive invocation which may result in a type approximation.
// * Invalidation of results of certain invocations cause types to bounce
// between approximated and non-approximated results, causing more
// self-induced invalidations.
//
class StreamSubscription {}
class _BufferingStreamSubscription extends StreamSubscription {}
class _BroadcastSubscription extends StreamSubscription {}
abstract class Stream {
StreamSubscription foobar(void onData(event), {Function onError});
}
abstract class _StreamImpl extends Stream {
StreamSubscription foobar(void onData(data), {Function onError}) {
return _createSubscription();
}
StreamSubscription _createSubscription() {
return new _BufferingStreamSubscription();
}
}
class _ControllerStream extends _StreamImpl {
StreamSubscription _createSubscription() {
return new _BroadcastSubscription();
}
}
class _GeneratedStreamImpl extends _StreamImpl {}
class StreamView extends Stream {
final Stream _stream;
StreamView(Stream stream) : _stream = stream;
StreamSubscription foobar(void onData(value), {Function onError}) {
return _stream.foobar(onData, onError: onError);
}
}
class ByteStream extends StreamView {
ByteStream(Stream stream) : super(stream);
super_foobar1(void onData(value)) {
super.foobar(onData);
}
super_foobar2(void onData(value)) {
super.foobar(onData);
}
super_foobar3({void onData(value), Function onError}) {
super.foobar(onData, onError: onError);
}
Stream get super_stream => super._stream;
}
class _HandleErrorStream extends Stream {
StreamSubscription foobar(void onData(event), {Function onError}) {
return new _BufferingStreamSubscription();
}
}
void round0() {
new ByteStream(new ByteStream(new _GeneratedStreamImpl()));
}
void round1({void onData(value)}) {
var x = new ByteStream(new ByteStream(new _GeneratedStreamImpl()));
x.super_foobar1(onData);
}
void round2({void onData(value), Function onError}) {
new _ControllerStream();
Stream x = new _GeneratedStreamImpl();
x = new ByteStream(x);
x.foobar(onData, onError: onError);
}
void round3({void onData(value), Function onError}) {
Stream x = new _GeneratedStreamImpl();
x = new ByteStream(x);
x = new _ControllerStream();
x.foobar(onData, onError: onError);
}
void round4({void onData(value)}) {
var x = new ByteStream(new _ControllerStream());
var y = x.super_stream;
var z = x._stream;
if (y == z) {
x.super_foobar2(onData);
}
}
void round5() {
var x = new ByteStream(new _GeneratedStreamImpl());
new _HandleErrorStream();
x.super_foobar3();
}
main(List<String> args) {
new _GeneratedStreamImpl();
round0();
round1();
round2();
round3();
round4();
round5();
}