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

abstract class M extends core::Object /*isMixinDeclaration*/  {
  field dynamic m = null;
}
abstract class N extends self::M /*isMixinDeclaration*/  {
  set superM(dynamic value) → void {
    super.{self::M::m} = value;
  }
  get superM() → dynamic
    return super.{self::M::m};
}
class S extends core::Object {
  synthetic constructor •() → self::S
    : super core::Object::•()
    ;
}
abstract class _Named&S&M extends self::S implements self::M /*isAnonymousMixin,isEliminatedMixin*/  {
  field dynamic m = null;
  synthetic constructor •() → self::_Named&S&M
    : super self::S::•()
    ;
}
abstract class _Named&S&M&N extends self::_Named&S&M implements self::N /*isAnonymousMixin,isEliminatedMixin*/  {
  synthetic constructor •() → self::_Named&S&M&N
    : super self::_Named&S&M::•()
    ;
  get superM() → dynamic
    return super.{self::M::m};
  set superM(dynamic value) → void {
    super.{self::M::m} = value;
  }
}
class Named extends self::_Named&S&M&N implements self::M /*isEliminatedMixin*/  {
  field dynamic m = null;
  synthetic constructor •() → self::Named
    : super self::_Named&S&M&N::•()
    ;
}
static method main() → dynamic {
  self::Named named = new self::Named::•();
  named.{self::Named::m} = 42;
  named.{self::_Named&S&M&N::superM} = 87;
  if(!(named.{self::Named::m}{dynamic} =={core::Object::==}{(core::Object) → core::bool} 42)) {
    throw "Bad mixin translation of set:superM";
  }
  if(!(named.{self::_Named&S&M&N::superM}{dynamic} =={core::Object::==}{(core::Object) → core::bool} 87)) {
    throw "Bad mixin translation of get:superM";
  }
}
