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

class Number extends core::Object {
  final field core::int value;
  constructor •(core::int value) → self::Number
    ;
  get hashCode() → core::int
    ;
  operator ==(core::Object other) → core::bool
    ;
  method toString() → core::String
    ;
}
class Class extends core::Object {
  field self::Number field;
  constructor •(self::Number field) → self::Class
    ;
}
class IntClass extends core::Object {
  field core::int field;
  constructor •(core::int field) → self::IntClass
    ;
}
extension NumberExtension on self::Number {
  operator + = self::NumberExtension|+;
  operator - = self::NumberExtension|-;
}
extension ClassExtension on self::Class {
  get property = self::ClassExtension|get#property;
  set property = self::ClassExtension|set#property;
  method testImplicitProperties = self::ClassExtension|testImplicitProperties;
  method tearoff testImplicitProperties = self::ClassExtension|get#testImplicitProperties;
}
extension IntClassExtension on self::IntClass {
  get property = self::IntClassExtension|get#property;
  set property = self::IntClassExtension|set#property;
  method testImplicitProperties = self::IntClassExtension|testImplicitProperties;
  method tearoff testImplicitProperties = self::IntClassExtension|get#testImplicitProperties;
}
static extension-member method NumberExtension|+(lowered final self::Number #this, core::Object other) → self::Number
  ;
static extension-member method NumberExtension|-(lowered final self::Number #this, core::Object other) → self::Number
  ;
static extension-member method ClassExtension|get#property(lowered final self::Class #this) → self::Number
  ;
static extension-member method ClassExtension|set#property(lowered final self::Class #this, self::Number value) → void
  ;
static extension-member method ClassExtension|testImplicitProperties(lowered final self::Class #this) → dynamic
  ;
static extension-member method ClassExtension|get#testImplicitProperties(lowered final self::Class #this) → () → dynamic
  return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
static extension-member method IntClassExtension|get#property(lowered final self::IntClass #this) → core::int
  ;
static extension-member method IntClassExtension|set#property(lowered final self::IntClass #this, core::int value) → void
  ;
static extension-member method IntClassExtension|testImplicitProperties(lowered final self::IntClass #this) → dynamic
  ;
static extension-member method IntClassExtension|get#testImplicitProperties(lowered final self::IntClass #this) → () → dynamic
  return () → dynamic => self::IntClassExtension|testImplicitProperties(#this);
static method main() → dynamic
  ;
static method testLocals() → dynamic
  ;
static method testProperties() → dynamic
  ;
static method testIntProperties() → dynamic
  ;
static method testExplicitProperties() → dynamic
  ;
static method testExplicitIntProperties() → dynamic
  ;
static method testExplicitNullAwareProperties(self::Class? v) → dynamic
  ;
static method testExplicitNullAwareIntProperties(self::IntClass? v) → dynamic
  ;
static method expect(dynamic expected, dynamic actual, [has-declared-initializer dynamic expectNull]) → dynamic
  ;
