library;
import self as self;
import "dart:core" as core;
import "dart:async" as asy;

typedef MyMixinTypedef = self::MyMixin<core::String, self::MyWidget>;
class State<T extends self::StatefulWidget> extends core::Object {
  synthetic constructor •() → self::State<self::State::T>
    : super core::Object::•()
    ;
}
class StatefulWidget extends core::Object {
  synthetic constructor •() → self::StatefulWidget
    : super core::Object::•()
    ;
}
abstract class MyMixin<T extends core::Object? = dynamic, W extends self::StatefulWidget> extends self::State<self::MyMixin::W> /*isMixinDeclaration*/  {
  method listenToEvents(covariant-by-class asy::Stream<self::MyModel<self::MyMixin::T%>> stream) → void {
    stream.{asy::Stream::listen}((self::MyModel<self::MyMixin::T%> event) → void {}){((self::MyModel<self::MyMixin::T%>) →? void, {cancelOnError: core::bool?, onDone: () →? void, onError: core::Function?}) → asy::StreamSubscription<self::MyModel<self::MyMixin::T%>>};
  }
}
class MyModel<T extends core::Object? = dynamic> extends core::Object {
  final field self::MyModel::T% data;
  constructor •(initializing-formal self::MyModel::T% data) → self::MyModel<self::MyModel::T%>
    : self::MyModel::data = data, super core::Object::•()
    ;
}
class MyWidget extends self::StatefulWidget {
  synthetic constructor •() → self::MyWidget
    : super self::StatefulWidget::•()
    ;
}
class MyWidgetState1 extends self::_MyWidgetState1&State&MyMixin {
  synthetic constructor •() → self::MyWidgetState1
    : super self::_MyWidgetState1&State&MyMixin::•()
    ;
  method doSomething() → void {
    this.{self::_MyWidgetState1&State&MyMixin::listenToEvents}(asy::Stream::value<self::MyModel<core::String>>(new self::MyModel::•<core::String>("foo"))){(asy::Stream<self::MyModel<core::String>>) → void};
  }
}
class MyWidgetState2 extends self::_MyWidgetState2&State&MyMixinTypedef {
  synthetic constructor •() → self::MyWidgetState2
    : super self::_MyWidgetState2&State&MyMixinTypedef::•()
    ;
  method doSomething() → void {
    this.{self::_MyWidgetState2&State&MyMixinTypedef::listenToEvents}(asy::Stream::value<self::MyModel<core::String>>(new self::MyModel::•<core::String>("foo"))){(asy::Stream<self::MyModel<core::String>>) → void};
  }
}
abstract class _MyWidgetState1&State&MyMixin = self::State<self::MyWidget> with self::MyMixin<core::String, self::MyWidget> /*isAnonymousMixin*/  {
  synthetic constructor •() → self::_MyWidgetState1&State&MyMixin
    : super self::State::•()
    ;
  synthetic mixin-super-stub method listenToEvents(covariant-by-class asy::Stream<self::MyModel<core::String>> stream) → void
    return super.{self::MyMixin::listenToEvents}(stream);
}
abstract class _MyWidgetState2&State&MyMixinTypedef = self::State<self::MyWidget> with self::MyMixin<core::String, self::MyWidget> /*isAnonymousMixin*/  {
  synthetic constructor •() → self::_MyWidgetState2&State&MyMixinTypedef
    : super self::State::•()
    ;
  synthetic mixin-super-stub method listenToEvents(covariant-by-class asy::Stream<self::MyModel<core::String>> stream) → void
    return super.{self::MyMixin::listenToEvents}(stream);
}
