typemap

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package typemap resolves ObjC qualType strings to their Go equivalents.

Mapper is the central resolver. Its Mapper.GoType method accepts a raw ObjC type string (e.g. "NSArray<NSString *> *") and a Context describing the declaration being emitted, and returns the corresponding Go type string (e.g. "*foundation.NSArray[*foundation.NSString]").

Resolution handles:

  • Primitives and ObjC integer aliases (NSInteger → int64, BOOL → bool).
  • Class references, with cross-framework import tracking as a side effect (discovered imports are collected in the caller-supplied ImportSet).
  • Generic type parameters (ObjectType on NSArray[T] → T).
  • Protocol references ("id<Protocol>" → interface type).
  • Enum and struct references, resolved to their owning framework package.
  • ObjC block signatures, converted to Go func types.
  • One-level typedef expansion for otherwise-unrecognised type names.
  • CoreFoundation opaque pointer types (CFArrayRef, etc.).

When a cross-framework reference cannot be emitted (because the import would introduce a cycle), Mapper substitutes unsafe.Pointer and records a diagnostic. The set of blocked imports is computed by the pipeline before generation begins and supplied via Mapper.BlockedImports.

Results are cached by a key composed of the normalised qualType and the relevant Context fields, with side effects (import additions) replayed on cache hits.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BSDStructCNames

func BSDStructCNames() []string

BSDStructCNames returns the set of C struct names that map to types in the bsd package. Used by the loader to pre-register these names in StructIndex.

func ClassName

func ClassName(qt string) string

ClassName extracts "NSString" from "NSString *" or "NSString * _Nullable". Returns empty string if the type does not look like a named ObjC object.

func GenericParam

func GenericParam(qt string) string

GenericParam extracts the first type parameter from a generic type string. E.g. "NSArray<ObjectType> *" → "ObjectType". Returns empty if no generic param is present. Use GenericParams for multi-parameter generics like NSDictionary<KeyType, ObjectType>.

func GenericParams

func GenericParams(qt string) []string

GenericParams extracts all type parameters from a generic type string. E.g. "NSDictionary<KeyType, ObjectType> *" → ["KeyType", "ObjectType"]. Returns nil if no generic params are present.

func IDProtocols

func IDProtocols(qt string) []string

IDProtocols extracts the ordered list of protocol names from a `id<P1, P2>` type expression. Returns nil for any input that is not exactly an `id<...>` form (bare `id`, `NSString *`, blocks, etc.). The returned names are trimmed of whitespace.

"id<VZGraphicsDisplayObserver>"           → ["VZGraphicsDisplayObserver"]
"id<NSCopying, NSSecureCoding> _Nullable" → ["NSCopying", "NSSecureCoding"]
"id"                                      → nil
"NSString *"                              → nil

func IsBOOL

func IsBOOL(qt string) bool

IsBOOL returns true for the ObjC BOOL type.

func IsBOOLPointer

func IsBOOLPointer(qt string) bool

IsBOOLPointer returns true for "BOOL *" — a pointer-to-BOOL used as an in-out stop flag in ObjC enumeration block callbacks.

func IsBlock

func IsBlock(qt string) bool

IsBlock returns true for ObjC block types: returnType (^)(args) or returnType (^ _Nonnull)(args) etc. Checks for the caret introducer only; qualifiers between ^ and ) are ignored.

func IsClass

func IsClass(qt string) bool

IsClass returns true for the ObjC `Class` meta-object type.

func IsCoreFoundationOpaqueRef

func IsCoreFoundationOpaqueRef(name string) bool

IsCoreFoundationOpaqueRef reports whether name is one of the well-known CoreFoundation opaque-pointer typedefs (CFStringRef, CFArrayRef, …) that the type mapper routes to *corefoundation.<Name>. Exposed so the pipeline can attribute these typedefs to CoreFoundation in cycle detection.

func IsDoublePointer

func IsDoublePointer(qt string) bool

IsDoublePointer returns true for NSError ** and similar out-param patterns. Generic type parameters like NSArray<NSString *> are NOT double pointers — the inner asterisk is part of the element type, not an extra indirection level. We only count asterisks that appear after the last closing angle bracket.

func IsID

func IsID(qt string) bool

