module FFI module Type class Builtin end class Mapped end end class AbstractMemory def get_array_of_string: (::Integer, ::Integer) -> Array[String] def read_bytes: (::Integer) -> ::String end class Pointer < AbstractMemory NULL: Pointer def null?: () -> bool end class MemoryPointer < Pointer def self.from_string: (::String) -> MemoryPointer end class Enum end class Union def self.layout: (*(Symbol | Integer)) -> void end type union = top # TODO: handle user-defined unions class Struct # TODO: layout args are actually "Symbol | Union, Integer, *(Symbol | Union, Integer)" def self.layout: (*(Symbol | Integer | union)) -> void def self.by_ref: () -> Type::Mapped def self.size: () -> Integer def null?: () -> bool def initialize: (?Pointer) -> void def []: (Symbol) -> untyped def []=: (Symbol, untyped) -> untyped def pointer: () -> Pointer end class Function < Pointer end module Library # these can be worked around by typedef'ing to a Symbol type enum = top # TODO: handle user-defined enum constants type ref = top # TODO: handle by_ref references type typedef = top # TODO: handle non-builtin types def ffi_lib: (Array[String]) -> void def typedef: (ref | Symbol, Symbol) -> (Type::Builtin | Type::Mapped | typedef) def attach_function: (Symbol, Array[Symbol | Struct | enum], Symbol | Enum, ?blocking: bool) -> Function def callback: (Symbol, Array[Symbol | Enum | Struct], Symbol | Enum) -> Function def enum: (*untyped) -> Enum end end