library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
//  - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
//       print(onlySetter);
//             ^^^^^^^^^^
//
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
//  - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
//     print(onlySetter);
//           ^^^^^^^^^^
//
// pkg/front_end/testcases/general/accessors.dart:40:11: Error: Getter not found: 'onlySetter'.
//     print(onlySetter);
//           ^^^^^^^^^^
//
import self as self;
import "dart:core" as core;

class C extends core::Object {
  synthetic constructor •() → self::C
    : super core::Object::•()
    ;
  set onlySetter(dynamic value) → void {
    core::print("C.onlySetter called with ${value}.");
  }
  method testC() → dynamic {
    try {
      core::print(invalid-expression "pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
 - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
      print(onlySetter);
            ^^^^^^^^^^" in this{<unresolved>}.onlySetter);
      throw "No error thrown";
    }
    on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
      core::print("Expected error: ${e}");
    }
    this.{self::C::onlySetter} = "hest";
  }
  method testD() → dynamic {
    core::print(invalid-expression "pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
 - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
    print(onlySetter);
          ^^^^^^^^^^" in this{<unresolved>}.onlySetter);
    this.{self::C::onlySetter} = "hest";
  }
}
class D extends self::C {
  synthetic constructor •() → self::D
    : super self::C::•()
    ;
  get onlySetter() → core::String
    return "D.onlySetter called.";
  set onlySetter(dynamic value) → void {
    core::print("D.onlySetter called with ${value}.");
  }
}
static set onlySetter(dynamic value) → void {
  core::print("onlySetter called with ${value}.");
}
static method main() → dynamic {
  try {
    core::print(invalid-expression "pkg/front_end/testcases/general/accessors.dart:40:11: Error: Getter not found: 'onlySetter'.
    print(onlySetter);
          ^^^^^^^^^^");
    throw "No error thrown";
  }
  on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
    core::print("Expected error: ${e}");
  }
  self::onlySetter = "fisk";
  new self::C::•().{self::C::testC}(){() → dynamic};
  new self::D::•().{self::C::testD}(){() → dynamic};
}
