main = main::main;
library from "org-dartlang-test:///lib.dart" as lib {

  import "dart:ffi";

  @#C7
  class Coordinate extends dart.ffi::Struct {
    static final field dart.core::int* #sizeOf = (#C10).{dart.core::List::[]}(dart.ffi::_abi());
    constructor #fromTypedDataBase(dart.core::Object #typedDataBase) → lib::Coordinate
      : super dart.ffi::Struct::_fromTypedDataBase(#typedDataBase)
      ;
    static factory allocate(dart.core::double* x, dart.core::double* y, dart.ffi::Pointer<lib::Coordinate*>* next) → lib::Coordinate* {
      return null;
    }
    abstract member-signature get _typedDataBase() → dart.core::Object*; -> dart.ffi::_Compound::_typedDataBase
    abstract member-signature get _identityHashCode() → dart.core::int*; -> dart.core::Object::_identityHashCode
    abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → dart.core::bool*; -> dart.core::Object::_instanceOf
    abstract member-signature method _simpleInstanceOf(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOf
    abstract member-signature method _simpleInstanceOfTrue(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOfTrue
    abstract member-signature method _simpleInstanceOfFalse(dynamic type) → dart.core::bool*; -> dart.core::Object::_simpleInstanceOfFalse
    abstract member-signature operator ==(dynamic other) → dart.core::bool*; -> dart.core::Object::==
    abstract member-signature get hashCode() → dart.core::int*; -> dart.core::Object::hashCode
    abstract member-signature method toString() → dart.core::String*; -> dart.core::Object::toString
    abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
    abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
    @#C11
    get x() → dart.core::double*
      return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C13).{dart.core::List::[]}(dart.ffi::_abi()));
    set x(dart.core::double* #v) → void
      return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C13).{dart.core::List::[]}(dart.ffi::_abi()), #v);
    @#C11
    get y() → dart.core::double*
      return dart.ffi::_loadDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C15).{dart.core::List::[]}(dart.ffi::_abi()));
    set y(dart.core::double* #v) → void
      return dart.ffi::_storeDouble(this.{dart.ffi::_Compound::_typedDataBase}, (#C15).{dart.core::List::[]}(dart.ffi::_abi()), #v);
    get next() → dart.ffi::Pointer<lib::Coordinate*>*
      return dart.ffi::_fromAddress<lib::Coordinate*>(dart.ffi::_loadIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C17).{dart.core::List::[]}(dart.ffi::_abi())));
    set next(dart.ffi::Pointer<lib::Coordinate*>* #v) → void
      return dart.ffi::_storeIntPtr(this.{dart.ffi::_Compound::_typedDataBase}, (#C17).{dart.core::List::[]}(dart.ffi::_abi()), #v.{dart.ffi::Pointer::address});
  }
}
library from "org-dartlang-test:///main.dart" as main {

  import "org-dartlang-test:///lib.dart";

  static method main() → dynamic {
    lib::Coordinate* coordinate = lib::Coordinate::allocate(42.0, 42.0, null);
    dart.core::print(coordinate.{lib::Coordinate::x});
    dart.core::print(coordinate.{lib::Coordinate::y});
    dart.core::print(coordinate.{lib::Coordinate::next});
    main::done();
  }
  static method done() → dynamic {
    dart.core::print("Done!");
  }
}
constants  {
  #C1 = "vm:ffi:struct-fields"
  #C2 = TypeLiteralConstant(dart.ffi::Double)
  #C3 = TypeLiteralConstant(dart.ffi::Pointer<dart.ffi::NativeType>)
  #C4 = <dart.core::Type>[#C2, #C2, #C3]
  #C5 = null
  #C6 = dart.ffi::_FfiStructLayout {fieldTypes:#C4, packing:#C5}
  #C7 = dart.core::pragma {name:#C1, options:#C6}
  #C8 = 24
  #C9 = 20
  #C10 = <dart.core::int*>[#C8, #C9, #C8]
  #C11 = dart.ffi::Double {}
  #C12 = 0
  #C13 = <dart.core::int*>[#C12, #C12, #C12]
  #C14 = 8
  #C15 = <dart.core::int*>[#C14, #C14, #C14]
  #C16 = 16
  #C17 = <dart.core::int*>[#C16, #C16, #C16]
}
