objcjs-types 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/objcjs-types.ts +31 -0
- package/dist/AVFoundation/functions.d.ts +21 -0
- package/dist/AVFoundation/functions.js +32 -0
- package/dist/AVFoundation/index.d.ts +1 -0
- package/dist/AVFoundation/index.js +1 -0
- package/dist/Accessibility/functions.d.ts +16 -0
- package/dist/Accessibility/functions.js +35 -0
- package/dist/Accessibility/index.d.ts +1 -0
- package/dist/Accessibility/index.js +1 -0
- package/dist/AddressBook/functions.d.ts +98 -0
- package/dist/AddressBook/functions.js +290 -0
- package/dist/AddressBook/index.d.ts +1 -0
- package/dist/AddressBook/index.js +1 -0
- package/dist/AppKit/functions.d.ts +112 -0
- package/dist/AppKit/functions.js +272 -0
- package/dist/AppKit/index.d.ts +1 -0
- package/dist/AppKit/index.js +1 -0
- package/dist/AudioToolbox/functions.d.ts +377 -0
- package/dist/AudioToolbox/functions.js +1124 -0
- package/dist/AudioToolbox/index.d.ts +1 -0
- package/dist/AudioToolbox/index.js +1 -0
- package/dist/AuthenticationServices/functions.d.ts +2 -0
- package/dist/AuthenticationServices/functions.js +5 -0
- package/dist/AuthenticationServices/index.d.ts +1 -0
- package/dist/AuthenticationServices/index.js +1 -0
- package/dist/BrowserEngineCore/functions.d.ts +3 -0
- package/dist/BrowserEngineCore/functions.js +11 -0
- package/dist/BrowserEngineCore/index.d.ts +1 -0
- package/dist/BrowserEngineCore/index.js +1 -0
- package/dist/CoreAudio/functions.d.ts +60 -0
- package/dist/CoreAudio/functions.js +173 -0
- package/dist/CoreAudio/index.d.ts +1 -0
- package/dist/CoreAudio/index.js +1 -0
- package/dist/CoreMIDI/functions.d.ts +96 -0
- package/dist/CoreMIDI/functions.js +287 -0
- package/dist/CoreMIDI/index.d.ts +1 -0
- package/dist/CoreMIDI/index.js +1 -0
- package/dist/CoreML/functions.d.ts +2 -0
- package/dist/CoreML/functions.js +5 -0
- package/dist/CoreML/index.d.ts +1 -0
- package/dist/CoreML/index.js +1 -0
- package/dist/CoreMediaIO/functions.d.ts +38 -0
- package/dist/CoreMediaIO/functions.js +107 -0
- package/dist/CoreMediaIO/index.d.ts +1 -0
- package/dist/CoreMediaIO/index.js +1 -0
- package/dist/CoreText/functions.d.ts +209 -0
- package/dist/CoreText/functions.js +611 -0
- package/dist/CoreText/index.d.ts +1 -0
- package/dist/CoreText/index.js +1 -0
- package/dist/CoreWLAN/functions.d.ts +23 -0
- package/dist/CoreWLAN/functions.js +56 -0
- package/dist/CoreWLAN/index.d.ts +1 -0
- package/dist/CoreWLAN/index.js +1 -0
- package/dist/DeviceDiscoveryExtension/functions.d.ts +11 -0
- package/dist/DeviceDiscoveryExtension/functions.js +17 -0
- package/dist/DeviceDiscoveryExtension/index.d.ts +1 -0
- package/dist/DeviceDiscoveryExtension/index.js +1 -0
- package/dist/DiscRecording/functions.d.ts +97 -0
- package/dist/DiscRecording/functions.js +290 -0
- package/dist/DiscRecording/index.d.ts +1 -0
- package/dist/DiscRecording/index.js +1 -0
- package/dist/DiscRecordingUI/functions.d.ts +13 -0
- package/dist/DiscRecordingUI/functions.js +38 -0
- package/dist/DiscRecordingUI/index.d.ts +1 -0
- package/dist/DiscRecordingUI/index.js +1 -0
- package/dist/ExceptionHandling/functions.d.ts +1 -0
- package/dist/ExceptionHandling/functions.js +5 -0
- package/dist/ExceptionHandling/index.d.ts +1 -0
- package/dist/ExceptionHandling/index.js +1 -0
- package/dist/FSKit/functions.d.ts +4 -0
- package/dist/FSKit/functions.js +11 -0
- package/dist/FSKit/index.d.ts +1 -0
- package/dist/FSKit/index.js +1 -0
- package/dist/Foundation/functions.d.ts +145 -0
- package/dist/Foundation/functions.js +386 -0
- package/dist/Foundation/index.d.ts +1 -0
- package/dist/Foundation/index.js +1 -0
- package/dist/GLKit/functions.d.ts +51 -0
- package/dist/GLKit/functions.js +146 -0
- package/dist/GLKit/index.d.ts +1 -0
- package/dist/GLKit/index.js +1 -0
- package/dist/GameController/functions.d.ts +18 -0
- package/dist/GameController/functions.js +44 -0
- package/dist/GameController/index.d.ts +1 -0
- package/dist/GameController/index.js +1 -0
- package/dist/HealthKit/functions.d.ts +19 -0
- package/dist/HealthKit/functions.js +35 -0
- package/dist/HealthKit/index.d.ts +1 -0
- package/dist/HealthKit/index.js +1 -0
- package/dist/IOSurface/functions.d.ts +53 -0
- package/dist/IOSurface/functions.js +155 -0
- package/dist/IOSurface/index.d.ts +1 -0
- package/dist/IOSurface/index.js +1 -0
- package/dist/IOUSBHost/functions.d.ts +44 -0
- package/dist/IOUSBHost/functions.js +131 -0
- package/dist/IOUSBHost/index.d.ts +1 -0
- package/dist/IOUSBHost/index.js +1 -0
- package/dist/InstantMessage/functions.d.ts +1 -0
- package/dist/InstantMessage/functions.js +5 -0
- package/dist/InstantMessage/index.d.ts +1 -0
- package/dist/InstantMessage/index.js +1 -0
- package/dist/JavaRuntimeSupport/functions.d.ts +40 -0
- package/dist/JavaRuntimeSupport/functions.js +113 -0
- package/dist/JavaRuntimeSupport/index.d.ts +1 -0
- package/dist/JavaRuntimeSupport/index.js +1 -0
- package/dist/JavaScriptCore/functions.d.ts +120 -0
- package/dist/JavaScriptCore/functions.js +359 -0
- package/dist/JavaScriptCore/index.d.ts +1 -0
- package/dist/JavaScriptCore/index.js +1 -0
- package/dist/MLCompute/functions.d.ts +27 -0
- package/dist/MLCompute/functions.js +41 -0
- package/dist/MLCompute/index.d.ts +1 -0
- package/dist/MLCompute/index.js +1 -0
- package/dist/MapKit/functions.d.ts +23 -0
- package/dist/MapKit/functions.js +56 -0
- package/dist/MapKit/index.d.ts +1 -0
- package/dist/MapKit/index.js +1 -0
- package/dist/Matter/functions.d.ts +17 -0
- package/dist/Matter/functions.js +26 -0
- package/dist/Matter/index.d.ts +1 -0
- package/dist/Matter/index.js +1 -0
- package/dist/MediaAccessibility/functions.d.ts +28 -0
- package/dist/MediaAccessibility/functions.js +83 -0
- package/dist/MediaAccessibility/index.d.ts +1 -0
- package/dist/MediaAccessibility/index.js +1 -0
- package/dist/MediaPlayer/functions.d.ts +3 -0
- package/dist/MediaPlayer/functions.js +11 -0
- package/dist/MediaPlayer/index.d.ts +1 -0
- package/dist/MediaPlayer/index.js +1 -0
- package/dist/Metal/functions.d.ts +14 -0
- package/dist/Metal/functions.js +26 -0
- package/dist/Metal/index.d.ts +1 -0
- package/dist/Metal/index.js +1 -0
- package/dist/MetalKit/functions.d.ts +11 -0
- package/dist/MetalKit/functions.js +20 -0
- package/dist/MetalKit/index.d.ts +1 -0
- package/dist/MetalKit/index.js +1 -0
- package/dist/MetalPerformanceShaders/functions.d.ts +7 -0
- package/dist/MetalPerformanceShaders/functions.js +14 -0
- package/dist/MetalPerformanceShaders/index.d.ts +1 -0
- package/dist/MetalPerformanceShaders/index.js +1 -0
- package/dist/NearbyInteraction/functions.d.ts +3 -0
- package/dist/NearbyInteraction/functions.js +5 -0
- package/dist/NearbyInteraction/index.d.ts +1 -0
- package/dist/NearbyInteraction/index.js +1 -0
- package/dist/ParavirtualizedGraphics/functions.d.ts +7 -0
- package/dist/ParavirtualizedGraphics/functions.js +14 -0
- package/dist/ParavirtualizedGraphics/index.d.ts +1 -0
- package/dist/ParavirtualizedGraphics/index.js +1 -0
- package/dist/QuartzCore/functions.d.ts +19 -0
- package/dist/QuartzCore/functions.js +50 -0
- package/dist/QuartzCore/index.d.ts +1 -0
- package/dist/QuartzCore/index.js +1 -0
- package/dist/SceneKit/functions.d.ts +17 -0
- package/dist/SceneKit/functions.js +38 -0
- package/dist/SceneKit/index.d.ts +1 -0
- package/dist/SceneKit/index.js +1 -0
- package/dist/SensorKit/functions.d.ts +4 -0
- package/dist/SensorKit/functions.js +14 -0
- package/dist/SensorKit/index.d.ts +1 -0
- package/dist/SensorKit/index.js +1 -0
- package/dist/ServiceManagement/functions.d.ts +7 -0
- package/dist/ServiceManagement/functions.js +20 -0
- package/dist/ServiceManagement/index.d.ts +1 -0
- package/dist/ServiceManagement/index.js +1 -0
- package/dist/StoreKit/functions.d.ts +1 -0
- package/dist/StoreKit/functions.js +5 -0
- package/dist/StoreKit/index.d.ts +1 -0
- package/dist/StoreKit/index.js +1 -0
- package/dist/VideoToolbox/functions.d.ts +81 -0
- package/dist/VideoToolbox/functions.js +236 -0
- package/dist/VideoToolbox/index.d.ts +1 -0
- package/dist/VideoToolbox/index.js +1 -0
- package/dist/Vision/functions.d.ts +16 -0
- package/dist/Vision/functions.js +38 -0
- package/dist/Vision/index.d.ts +1 -0
- package/dist/Vision/index.js +1 -0
- package/generator/ast-parser.ts +1368 -0
- package/generator/clang.ts +167 -0
- package/generator/custom.ts +936 -0
- package/generator/discover.ts +111 -0
- package/generator/emitter.ts +2026 -0
- package/generator/frameworks.ts +135 -0
- package/generator/index.ts +1334 -0
- package/generator/parse-worker.ts +263 -0
- package/generator/resolve-strings.ts +121 -0
- package/generator/struct-fields.ts +46 -0
- package/generator/templates/bind.ts +100 -0
- package/generator/templates/helpers.ts +70 -0
- package/generator/templates/nsdata.ts +97 -0
- package/generator/templates/osversion.ts +91 -0
- package/generator/type-mapper.ts +615 -0
- package/generator/worker-pool.ts +309 -0
- package/package.json +13 -4
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* macOS operating system version utilities.
|
|
3
|
+
*
|
|
4
|
+
* Provides cached access to the current OS version and helpers for comparing
|
|
5
|
+
* it against a target version. All reads after the first go through the cache
|
|
6
|
+
* so `NSProcessInfo` is only called once per process lifetime.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { NSProcessInfo } from "./Foundation/index.js";
|
|
10
|
+
|
|
11
|
+
// --- Types ---
|
|
12
|
+
|
|
13
|
+
export interface OSVersion {
|
|
14
|
+
readonly major: number;
|
|
15
|
+
readonly minor: number;
|
|
16
|
+
readonly patch: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// --- Cache ---
|
|
20
|
+
|
|
21
|
+
let cached: OSVersion | undefined;
|
|
22
|
+
|
|
23
|
+
// --- Core ---
|
|
24
|
+
|
|
25
|
+
/** Return the current macOS version, reading from cache after the first call. */
|
|
26
|
+
export function getOSVersion(): OSVersion {
|
|
27
|
+
if (cached !== undefined) return cached;
|
|
28
|
+
const raw = NSProcessInfo.processInfo().operatingSystemVersion();
|
|
29
|
+
cached = { major: raw.field0, minor: raw.field1, patch: raw.field2 };
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Invalidate the cached version (useful in tests). */
|
|
34
|
+
export function clearOSVersionCache(): void {
|
|
35
|
+
cached = undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// --- Comparison ---
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Compare two OS versions.
|
|
42
|
+
*
|
|
43
|
+
* Returns a negative number if `a < b`, 0 if equal, positive if `a > b`.
|
|
44
|
+
*/
|
|
45
|
+
export function compareVersions(a: OSVersion, b: OSVersion): number {
|
|
46
|
+
if (a.major !== b.major) return a.major - b.major;
|
|
47
|
+
if (a.minor !== b.minor) return a.minor - b.minor;
|
|
48
|
+
return a.patch - b.patch;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Returns true if the current OS version is at least `target`. */
|
|
52
|
+
export function isAtLeast(target: OSVersion): boolean {
|
|
53
|
+
return compareVersions(getOSVersion(), target) >= 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Returns true if the current OS version is strictly before `target`. */
|
|
57
|
+
export function isBefore(target: OSVersion): boolean {
|
|
58
|
+
return compareVersions(getOSVersion(), target) < 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Returns true if the current OS version exactly matches `target`. */
|
|
62
|
+
export function isExactly(target: OSVersion): boolean {
|
|
63
|
+
return compareVersions(getOSVersion(), target) === 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// --- Convenience constructors ---
|
|
67
|
+
|
|
68
|
+
/** Build a version object from major/minor/patch components. */
|
|
69
|
+
export function version(major: number, minor: number = 0, patch: number = 0): OSVersion {
|
|
70
|
+
return { major, minor, patch };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Format a version as a human-readable string, e.g. `"15.3.1"`. */
|
|
74
|
+
export function formatVersion(v: OSVersion): string {
|
|
75
|
+
return `${v.major}.${v.minor}.${v.patch}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// --- Named macOS release versions ---
|
|
79
|
+
|
|
80
|
+
export const macOS = {
|
|
81
|
+
Tahoe: version(26),
|
|
82
|
+
Sequoia: version(15),
|
|
83
|
+
Sonoma: version(14),
|
|
84
|
+
Ventura: version(13),
|
|
85
|
+
Monterey: version(12),
|
|
86
|
+
BigSur: version(11),
|
|
87
|
+
Catalina: version(10, 15),
|
|
88
|
+
Mojave: version(10, 14),
|
|
89
|
+
HighSierra: version(10, 13),
|
|
90
|
+
Sierra: version(10, 12)
|
|
91
|
+
} as const;
|
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps Objective-C types (from clang AST qualType strings) to TypeScript types.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** Set of all class names we're generating types for (across all frameworks) */
|
|
6
|
+
let knownClasses: Set<string> = new Set();
|
|
7
|
+
|
|
8
|
+
/** Set of all known protocol names across all frameworks */
|
|
9
|
+
let knownProtocols: Set<string> = new Set();
|
|
10
|
+
|
|
11
|
+
/** Maps protocol name → set of known conforming class names */
|
|
12
|
+
let protocolConformers: Map<string, Set<string>> = new Map();
|
|
13
|
+
|
|
14
|
+
/** Set of all known integer enum names (NS_ENUM / NS_OPTIONS) across all frameworks */
|
|
15
|
+
let knownIntegerEnums: Set<string> = new Set();
|
|
16
|
+
|
|
17
|
+
/** Set of all known string enum names (NS_TYPED_EXTENSIBLE_ENUM etc.) across all frameworks */
|
|
18
|
+
let knownStringEnums: Set<string> = new Set();
|
|
19
|
+
|
|
20
|
+
/** General typedef resolution table: typedef name → underlying qualType string */
|
|
21
|
+
let knownTypedefs: Map<string, string> = new Map();
|
|
22
|
+
|
|
23
|
+
/** Read-only access to the known integer enum names set (for use by the emitter). */
|
|
24
|
+
export function getKnownIntegerEnums(): Set<string> {
|
|
25
|
+
return knownIntegerEnums;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Read-only access to the known string enum names set (for use by the emitter). */
|
|
29
|
+
export function getKnownStringEnums(): Set<string> {
|
|
30
|
+
return knownStringEnums;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function setKnownClasses(classes: Set<string>): void {
|
|
34
|
+
knownClasses = classes;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function setKnownProtocols(protocols: Set<string>): void {
|
|
38
|
+
knownProtocols = protocols;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function setProtocolConformers(conformers: Map<string, Set<string>>): void {
|
|
42
|
+
protocolConformers = conformers;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function setKnownIntegerEnums(enums: Set<string>): void {
|
|
46
|
+
knownIntegerEnums = enums;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function setKnownStringEnums(enums: Set<string>): void {
|
|
50
|
+
knownStringEnums = enums;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function setKnownTypedefs(typedefs: Map<string, string>): void {
|
|
54
|
+
knownTypedefs = typedefs;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Numeric ObjC types that map to `number` in TypeScript.
|
|
59
|
+
*/
|
|
60
|
+
const NUMERIC_TYPES = new Set([
|
|
61
|
+
"int",
|
|
62
|
+
"unsigned int",
|
|
63
|
+
"short",
|
|
64
|
+
"unsigned short",
|
|
65
|
+
"long",
|
|
66
|
+
"unsigned long",
|
|
67
|
+
"long long",
|
|
68
|
+
"unsigned long long",
|
|
69
|
+
"float",
|
|
70
|
+
"double",
|
|
71
|
+
"NSInteger",
|
|
72
|
+
"NSUInteger",
|
|
73
|
+
"CGFloat",
|
|
74
|
+
"NSTimeInterval",
|
|
75
|
+
"unichar",
|
|
76
|
+
"size_t",
|
|
77
|
+
"ssize_t",
|
|
78
|
+
"uint8_t",
|
|
79
|
+
"uint16_t",
|
|
80
|
+
"uint32_t",
|
|
81
|
+
"uint64_t",
|
|
82
|
+
"int8_t",
|
|
83
|
+
"int16_t",
|
|
84
|
+
"int32_t",
|
|
85
|
+
"int64_t",
|
|
86
|
+
"CFIndex",
|
|
87
|
+
"CFTimeInterval",
|
|
88
|
+
"CGWindowLevel",
|
|
89
|
+
"NSWindowLevel",
|
|
90
|
+
"NSModalResponse",
|
|
91
|
+
"NSComparisonResult",
|
|
92
|
+
"NSStringEncoding"
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* ObjC types that map to specific TS types.
|
|
97
|
+
*/
|
|
98
|
+
const DIRECT_MAPPINGS: Record<string, string> = {
|
|
99
|
+
void: "void",
|
|
100
|
+
BOOL: "boolean",
|
|
101
|
+
bool: "boolean",
|
|
102
|
+
_Bool: "boolean",
|
|
103
|
+
id: "NobjcObject",
|
|
104
|
+
SEL: "string",
|
|
105
|
+
Class: "NobjcObject",
|
|
106
|
+
"char *": "string",
|
|
107
|
+
"const char *": "string",
|
|
108
|
+
"unsigned char *": "string",
|
|
109
|
+
"const unsigned char *": "string",
|
|
110
|
+
// Typedef'd NSString * aliases — clang resolves the typedef name, not the underlying type
|
|
111
|
+
NSAttributedStringKey: "_NSString",
|
|
112
|
+
NSStringTransform: "_NSString",
|
|
113
|
+
NSNotificationName: "_NSString",
|
|
114
|
+
NSRunLoopMode: "_NSString",
|
|
115
|
+
NSPasteboardType: "_NSString",
|
|
116
|
+
NSTouchBarItemIdentifier: "_NSString",
|
|
117
|
+
NSToolbarIdentifier: "_NSString",
|
|
118
|
+
NSToolbarItemIdentifier: "_NSString",
|
|
119
|
+
NSAccessibilityRole: "_NSString",
|
|
120
|
+
NSAccessibilitySubrole: "_NSString",
|
|
121
|
+
NSAccessibilityNotificationName: "_NSString",
|
|
122
|
+
NSUserInterfaceItemIdentifier: "_NSString",
|
|
123
|
+
NSStoryboardName: "_NSString",
|
|
124
|
+
NSStoryboardSceneIdentifier: "_NSString",
|
|
125
|
+
NSNibName: "_NSString",
|
|
126
|
+
NSBindingName: "_NSString",
|
|
127
|
+
NSColorName: "_NSString",
|
|
128
|
+
NSColorListName: "_NSString",
|
|
129
|
+
NSImageName: "_NSString",
|
|
130
|
+
NSSoundName: "_NSString",
|
|
131
|
+
NSAppearanceName: "_NSString",
|
|
132
|
+
NSPasteboardReadingOptionKey: "_NSString",
|
|
133
|
+
// Pointer-to-struct typedefs — these are C pointer types, not value types
|
|
134
|
+
NSRectArray: "NobjcObject",
|
|
135
|
+
NSRectPointer: "NobjcObject",
|
|
136
|
+
NSPointArray: "NobjcObject",
|
|
137
|
+
NSPointPointer: "NobjcObject",
|
|
138
|
+
NSSizeArray: "NobjcObject",
|
|
139
|
+
NSSizePointer: "NobjcObject",
|
|
140
|
+
NSRangePointer: "NobjcObject"
|
|
141
|
+
// CoreFoundation opaque types — these are C struct pointers (type encoding `^{...}`),
|
|
142
|
+
// NOT ObjC objects. Handled separately in mapParamType/mapReturnType.
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* CoreFoundation opaque types — these are C struct pointers (type encoding
|
|
147
|
+
* `^{CGContext=}` etc.), NOT ObjC objects. The objc-js bridge handles `^`
|
|
148
|
+
* params with Buffer/TypedArray and pointer returns throw TypeError.
|
|
149
|
+
*/
|
|
150
|
+
const CF_OPAQUE_TYPES = new Set([
|
|
151
|
+
"CGContextRef",
|
|
152
|
+
"CGImageRef",
|
|
153
|
+
"CGColorRef",
|
|
154
|
+
"CGColorSpaceRef",
|
|
155
|
+
"CGPathRef",
|
|
156
|
+
"CGEventRef",
|
|
157
|
+
"CGLayerRef",
|
|
158
|
+
"CFRunLoopRef",
|
|
159
|
+
"CFStringRef",
|
|
160
|
+
"CFTypeRef",
|
|
161
|
+
"SecTrustRef",
|
|
162
|
+
"SecIdentityRef",
|
|
163
|
+
"IOSurfaceRef"
|
|
164
|
+
]);
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* ObjC generic type parameters that should map to NobjcObject.
|
|
168
|
+
* These are erased at runtime; the bridge just sees "id".
|
|
169
|
+
*/
|
|
170
|
+
const GENERIC_TYPE_PARAMS = new Set(["ObjectType", "KeyType", "ValueType", "ElementType", "ResultType", "ContentType"]);
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Maps ObjC struct type names to their TypeScript interface names (defined in src/structs.ts).
|
|
174
|
+
* Built dynamically from parsed struct data by setKnownStructs().
|
|
175
|
+
* NS geometry aliases map to their CG counterparts (identical layout).
|
|
176
|
+
*/
|
|
177
|
+
let STRUCT_TYPE_MAP: Record<string, string> = {};
|
|
178
|
+
|
|
179
|
+
/** The set of all TS struct type names (for use by the emitter to generate imports). */
|
|
180
|
+
export let STRUCT_TS_TYPES = new Set<string>();
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Set the known struct types from parsed AST data.
|
|
184
|
+
* Builds STRUCT_TYPE_MAP (ObjC name → TS name) and STRUCT_TS_TYPES (set of TS names).
|
|
185
|
+
*
|
|
186
|
+
* @param structNames - All struct definition names (e.g., "CGPoint", "NSRange")
|
|
187
|
+
* @param aliases - Map of alias name → target name (e.g., "NSPoint" → "CGPoint")
|
|
188
|
+
* @param internalNames - Map of public name → internal name (e.g., "NSRange" → "_NSRange")
|
|
189
|
+
*/
|
|
190
|
+
export function setKnownStructs(
|
|
191
|
+
structNames: Set<string>,
|
|
192
|
+
aliases: Map<string, string>,
|
|
193
|
+
internalNames: Map<string, string>
|
|
194
|
+
): void {
|
|
195
|
+
STRUCT_TYPE_MAP = {};
|
|
196
|
+
|
|
197
|
+
// Add direct struct names — they map to themselves as TS types
|
|
198
|
+
for (const name of structNames) {
|
|
199
|
+
STRUCT_TYPE_MAP[name] = name;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Add internal names mapping to the public typedef name
|
|
203
|
+
// e.g., _NSRange → NSRange
|
|
204
|
+
// But don't overwrite if the internal name is itself a known public struct name
|
|
205
|
+
// (that case should have been handled as an alias in the parser).
|
|
206
|
+
for (const [publicName, internalName] of internalNames) {
|
|
207
|
+
if (!structNames.has(internalName)) {
|
|
208
|
+
STRUCT_TYPE_MAP[internalName] = publicName;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Add aliases — they map to the target TS type
|
|
213
|
+
// e.g., NSPoint → CGPoint (the TS type is CGPoint)
|
|
214
|
+
for (const [aliasName, targetName] of aliases) {
|
|
215
|
+
STRUCT_TYPE_MAP[aliasName] = targetName;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Rebuild the TS types set
|
|
219
|
+
STRUCT_TS_TYPES = new Set(Object.values(STRUCT_TYPE_MAP));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Convert an ObjC selector string to the objc-js `$` convention.
|
|
224
|
+
* e.g., "arrayByAddingObject:" -> "arrayByAddingObject$"
|
|
225
|
+
* e.g., "initWithFrame:styleMask:" -> "initWithFrame$styleMask$"
|
|
226
|
+
*/
|
|
227
|
+
export function selectorToJS(selector: string): string {
|
|
228
|
+
return selector.replace(/:/g, "$");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Parse the nullable status from a qualType string.
|
|
233
|
+
*/
|
|
234
|
+
function isNullableType(qualType: string): boolean {
|
|
235
|
+
return qualType.includes("_Nullable") || qualType.includes("nullable") || qualType.startsWith("nullable ");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Clean up a qualType string by removing annotations.
|
|
240
|
+
*
|
|
241
|
+
* Clang qualType strings can contain attribute macros that are not part of the
|
|
242
|
+
* actual type. These include nullability qualifiers, ownership qualifiers,
|
|
243
|
+
* availability macros (API_AVAILABLE, API_DEPRECATED, etc.), CoreFoundation
|
|
244
|
+
* ownership macros (CF_CONSUMED, CF_RETURNS_RETAINED, etc.), and Swift interop
|
|
245
|
+
* macros (NS_REFINED_FOR_SWIFT, NS_SWIFT_UI_ACTOR, etc.).
|
|
246
|
+
*/
|
|
247
|
+
function cleanQualType(qualType: string): string {
|
|
248
|
+
return (
|
|
249
|
+
qualType
|
|
250
|
+
.replace(/_Nonnull/g, "")
|
|
251
|
+
.replace(/_Nullable/g, "")
|
|
252
|
+
.replace(/_Null_unspecified/g, "")
|
|
253
|
+
.replace(/\b__kindof\b/g, "")
|
|
254
|
+
.replace(/\b__unsafe_unretained\b/g, "")
|
|
255
|
+
.replace(/\b__strong\b/g, "")
|
|
256
|
+
.replace(/\b__weak\b/g, "")
|
|
257
|
+
.replace(/\b__autoreleasing\b/g, "")
|
|
258
|
+
// Attribute macros: NS_*, API_*, CF_*, XPC_* (e.g. API_AVAILABLE, CF_RETURNS_RETAINED)
|
|
259
|
+
.replace(/\b(?:NS|API|CF|XPC)_[A-Z_]+\b/g, "")
|
|
260
|
+
// Legacy availability macros: AVAILABLE_MAC_OS_X_VERSION_*_AND_LATER etc.
|
|
261
|
+
.replace(/\bAVAILABLE_MAC_OS_X_VERSION_[A-Z0-9_]+\b/g, "")
|
|
262
|
+
.replace(/^struct\s+/, "")
|
|
263
|
+
.trim()
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Extract the base class name from a pointer type like "NSArray<ObjectType> *".
|
|
269
|
+
*/
|
|
270
|
+
function extractClassName(cleaned: string): string | null {
|
|
271
|
+
// Match "ClassName *" or "ClassName<...> *" (with optional const prefix).
|
|
272
|
+
// The generic parameter section may contain nested angle brackets
|
|
273
|
+
// (e.g., "NSArray<id<NSAccessibilityRow>> *"), so we match from the
|
|
274
|
+
// first '<' to the last '>' instead of using [^>]*.
|
|
275
|
+
const match = cleaned.match(/^(?:const\s+)?(\w+)\s*(?:<.*>)?\s*\*$/);
|
|
276
|
+
if (match) return match[1]!;
|
|
277
|
+
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Map an Objective-C type string to a TypeScript type string.
|
|
283
|
+
*
|
|
284
|
+
* @param qualType The clang qualType string (e.g., "NSArray<ObjectType> * _Nonnull")
|
|
285
|
+
* @param containingClass The class this type appears in (for resolving `instancetype`)
|
|
286
|
+
* @param isReturnType Whether this type is used in a return position (enables conformer union expansion)
|
|
287
|
+
* @returns The TypeScript type string
|
|
288
|
+
*/
|
|
289
|
+
export function mapType(qualType: string, containingClass: string, isReturnType = false): string {
|
|
290
|
+
const nullable = isNullableType(qualType);
|
|
291
|
+
const cleaned = cleanQualType(qualType);
|
|
292
|
+
|
|
293
|
+
let tsType = mapTypeInner(cleaned, containingClass, undefined, isReturnType);
|
|
294
|
+
|
|
295
|
+
if (nullable && tsType !== "void") {
|
|
296
|
+
tsType = `${tsType} | null`;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return tsType;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function mapTypeInner(cleaned: string, containingClass: string, resolving?: Set<string>, isReturnType = false): string {
|
|
303
|
+
// Direct mappings
|
|
304
|
+
if (cleaned in DIRECT_MAPPINGS) {
|
|
305
|
+
return DIRECT_MAPPINGS[cleaned]!;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Numeric types
|
|
309
|
+
if (NUMERIC_TYPES.has(cleaned)) {
|
|
310
|
+
return "number";
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ObjC generic type parameters (ObjectType, KeyType, etc.)
|
|
314
|
+
if (GENERIC_TYPE_PARAMS.has(cleaned)) {
|
|
315
|
+
return "NobjcObject";
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// instancetype -> the containing class
|
|
319
|
+
if (cleaned === "instancetype" || cleaned === "instancetype _Nonnull" || cleaned === "instancetype _Nullable") {
|
|
320
|
+
return `_${containingClass}`;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Struct types -> typed interfaces from src/structs.ts
|
|
324
|
+
if (cleaned in STRUCT_TYPE_MAP) {
|
|
325
|
+
return STRUCT_TYPE_MAP[cleaned]!;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Block types: "void (^)(Type1, Type2)" or "ReturnType (^)(Type1, Type2)"
|
|
329
|
+
// At runtime, blocks have type encoding `@?` which the bridge handles via
|
|
330
|
+
// the `@` (id) case — only NobjcObject is accepted/returned, not JS functions.
|
|
331
|
+
if (cleaned.includes("(^") || cleaned.includes("Block_")) {
|
|
332
|
+
return "NobjcObject";
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Function pointer types — same runtime limitation as blocks
|
|
336
|
+
if (cleaned.includes("(*)") || cleaned.includes("(*")) {
|
|
337
|
+
return "NobjcObject";
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Pointer to pointer (e.g., "NSError **") - out parameters
|
|
341
|
+
if (cleaned.match(/\w+\s*\*\s*\*/)) {
|
|
342
|
+
return "NobjcObject";
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Void pointer
|
|
346
|
+
if (cleaned === "void *" || cleaned === "const void *") {
|
|
347
|
+
return "NobjcObject";
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ObjC object pointer (e.g., "NSString *", "NSArray<ObjectType> *")
|
|
351
|
+
const className = extractClassName(cleaned);
|
|
352
|
+
if (className) {
|
|
353
|
+
// instancetype check again
|
|
354
|
+
if (className === "instancetype") {
|
|
355
|
+
return `_${containingClass}`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Known class -> use typed reference
|
|
359
|
+
if (knownClasses.has(className)) {
|
|
360
|
+
return `_${className}`;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Unknown class -> NobjcObject
|
|
364
|
+
return "NobjcObject";
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Enum / typedef types — use the enum type name directly for type safety.
|
|
368
|
+
// First check if this is a known enum type — this is more precise than the
|
|
369
|
+
// typedef resolution below and handles prefixes like AS that aren't in the list.
|
|
370
|
+
if (knownIntegerEnums.has(cleaned)) {
|
|
371
|
+
return cleaned;
|
|
372
|
+
}
|
|
373
|
+
if (knownStringEnums.has(cleaned)) {
|
|
374
|
+
return cleaned;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Resolve typedefs: look up the underlying type and recursively map it.
|
|
378
|
+
// This handles cases like NSWindowPersistableFrameDescriptor → NSString *,
|
|
379
|
+
// NSWindowFrameAutosaveName → NSString *, FourCharCode → unsigned int, etc.
|
|
380
|
+
// without needing hardcoded heuristics or manual DIRECT_MAPPINGS entries.
|
|
381
|
+
if (knownTypedefs.has(cleaned)) {
|
|
382
|
+
// Guard against circular typedef chains (e.g., typedef struct X X → cleanQualType → X)
|
|
383
|
+
const seen = resolving ?? new Set<string>();
|
|
384
|
+
if (!seen.has(cleaned)) {
|
|
385
|
+
seen.add(cleaned);
|
|
386
|
+
const underlying = knownTypedefs.get(cleaned)!;
|
|
387
|
+
return mapTypeInner(cleanQualType(underlying), containingClass, seen, isReturnType);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Protocol-qualified id: "id<ASAuthorizationCredential>" or "id<Proto1, Proto2>"
|
|
392
|
+
//
|
|
393
|
+
// For RETURN types: if the protocol has a small number of known conforming classes
|
|
394
|
+
// (≤ MAX_CONFORMERS_FOR_UNION), expand to a union of those concrete classes.
|
|
395
|
+
// This gives callers useful type information — e.g., credential() returns the
|
|
396
|
+
// union of all ASAuthorizationCredential-conforming classes rather than an empty
|
|
397
|
+
// protocol interface. The conformers set is deterministic (same for parent and
|
|
398
|
+
// child classes), so override compatibility is preserved.
|
|
399
|
+
//
|
|
400
|
+
// For PARAMETER types: keep the protocol interface type. Expanding to a union
|
|
401
|
+
// would incorrectly restrict which objects can be passed (any conforming object
|
|
402
|
+
// should be accepted, not just known SDK conformers).
|
|
403
|
+
const MAX_CONFORMERS_FOR_UNION = 30;
|
|
404
|
+
const protoMatch = cleaned.match(/^id<(.+)>$/);
|
|
405
|
+
if (protoMatch) {
|
|
406
|
+
const protoNames = protoMatch[1]!.split(/,\s*/);
|
|
407
|
+
|
|
408
|
+
// For return types with a single protocol, try conformer union expansion
|
|
409
|
+
if (isReturnType && protoNames.length === 1) {
|
|
410
|
+
const protoName = protoNames[0]!;
|
|
411
|
+
const conformers = protocolConformers.get(protoName);
|
|
412
|
+
if (conformers && conformers.size > 0 && conformers.size <= MAX_CONFORMERS_FOR_UNION) {
|
|
413
|
+
const sorted = [...conformers].sort();
|
|
414
|
+
return sorted.map((c) => `_${c}`).join(" | ");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Fallback: use the protocol interface type(s)
|
|
419
|
+
const unionParts: string[] = [];
|
|
420
|
+
|
|
421
|
+
for (const protoName of protoNames) {
|
|
422
|
+
if (knownProtocols.has(protoName)) {
|
|
423
|
+
unionParts.push(`_${protoName}`);
|
|
424
|
+
} else if (knownClasses.has(protoName)) {
|
|
425
|
+
// Sometimes a "protocol" name is actually a class name
|
|
426
|
+
unionParts.push(`_${protoName}`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (unionParts.length > 0) {
|
|
431
|
+
// Deduplicate (a class conforming to multiple listed protocols)
|
|
432
|
+
return [...new Set(unionParts)].join(" | ");
|
|
433
|
+
}
|
|
434
|
+
return "NobjcObject";
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Array type (C array parameters like "const ObjectType [_Nonnull]")
|
|
438
|
+
if (cleaned.includes("[")) {
|
|
439
|
+
return "NobjcObject";
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Fallback: unknown type -> NobjcObject
|
|
443
|
+
return "NobjcObject";
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Map a return type, handling instancetype specially.
|
|
448
|
+
*
|
|
449
|
+
* CF opaque types (CGContextRef, etc.) are struct pointers at the ABI level.
|
|
450
|
+
* The objc-js bridge throws TypeError for pointer return types, so we type
|
|
451
|
+
* them as NobjcObject (the call will fail at runtime regardless).
|
|
452
|
+
*
|
|
453
|
+
* For protocol-qualified id types (e.g., id<ASAuthorizationCredential>),
|
|
454
|
+
* returns a union of known conforming classes when the conformer set is small
|
|
455
|
+
* enough, providing concrete type information to callers.
|
|
456
|
+
*/
|
|
457
|
+
export function mapReturnType(qualType: string, containingClass: string): string {
|
|
458
|
+
const cleaned = cleanQualType(qualType);
|
|
459
|
+
if (CF_OPAQUE_TYPES.has(cleaned)) {
|
|
460
|
+
return "NobjcObject";
|
|
461
|
+
}
|
|
462
|
+
return mapType(qualType, containingClass, true);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Map an ObjC qualType string to its ObjC type encoding character(s).
|
|
467
|
+
*
|
|
468
|
+
* Used by the function emitter to generate `{ returns: "..." }` and
|
|
469
|
+
* `{ args: [...] }` options for `callFunction()`. The type encodings
|
|
470
|
+
* follow the ObjC runtime convention:
|
|
471
|
+
* - `v` = void, `B` = BOOL, `i` = int, `I` = unsigned int
|
|
472
|
+
* - `s` = short, `S` = unsigned short, `l` = long, `L` = unsigned long
|
|
473
|
+
* - `q` = long long, `Q` = unsigned long long
|
|
474
|
+
* - `f` = float, `d` = double
|
|
475
|
+
* - `@` = ObjC object pointer (id, NSString *, etc.)
|
|
476
|
+
* - `:` = SEL, `#` = Class
|
|
477
|
+
* - `*` = char *, `^v` = void *
|
|
478
|
+
* - `^` = generic pointer (CF opaque types, etc.)
|
|
479
|
+
*
|
|
480
|
+
* @returns The type encoding string, or null if the type cannot be encoded
|
|
481
|
+
* (e.g., block types, function pointers, pointer-to-pointer).
|
|
482
|
+
*/
|
|
483
|
+
export function qualTypeToEncoding(qualType: string): string | null {
|
|
484
|
+
const cleaned = cleanQualType(qualType);
|
|
485
|
+
|
|
486
|
+
// Void
|
|
487
|
+
if (cleaned === "void") return "v";
|
|
488
|
+
|
|
489
|
+
// Boolean
|
|
490
|
+
if (cleaned === "BOOL" || cleaned === "bool" || cleaned === "_Bool") return "B";
|
|
491
|
+
|
|
492
|
+
// Integer types
|
|
493
|
+
if (cleaned === "char" || cleaned === "signed char") return "c";
|
|
494
|
+
if (cleaned === "unsigned char") return "C";
|
|
495
|
+
if (cleaned === "short" || cleaned === "unsigned short") return cleaned.startsWith("unsigned") ? "S" : "s";
|
|
496
|
+
if (cleaned === "int") return "i";
|
|
497
|
+
if (cleaned === "unsigned int") return "I";
|
|
498
|
+
if (cleaned === "long") return "l";
|
|
499
|
+
if (cleaned === "unsigned long") return "L";
|
|
500
|
+
if (cleaned === "long long") return "q";
|
|
501
|
+
if (cleaned === "unsigned long long") return "Q";
|
|
502
|
+
|
|
503
|
+
// Fixed-width integer types
|
|
504
|
+
if (cleaned === "int8_t") return "c";
|
|
505
|
+
if (cleaned === "uint8_t") return "C";
|
|
506
|
+
if (cleaned === "int16_t") return "s";
|
|
507
|
+
if (cleaned === "uint16_t") return "S";
|
|
508
|
+
if (cleaned === "int32_t") return "i";
|
|
509
|
+
if (cleaned === "uint32_t") return "I";
|
|
510
|
+
if (cleaned === "int64_t") return "q";
|
|
511
|
+
if (cleaned === "uint64_t") return "Q";
|
|
512
|
+
|
|
513
|
+
// Platform-dependent integer types (arm64 macOS: NSInteger = long, NSUInteger = unsigned long)
|
|
514
|
+
if (cleaned === "NSInteger" || cleaned === "CFIndex" || cleaned === "ssize_t") return "q";
|
|
515
|
+
if (cleaned === "NSUInteger" || cleaned === "size_t") return "Q";
|
|
516
|
+
|
|
517
|
+
// Floating point
|
|
518
|
+
if (cleaned === "float") return "f";
|
|
519
|
+
if (cleaned === "double" || cleaned === "CGFloat" || cleaned === "NSTimeInterval" || cleaned === "CFTimeInterval")
|
|
520
|
+
return "d";
|
|
521
|
+
|
|
522
|
+
// Unicode character
|
|
523
|
+
if (cleaned === "unichar") return "S";
|
|
524
|
+
|
|
525
|
+
// Selector
|
|
526
|
+
if (cleaned === "SEL") return ":";
|
|
527
|
+
|
|
528
|
+
// Class
|
|
529
|
+
if (cleaned === "Class") return "#";
|
|
530
|
+
|
|
531
|
+
// C string types
|
|
532
|
+
if (
|
|
533
|
+
cleaned === "char *" ||
|
|
534
|
+
cleaned === "const char *" ||
|
|
535
|
+
cleaned === "unsigned char *" ||
|
|
536
|
+
cleaned === "const unsigned char *"
|
|
537
|
+
)
|
|
538
|
+
return "*";
|
|
539
|
+
|
|
540
|
+
// Void pointer
|
|
541
|
+
if (cleaned === "void *" || cleaned === "const void *") return "^v";
|
|
542
|
+
|
|
543
|
+
// ObjC id (bare)
|
|
544
|
+
if (cleaned === "id") return "@";
|
|
545
|
+
|
|
546
|
+
// ObjC object pointers (NSString *, NSArray<...> *, id<Protocol>, etc.)
|
|
547
|
+
if (cleaned.endsWith("*") || cleaned.startsWith("id<")) return "@";
|
|
548
|
+
|
|
549
|
+
// Enum types that are known integers — map to their underlying integer encoding
|
|
550
|
+
if (knownIntegerEnums.has(cleaned)) return "q"; // Most NS_ENUM/NS_OPTIONS use NSInteger/NSUInteger
|
|
551
|
+
|
|
552
|
+
// String enum types (NSString * typedef aliases)
|
|
553
|
+
if (knownStringEnums.has(cleaned)) return "@";
|
|
554
|
+
|
|
555
|
+
// NSString typedef aliases from DIRECT_MAPPINGS
|
|
556
|
+
if (cleaned in DIRECT_MAPPINGS) {
|
|
557
|
+
const mapped = DIRECT_MAPPINGS[cleaned]!;
|
|
558
|
+
if (mapped === "_NSString" || mapped === "string") return "@";
|
|
559
|
+
if (mapped === "boolean") return "B";
|
|
560
|
+
if (mapped === "number") return "q";
|
|
561
|
+
if (mapped === "void") return "v";
|
|
562
|
+
if (mapped === "NobjcObject") return "@";
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Struct types
|
|
566
|
+
if (cleaned in STRUCT_TYPE_MAP) return "{" + cleaned + "}";
|
|
567
|
+
|
|
568
|
+
// CF opaque types (struct pointers)
|
|
569
|
+
if (CF_OPAQUE_TYPES.has(cleaned)) return "^";
|
|
570
|
+
|
|
571
|
+
// Typedef resolution
|
|
572
|
+
if (knownTypedefs.has(cleaned)) {
|
|
573
|
+
const underlying = knownTypedefs.get(cleaned)!;
|
|
574
|
+
return qualTypeToEncoding(underlying);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Numeric types catch-all
|
|
578
|
+
if (NUMERIC_TYPES.has(cleaned)) return "d";
|
|
579
|
+
|
|
580
|
+
// Block types, function pointers, pointer-to-pointer — cannot encode simply
|
|
581
|
+
if (
|
|
582
|
+
cleaned.includes("(^") ||
|
|
583
|
+
cleaned.includes("Block_") ||
|
|
584
|
+
cleaned.includes("(*)") ||
|
|
585
|
+
cleaned.match(/\w+\s*\*\s*\*/)
|
|
586
|
+
) {
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Unknown — default to object pointer
|
|
591
|
+
return "@";
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Map a parameter type.
|
|
596
|
+
*
|
|
597
|
+
* For raw pointer parameters (`void *`, `const void *`) and CF opaque types
|
|
598
|
+
* (CGContextRef, etc.), the objc-js bridge expects `Buffer` or `TypedArray`
|
|
599
|
+
* at runtime (type encoding `^`). We type these as `Uint8Array` so callers
|
|
600
|
+
* can pass `Buffer` or `Uint8Array` without casting.
|
|
601
|
+
*/
|
|
602
|
+
export function mapParamType(qualType: string, containingClass: string): string {
|
|
603
|
+
const cleaned = cleanQualType(qualType);
|
|
604
|
+
// Raw void pointers
|
|
605
|
+
if (cleaned === "void *" || cleaned === "const void *") {
|
|
606
|
+
const nullable = isNullableType(qualType);
|
|
607
|
+
return nullable ? "Uint8Array | null" : "Uint8Array";
|
|
608
|
+
}
|
|
609
|
+
// CF opaque types (struct pointers with `^{...}` encoding)
|
|
610
|
+
if (CF_OPAQUE_TYPES.has(cleaned)) {
|
|
611
|
+
const nullable = isNullableType(qualType);
|
|
612
|
+
return nullable ? "Uint8Array | null" : "Uint8Array";
|
|
613
|
+
}
|
|
614
|
+
return mapType(qualType, containingClass);
|
|
615
|
+
}
|