IsID returns true for bare `id` (any object).

func IsInstancetype

func IsInstancetype(qt string) bool

IsInstancetype returns true for the special ObjC instancetype return.

func IsNSError

func IsNSError(qt string) bool

IsNSError returns true for the canonical ObjC error type NSError *.

func IsPointer

func IsPointer(qt string) bool

IsPointer returns true if the (normalised) type is a pointer.

func IsSEL

func IsSEL(qt string) bool

IsSEL returns true for ObjC selectors.

func IsStructCType

func IsStructCType(qt string) bool

IsStructCType reports whether the ObjC/C type name (after normalisation) is a known value-type struct that requires special bridge handling.

func IsVoid

func IsVoid(qt string) bool

IsVoid returns true for the void type (no return value).

func Normalise

func Normalise(qt string) string

Normalise strips GNU __attribute__((...)) constructs, ObjC attribute macros, nullability qualifiers, leading const/volatile, and normalises whitespace.

func NormaliseBlock

func NormaliseBlock(qt string) string

NormaliseBlock strips ObjC attribute macros, GNU __attribute__((...)) constructs, and nullability qualifiers but preserves const/volatile, so that block casts remain compatible with parameters that have const-qualified argument types.

func ParseBlock

func ParseBlock(qt string) (string, []string, bool)

ParseBlock parses a block type string into its return type and argument types. Returns (returnType, []argTypes, ok).

Types

type Context

type Context struct {
	// ClassName is the ObjC class being processed (resolves instancetype).
	ClassName string
	// Framework is the framework being generated (e.g. "Foundation").
	Framework string
	// ClassNameIndex is the set of ObjC class names visible in the current framework.
	ClassNameIndex map[string]bool
	// GenericParams are the generic type parameter names of the current class
	// (e.g. ["ObjectType", "KeyType"] for NSDictionary). Set per-class by emitters.
	GenericParams []string
	// IsReturn indicates this type is in a return-value position.
	IsReturn bool
	// IsClassMethod indicates the type is being resolved for a class method (+method).
	// Class methods have no receiver [T] in scope, so generic type parameters must
	// be replaced with objc.Object rather than T.
	IsClassMethod bool
}

Context carries the per-call state for a single GoType resolution. Stable, run-wide data (OwnerIndex, EnumIndex, …) lives on the Mapper; only fields that vary between individual method/argument resolutions belong here.

type ImportSet

type ImportSet map[string]string

ImportSet is populated as a side effect of type resolution. It maps Go package alias → full import path for cross-framework references. Pass a non-nil ImportSet to GoType/GoReturnType/CType to collect imports.

type Mapper

type Mapper struct {
	// GenericClasses is the set of class names that use Go generics.
	GenericClasses map[string]bool
	// GenericParamIndex maps a generic class name to its ordered list of ObjC
	// generic type parameter names. See Context.GenericParamIndex.
	GenericParamIndex map[string][]string
	// OwnerIndex maps class name → owning framework name.
	// Used to qualify cross-framework type references (e.g. *foundation.NSString).
	OwnerIndex map[string]string
	// EnumIndex maps enum type name → owning framework.
	// Used to resolve enum return types to their Go equivalents.
	EnumIndex map[string]string
	// EnumGoTypeIndex maps enum type name → underlying Go integer type (e.g. "int64").
	// Used by CType() and bridge emitters to produce correct C casts for enum arguments.
	EnumGoTypeIndex map[string]string
	// TypedefIndex maps typedef name → target ObjC qualType.
	// Used as a last-resort fallback before degrading to unsafe.Pointer.
	TypedefIndex map[string]string
	// StructIndex maps struct name → owning framework. See Context.StructIndex.
	StructIndex map[string]string
	// CFTypeIndex maps framework-specific CF opaque typedef names to their
	// owning framework (e.g. "CFHTTPMessageRef" → "CFNetwork"). These are CF-style
	// reference types generated outside CoreFoundation and not in cfTypedefSet.
	CFTypeIndex map[string]string
	// ProtocolIndex maps protocol name → owning framework. See Context.ProtocolIndex.
	ProtocolIndex map[string]string
	// ProtocolProxyIndex maps protocol name → owning framework.
	// When non-empty, return-position id<Protocol> for a single known protocol
	// resolves to *<GoProtoName>IDProtocol instead of unsafe.Pointer.
	ProtocolProxyIndex map[string]string
	// ModulePrefix is the Go module import path prefix for framework packages.
	ModulePrefix string
	// BlockedImports maps sourceFramework → set of targetFrameworks whose concrete
	// types must not be referenced. When a type resolution would produce a cross-
	// framework reference into a blocked target, unsafe.Pointer is emitted instead.
	// This breaks import cycles detected before code generation begins.
	BlockedImports map[string]map[string]bool

	// Diagnostics accumulates a record every time a type degrades to unsafe.Pointer
	// due to a blocked import cycle or an unresolvable cross-framework reference.
	// The generator can print these under --verbose to help diagnose missing types.
	Diagnostics []string

	// IsNSStringOverloads enables generation of additional Go-string overloads for
	// methods that accept NSString * parameters. Each such method gets a companion
	// with a "Go" suffix where NSString * args become plain Go string args.
	IsNSStringOverloads bool
	// contains filtered or unexported fields
}

