| // 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(); |
| } |