Mapper converts ObjC qualType strings to Go type strings.

func New

func New() *Mapper

New returns a Mapper.

func (*Mapper) BaseContext

func (m *Mapper) BaseContext(framework string, knownClasses map[string]bool) Context

BaseContext returns a Context pre-populated with the per-call fields. Stable, run-wide data (OwnerIndex, EnumIndex, etc.) is read directly from the Mapper by resolution methods — callers need not set it on Context.

func (*Mapper) BlockedImportNote

func (m *Mapper) BlockedImportNote(qt string, ctx Context) string

BlockedImportNote returns a comment string when the ObjC type qt would be replaced with unsafe.Pointer due to an import cycle. Returns "" otherwise. Intended for use by emitters to annotate generated code.

func (*Mapper) CType

func (m *Mapper) CType(qt string, ctx Context, imports ImportSet) string

CType returns the C type for a bridge function parameter/return. This is what appears in the generated .h file.

func (*Mapper) EnumGoIntType

func (m *Mapper) EnumGoIntType(goType string) string

EnumGoIntType returns the underlying Go integer type (e.g. "int64") for a Go enum type expression (e.g. "CFNotificationSuspensionBehavior" or "corefoundation.CFNotificationSuspensionBehavior"). Returns "" when goType is not a known enum. Used by bridge emitters to generate correct integer casts.

func (*Mapper) GoBlockArgType

func (m *Mapper) GoBlockArgType(qt string) string

GoBlockArgType returns the primitive Go type for a block argument or return type. Unlike GoType, this always uses primitive representations: all ObjC objects and pointers return "unsafe.Pointer", enums return their underlying int type. Used to build func types that match the generated MakeBlock_* factory signatures.

func (*Mapper) GoBlockUserFuncType

func (m *Mapper) GoBlockUserFuncType(n string, ctx Context, imports ImportSet) string

GoBlockUserFuncType returns the user-facing Go function type for an ObjC block parameter. Unlike buildBlockGoType (which uses raw unsafe.Pointer for all ObjC objects to match MakeBlock_* trampoline signatures), this maps:

  • NSError * → Go error interface (idiomatic error handling)
  • Known ObjC class pointers in args → typed Go pointer (*ClassName or *pkg.ClassName)
  • Known ObjC class pointer return types → typed Go pointer

ctx is used to resolve class names; imports collects cross-framework import paths. Returns "" when the block type cannot be parsed.

func (*Mapper) GoReturnType

func (m *Mapper) GoReturnType(qt string, ctx Context, imports ImportSet) string

GoReturnType is like GoType but handles the void case explicitly — it returns the empty string for void (caller checks len).

func (*Mapper) GoType

func (m *Mapper) GoType(qt string, ctx Context, imports ImportSet) string

GoType converts an ObjC qualType string to its Go equivalent. It returns the Go type string (e.g. "uint64", "*NSString", "unsafe.Pointer"). An empty string means "no type" (void return).

Results are cached keyed by (normalised type, framework, generic params, class name). Cross-framework import side effects are also cached and replayed on hits so callers always receive correct imports regardless of whether the result came from the cache.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL