objcjs-types 0.5.1 → 0.5.2

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.
Files changed (173) hide show
  1. package/dist/AVFAudio/index.js +74 -74
  2. package/dist/AVFoundation/index.js +269 -269
  3. package/dist/AVKit/index.js +7 -7
  4. package/dist/AVRouting/index.js +7 -7
  5. package/dist/Accessibility/index.js +29 -29
  6. package/dist/AccessorySetupKit/index.js +12 -12
  7. package/dist/Accounts/index.js +5 -5
  8. package/dist/AdServices/index.js +2 -2
  9. package/dist/AdSupport/index.js +2 -2
  10. package/dist/AddressBook/index.js +11 -11
  11. package/dist/AppKit/constants.d.ts +8 -0
  12. package/dist/AppKit/constants.js +9 -0
  13. package/dist/AppKit/index.js +317 -317
  14. package/dist/AppTrackingTransparency/index.js +2 -2
  15. package/dist/AppleScriptKit/index.js +2 -2
  16. package/dist/AudioToolbox/index.js +10 -10
  17. package/dist/AudioVideoBridging/index.js +18 -18
  18. package/dist/AuthenticationServices/index.js +79 -79
  19. package/dist/AutomaticAssessmentConfiguration/index.js +5 -5
  20. package/dist/Automator/index.js +9 -9
  21. package/dist/BackgroundAssets/index.js +8 -8
  22. package/dist/BackgroundTasks/index.js +12 -12
  23. package/dist/BrowserEngineCore/index.js +2 -2
  24. package/dist/BrowserEngineKit/index.js +19 -19
  25. package/dist/BusinessChat/index.js +3 -3
  26. package/dist/CalendarStore/index.js +11 -11
  27. package/dist/CallKit/index.js +22 -22
  28. package/dist/Cinematic/index.js +17 -17
  29. package/dist/ClassKit/index.js +10 -10
  30. package/dist/CloudKit/index.js +90 -90
  31. package/dist/Collaboration/index.js +6 -6
  32. package/dist/Contacts/index.js +36 -36
  33. package/dist/ContactsUI/index.js +3 -3
  34. package/dist/CoreAudio/index.js +2 -2
  35. package/dist/CoreAudioKit/index.js +9 -9
  36. package/dist/CoreBluetooth/index.js +17 -17
  37. package/dist/CoreData/index.js +63 -63
  38. package/dist/CoreHaptics/index.js +8 -8
  39. package/dist/CoreImage/index.js +31 -31
  40. package/dist/CoreLocation/index.js +24 -24
  41. package/dist/CoreMIDI/index.js +20 -20
  42. package/dist/CoreML/index.js +52 -52
  43. package/dist/CoreMediaIO/index.js +13 -13
  44. package/dist/CoreMotion/index.js +38 -38
  45. package/dist/CoreSpotlight/index.js +14 -14
  46. package/dist/CoreTelephony/index.js +12 -12
  47. package/dist/CoreText/index.js +1 -1
  48. package/dist/CoreWLAN/index.js +9 -9
  49. package/dist/CryptoTokenKit/index.js +36 -36
  50. package/dist/DataDetection/index.js +10 -10
  51. package/dist/DeviceCheck/index.js +3 -3
  52. package/dist/DeviceDiscoveryExtension/index.js +4 -4
  53. package/dist/DiscRecording/index.js +12 -12
  54. package/dist/DiscRecordingUI/index.js +6 -6
  55. package/dist/EventKit/index.js +18 -18
  56. package/dist/ExceptionHandling/index.js +2 -2
  57. package/dist/ExecutionPolicy/index.js +3 -3
  58. package/dist/ExtensionKit/index.js +3 -3
  59. package/dist/ExternalAccessory/index.js +6 -6
  60. package/dist/FSKit/index.js +28 -28
  61. package/dist/FileProvider/index.js +10 -10
  62. package/dist/FileProviderUI/index.js +3 -3
  63. package/dist/FinderSync/index.js +3 -3
  64. package/dist/Foundation/constants.d.ts +3 -0
  65. package/dist/Foundation/constants.js +4 -0
  66. package/dist/Foundation/index.js +275 -275
  67. package/dist/GLKit/index.js +16 -16
  68. package/dist/GameController/index.js +39 -39
  69. package/dist/GameKit/index.js +44 -44
  70. package/dist/GameSave/index.js +4 -4
  71. package/dist/GameplayKit/constants.d.ts +2 -0
  72. package/dist/GameplayKit/constants.js +3 -0
  73. package/dist/GameplayKit/index.js +59 -59
  74. package/dist/HealthKit/constants.d.ts +1 -0
  75. package/dist/HealthKit/constants.js +2 -0
  76. package/dist/HealthKit/index.js +109 -109
  77. package/dist/IOSurface/index.js +2 -2
  78. package/dist/IOUSBHost/index.js +12 -12
  79. package/dist/IdentityLookup/index.js +15 -15
  80. package/dist/ImageCaptureCore/index.js +19 -19
  81. package/dist/InputMethodKit/index.js +4 -4
  82. package/dist/InstallerPlugins/index.js +4 -4
  83. package/dist/InstantMessage/index.js +7 -7
  84. package/dist/Intents/index.js +310 -310
  85. package/dist/IntentsUI/index.js +4 -4
  86. package/dist/JavaRuntimeSupport/index.js +6 -6
  87. package/dist/JavaScriptCore/index.js +5 -5
  88. package/dist/Kernel/index.js +1 -1
  89. package/dist/LinkPresentation/index.js +4 -4
  90. package/dist/LocalAuthentication/index.js +19 -19
  91. package/dist/LocalAuthenticationEmbeddedUI/index.js +2 -2
  92. package/dist/MLCompute/index.js +57 -57
  93. package/dist/MailKit/index.js +17 -17
  94. package/dist/MapKit/index.js +75 -75
  95. package/dist/Matter/index.js +1331 -1331
  96. package/dist/MediaAccessibility/index.js +4 -4
  97. package/dist/MediaExtension/index.js +19 -19
  98. package/dist/MediaLibrary/index.js +5 -5
  99. package/dist/MediaPlayer/index.js +49 -49
  100. package/dist/Metal/constants.d.ts +2 -0
  101. package/dist/Metal/constants.js +3 -0
  102. package/dist/Metal/index.js +150 -150
  103. package/dist/MetalFX/index.js +5 -5
  104. package/dist/MetalKit/index.js +7 -7
  105. package/dist/MetalPerformanceShaders/index.js +1 -1
  106. package/dist/MetalPerformanceShadersGraph/index.js +29 -29
  107. package/dist/MetricKit/index.js +38 -38
  108. package/dist/ModelIO/index.js +67 -67
  109. package/dist/MultipeerConnectivity/index.js +7 -7
  110. package/dist/NaturalLanguage/index.js +10 -10
  111. package/dist/NearbyInteraction/index.js +10 -10
  112. package/dist/NetworkExtension/index.js +89 -89
  113. package/dist/NotificationCenter/index.js +4 -4
  114. package/dist/OSAKit/index.js +6 -6
  115. package/dist/OSLog/index.js +10 -10
  116. package/dist/OpenDirectory/index.js +10 -10
  117. package/dist/PDFKit/index.js +30 -30
  118. package/dist/PHASE/index.js +60 -60
  119. package/dist/ParavirtualizedGraphics/index.js +4 -4
  120. package/dist/PassKit/index.js +74 -74
  121. package/dist/PencilKit/index.js +14 -14
  122. package/dist/Photos/index.js +44 -44
  123. package/dist/PhotosUI/index.js +18 -18
  124. package/dist/PreferencePanes/index.js +2 -2
  125. package/dist/PushKit/index.js +4 -4
  126. package/dist/QuartzCore/index.js +32 -32
  127. package/dist/QuickLookThumbnailing/index.js +7 -7
  128. package/dist/QuickLookUI/index.js +7 -7
  129. package/dist/ReplayKit/index.js +8 -8
  130. package/dist/SafariServices/index.js +15 -15
  131. package/dist/SafetyKit/index.js +4 -4
  132. package/dist/SceneKit/index.js +67 -67
  133. package/dist/ScreenCaptureKit/index.js +16 -16
  134. package/dist/ScreenSaver/index.js +3 -3
  135. package/dist/ScreenTime/index.js +5 -5
  136. package/dist/ScriptingBridge/index.js +4 -4
  137. package/dist/SecurityFoundation/index.js +2 -2
  138. package/dist/SecurityInterface/index.js +10 -10
  139. package/dist/SecurityUI/index.js +2 -2
  140. package/dist/SensitiveContentAnalysis/index.js +4 -4
  141. package/dist/SensorKit/index.js +39 -39
  142. package/dist/ServiceManagement/index.js +2 -2
  143. package/dist/SharedWithYou/index.js +11 -11
  144. package/dist/SharedWithYouCore/index.js +14 -14
  145. package/dist/ShazamKit/index.js +11 -11
  146. package/dist/Social/index.js +3 -3
  147. package/dist/SoundAnalysis/index.js +7 -7
  148. package/dist/Speech/index.js +14 -14
  149. package/dist/SpriteKit/index.js +49 -49
  150. package/dist/StoreKit/index.js +28 -28
  151. package/dist/Symbols/index.js +19 -19
  152. package/dist/SyncServices/index.js +9 -9
  153. package/dist/SystemExtensions/index.js +6 -6
  154. package/dist/ThreadNetwork/index.js +3 -3
  155. package/dist/UniformTypeIdentifiers/index.js +2 -2
  156. package/dist/UserNotifications/index.js +22 -22
  157. package/dist/UserNotificationsUI/index.js +1 -1
  158. package/dist/VideoSubscriberAccount/index.js +14 -14
  159. package/dist/VideoToolbox/index.js +18 -18
  160. package/dist/Virtualization/index.js +111 -111
  161. package/dist/Vision/constants.d.ts +54 -0
  162. package/dist/Vision/constants.js +55 -0
  163. package/dist/Vision/index.js +92 -92
  164. package/dist/WebKit/index.js +166 -166
  165. package/dist/iTunesLibrary/index.js +9 -9
  166. package/generator/ast-parser.ts +132 -0
  167. package/generator/discover.ts +26 -1
  168. package/generator/emitter.ts +34 -3
  169. package/generator/frameworks.ts +4 -0
  170. package/generator/index.ts +61 -9
  171. package/generator/parse-worker.ts +9 -2
  172. package/generator/worker-pool.ts +12 -5
  173. package/package.json +8 -3
@@ -122,6 +122,17 @@ export interface ObjCFunction {
122
122
  frameworkName: string;
123
123
  }
124
124
 
125
+ // --- Numeric constant types ---
126
+
127
+ export interface ObjCNumericConstant {
128
+ /** The constant name (e.g., "NSVariableStatusItemLength") */
129
+ name: string;
130
+ /** The numeric value */
131
+ value: number;
132
+ /** Whether the value is a floating-point type (CGFloat, double, float) vs integer (NSInteger, etc.) */
133
+ isFloat: boolean;
134
+ }
135
+
125
136
  // --- Helpers for extracting doc comments and deprecation info ---
126
137
 
127
138
  /**
@@ -1399,6 +1410,127 @@ function extractIntegerValue(node: ClangASTNode): string | null {
1399
1410
  return val !== null ? String(val) : null;
1400
1411
  }
1401
1412
 
1413
+ /**
1414
+ * Extract a numeric value (integer or floating-point) from a VarDecl's initializer expression tree.
1415
+ * Handles IntegerLiteral, FloatingLiteral, UnaryOperator("-"), and ImplicitCastExpr wrappers.
1416
+ * Returns the numeric value, or null if it can't be extracted.
1417
+ */
1418
+ function extractNumericValue(node: ClangASTNode): number | null {
1419
+ if (!node.inner) return null;
1420
+
1421
+ function evaluate(n: ClangASTNode): number | null {
1422
+ if (n.kind === "IntegerLiteral" && n.value !== undefined) {
1423
+ return parseInt(n.value, 10);
1424
+ }
1425
+ if (n.kind === "FloatingLiteral" && n.value !== undefined) {
1426
+ return parseFloat(n.value);
1427
+ }
1428
+ if (n.kind === "UnaryOperator" && (n as any).opcode === "-" && n.inner?.length === 1) {
1429
+ const operand = evaluate(n.inner[0]!);
1430
+ return operand !== null ? -operand : null;
1431
+ }
1432
+ // Walk through transparent wrappers (ImplicitCastExpr, ParenExpr, ConstantExpr, etc.)
1433
+ if (n.inner?.length === 1) {
1434
+ return evaluate(n.inner[0]!);
1435
+ }
1436
+ // Try all children for multi-child wrappers
1437
+ if (n.inner) {
1438
+ for (const child of n.inner) {
1439
+ const val = evaluate(child);
1440
+ if (val !== null) return val;
1441
+ }
1442
+ }
1443
+ return null;
1444
+ }
1445
+
1446
+ return evaluate(node);
1447
+ }
1448
+
1449
+ /**
1450
+ * Parse a clang AST root node and extract standalone numeric constants.
1451
+ *
1452
+ * These are `static const` VarDecl nodes with numeric types (CGFloat, double, float,
1453
+ * NSInteger, NSUInteger, NSTimeInterval, int, long) that are NOT linked to a
1454
+ * NS_TYPED_EXTENSIBLE_ENUM typedef via `typeAliasDeclId`.
1455
+ *
1456
+ * Examples:
1457
+ * - `static const CGFloat NSVariableStatusItemLength = -1;`
1458
+ * - `static const NSInteger NSSearchFieldRecentsTitleMenuItemTag = 1000;`
1459
+ *
1460
+ * @param targetConstants - Set of constant names to extract (from discovery)
1461
+ */
1462
+ export function parseNumericConstants(
1463
+ root: ClangASTNode,
1464
+ targetConstants: Set<string>
1465
+ ): Map<string, ObjCNumericConstant> {
1466
+ const constants = new Map<string, ObjCNumericConstant>();
1467
+ if (targetConstants.size === 0) return constants;
1468
+
1469
+ // Collect all TypedefDecl ids that are NS_TYPED_EXTENSIBLE_ENUM / NS_TYPED_ENUM
1470
+ // so we can exclude VarDecls that are already handled by parseIntegerTypedEnums.
1471
+ const typedEnumIds = new Set<string>();
1472
+ function walkForTypedEnumTypedefs(node: ClangASTNode): void {
1473
+ if (node.kind === "TypedefDecl" && node.id) {
1474
+ const hasSwiftNewType = node.inner?.some((child) => child.kind === "SwiftNewTypeAttr") ?? false;
1475
+ if (hasSwiftNewType) {
1476
+ typedEnumIds.add(node.id);
1477
+ }
1478
+ }
1479
+ if (node.inner) {
1480
+ for (const child of node.inner) {
1481
+ walkForTypedEnumTypedefs(child);
1482
+ }
1483
+ }
1484
+ }
1485
+
1486
+ function walkForConstants(node: ClangASTNode): void {
1487
+ if (node.kind === "VarDecl" && node.name && node.storageClass === "static" && targetConstants.has(node.name)) {
1488
+ // Skip VarDecls linked to NS_TYPED_EXTENSIBLE_ENUM typedefs (handled by parseIntegerTypedEnums)
1489
+ if (node.type?.typeAliasDeclId && typedEnumIds.has(node.type.typeAliasDeclId)) {
1490
+ return;
1491
+ }
1492
+
1493
+ // Check that the type is a const numeric type
1494
+ const qualType = node.type?.qualType ?? "";
1495
+ const desugared = node.type?.desugaredQualType ?? "";
1496
+ const isConstNumeric =
1497
+ /\bconst\b/.test(qualType) &&
1498
+ (/\b(CGFloat|double|float|NSInteger|NSUInteger|NSTimeInterval|int|long)\b/.test(qualType) ||
1499
+ /\b(double|float|long|int|unsigned long)\b/.test(desugared));
1500
+
1501
+ if (!isConstNumeric) return;
1502
+
1503
+ const value = extractNumericValue(node);
1504
+ if (value === null) return;
1505
+
1506
+ // Determine if this is a float type
1507
+ const isFloat =
1508
+ /\b(CGFloat|double|float|NSTimeInterval)\b/.test(qualType) || /\b(double|float)\b/.test(desugared);
1509
+
1510
+ if (!constants.has(node.name)) {
1511
+ constants.set(node.name, {
1512
+ name: node.name,
1513
+ value,
1514
+ isFloat
1515
+ });
1516
+ }
1517
+ }
1518
+
1519
+ if (node.inner) {
1520
+ for (const child of node.inner) {
1521
+ walkForConstants(child);
1522
+ }
1523
+ }
1524
+ }
1525
+
1526
+ // First pass: find typed enum typedef IDs to exclude
1527
+ walkForTypedEnumTypedefs(root);
1528
+ // Second pass: find matching VarDecl constants
1529
+ walkForConstants(root);
1530
+
1531
+ return constants;
1532
+ }
1533
+
1402
1534
  // --- Struct parsing ---
1403
1535
 
1404
1536
  /**
@@ -15,6 +15,8 @@ export interface DiscoveryResult {
15
15
  integerEnums: Map<string, string>;
16
16
  /** Maps string enum name → header file name (without .h extension) */
17
17
  stringEnums: Map<string, string>;
18
+ /** Maps numeric constant name → header file name (without .h extension) */
19
+ numericConstants: Map<string, string>;
18
20
  }
19
21
 
20
22
  /** Matches `@interface ClassName` — captures class name */
@@ -58,6 +60,18 @@ const NS_INTEGER_TYPED_ENUM_RE = /typedef\s+NSU?Integer\s+(\w+)\s+NS_(?:TYPED_EX
58
60
  */
59
61
  const NS_ERROR_ENUM_RE = /typedef\s+NS_ERROR_ENUM\s*\(\s*\w+\s*,\s*(\w+)\s*\)/;
60
62
 
63
+ /**
64
+ * Matches standalone `static const` numeric variable declarations.
65
+ * These are constants like `NSVariableStatusItemLength`, `NSEventDurationForever`, etc.
66
+ * Captures the constant name from declarations like:
67
+ * `static const CGFloat NSVariableStatusItemLength = -1;`
68
+ * `static const NSInteger NSSearchFieldRecentsTitleMenuItemTag = 1000;`
69
+ * `static const CGFloat NSStackViewSpacingUseDefault API_AVAILABLE(macos(10.9)) = FLT_MAX;`
70
+ * Allows optional API_AVAILABLE / NS_AVAILABLE / etc. attributes between name and `=`.
71
+ */
72
+ const STATIC_CONST_NUMERIC_RE =
73
+ /static\s+(?:const\s+)?(?:CGFloat|double|float|NSInteger|NSUInteger|NSTimeInterval|int|long)\s+(?:const\s+)?(\w+)\b[^;]*=/;
74
+
61
75
  /**
62
76
  * Scan all .h files in a framework's Headers directory and discover
63
77
  * every ObjC class and protocol declaration, mapping each to its header file.
@@ -71,6 +85,7 @@ export async function discoverFramework(headersPath: string): Promise<DiscoveryR
71
85
  const protocols = new Map<string, string>();
72
86
  const integerEnums = new Map<string, string>();
73
87
  const stringEnums = new Map<string, string>();
88
+ const numericConstants = new Map<string, string>();
74
89
 
75
90
  const entries = await readdir(headersPath);
76
91
  const headerFiles = entries.filter((f) => f.endsWith(".h")).sort();
@@ -141,8 +156,18 @@ export async function discoverFramework(headersPath: string): Promise<DiscoveryR
141
156
  integerEnums.set(name, headerName);
142
157
  }
143
158
  }
159
+
160
+ // --- Standalone numeric constants ---
161
+ // e.g., `static const CGFloat NSVariableStatusItemLength = -1;`
162
+ const numericConstMatch = STATIC_CONST_NUMERIC_RE.exec(line);
163
+ if (numericConstMatch) {
164
+ const name = numericConstMatch[1]!;
165
+ if (!numericConstants.has(name)) {
166
+ numericConstants.set(name, headerName);
167
+ }
168
+ }
144
169
  }
145
170
  }
146
171
 
147
- return { classes, protocols, integerEnums, stringEnums };
172
+ return { classes, protocols, integerEnums, stringEnums, numericConstants };
148
173
  }
@@ -10,7 +10,8 @@ import type {
10
10
  ObjCIntegerEnum,
11
11
  ObjCStringEnum,
12
12
  ObjCStringEnumValue,
13
- ObjCFunction
13
+ ObjCFunction,
14
+ ObjCNumericConstant
14
15
  } from "./ast-parser.ts";
15
16
  import type { FrameworkConfig } from "./frameworks.ts";
16
17
  import {
@@ -1809,6 +1810,36 @@ export function emitFunctionsFile(
1809
1810
  return lines.join("\n");
1810
1811
  }
1811
1812
 
1813
+ /**
1814
+ * Generate a constants.ts file for a framework.
1815
+ * Emits `export const NAME: number = VALUE;` for each standalone numeric constant.
1816
+ *
1817
+ * Example output:
1818
+ * ```ts
1819
+ * // AUTO-GENERATED by objcjs-types generator — DO NOT EDIT
1820
+ *
1821
+ * export const NSVariableStatusItemLength: number = -1;
1822
+ * export const NSSquareStatusItemLength: number = -2;
1823
+ * ```
1824
+ */
1825
+ export function emitConstantsFile(constants: ObjCNumericConstant[]): string {
1826
+ const lines: string[] = [];
1827
+ lines.push(AUTOGEN_HEADER);
1828
+ lines.push("");
1829
+
1830
+ // Sort constants alphabetically for deterministic output
1831
+ const sorted = [...constants].sort((a, b) => a.name.localeCompare(b.name));
1832
+
1833
+ for (const constant of sorted) {
1834
+ // Format the value: use integer representation when possible for cleaner output
1835
+ const valueStr = Number.isInteger(constant.value) ? String(constant.value) : String(constant.value);
1836
+ lines.push(`export const ${constant.name}: number = ${valueStr};`);
1837
+ }
1838
+ lines.push("");
1839
+
1840
+ return lines.join("\n");
1841
+ }
1842
+
1812
1843
  /**
1813
1844
  * Extract class, struct, and enum references from a mapped TS type string
1814
1845
  * (used by emitFunctionsFile for collecting imports).
@@ -1878,7 +1909,7 @@ export function emitFrameworkIndex(
1878
1909
  // as the framework (e.g. IOSurface framework has an IOSurface class)
1879
1910
  const classNames = new Set(generatedClasses);
1880
1911
  const libVar = classNames.has(framework.name) ? `${framework.name}_lib` : framework.name;
1881
- lines.push(`export const ${libVar} = new NobjcLibrary("${framework.libraryPath}");`);
1912
+ lines.push(`export const ${libVar} = /* @__PURE__ */ new NobjcLibrary("${framework.libraryPath}");`);
1882
1913
  lines.push("");
1883
1914
 
1884
1915
  // Build a reverse lookup: className → canonical filename for collision groups
@@ -1894,7 +1925,7 @@ export function emitFrameworkIndex(
1894
1925
  for (const className of generatedClasses) {
1895
1926
  const fileName = classToFile.get(className) ?? className;
1896
1927
  lines.push(`import type { _${className} } from "./${fileName}.js";`);
1897
- lines.push(`export const ${className} = _bindClass<typeof _${className}>(${libVar}, "${className}");`);
1928
+ lines.push(`export const ${className} = /* @__PURE__ */ _bindClass<typeof _${className}>(${libVar}, "${className}");`);
1898
1929
  lines.push(`export type { _${className} };`);
1899
1930
  lines.push("");
1900
1931
  }
@@ -31,6 +31,8 @@ export interface FrameworkConfig extends FrameworkBase {
31
31
  integerEnums: string[];
32
32
  /** All discovered string enum names (NS_TYPED_EXTENSIBLE_ENUM etc.) */
33
33
  stringEnums: string[];
34
+ /** All discovered standalone numeric constant names */
35
+ numericConstants: string[];
34
36
  /** Maps class name → header file name (without .h) */
35
37
  classHeaders: Map<string, string>;
36
38
  /** Maps protocol name → header file name (without .h) */
@@ -39,6 +41,8 @@ export interface FrameworkConfig extends FrameworkBase {
39
41
  integerEnumHeaders: Map<string, string>;
40
42
  /** Maps string enum name → header file name (without .h) */
41
43
  stringEnumHeaders: Map<string, string>;
44
+ /** Maps numeric constant name → header file name (without .h) */
45
+ numericConstantHeaders: Map<string, string>;
42
46
  }
43
47
 
44
48
  export const SDK_PATH =
@@ -24,7 +24,8 @@ import type {
24
24
  ObjCStringEnum,
25
25
  ObjCStruct,
26
26
  ObjCStructAlias,
27
- ObjCFunction
27
+ ObjCFunction,
28
+ ObjCNumericConstant
28
29
  } from "./ast-parser.ts";
29
30
  import {
30
31
  setKnownClasses,
@@ -51,6 +52,7 @@ import {
51
52
  emitIntegerEnumFile,
52
53
  emitStringEnumFile,
53
54
  emitFunctionsFile,
55
+ emitConstantsFile,
54
56
  groupCaseCollisions
55
57
  } from "./emitter.ts";
56
58
  import type { StructDef, StructFieldDef } from "./emitter.ts";
@@ -123,7 +125,8 @@ async function main(): Promise<void> {
123
125
  discovery.classes.size === 0 &&
124
126
  discovery.protocols.size === 0 &&
125
127
  discovery.integerEnums.size === 0 &&
126
- discovery.stringEnums.size === 0
128
+ discovery.stringEnums.size === 0 &&
129
+ discovery.numericConstants.size === 0
127
130
  )
128
131
  continue;
129
132
 
@@ -133,15 +136,20 @@ async function main(): Promise<void> {
133
136
  protocols: [...discovery.protocols.keys()].sort(),
134
137
  integerEnums: [...discovery.integerEnums.keys()].sort(),
135
138
  stringEnums: [...discovery.stringEnums.keys()].sort(),
139
+ numericConstants: [...discovery.numericConstants.keys()].sort(),
136
140
  classHeaders: discovery.classes,
137
141
  protocolHeaders: discovery.protocols,
138
142
  integerEnumHeaders: discovery.integerEnums,
139
- stringEnumHeaders: discovery.stringEnums
143
+ stringEnumHeaders: discovery.stringEnums,
144
+ numericConstantHeaders: discovery.numericConstants
140
145
  };
141
146
  frameworks.push(fw);
142
147
 
143
148
  const enumCount = fw.integerEnums.length + fw.stringEnums.length;
144
- console.log(` ${fw.name}: ${fw.classes.length} classes, ${fw.protocols.length} protocols, ${enumCount} enums`);
149
+ const constStr = fw.numericConstants.length > 0 ? `, ${fw.numericConstants.length} constants` : "";
150
+ console.log(
151
+ ` ${fw.name}: ${fw.classes.length} classes, ${fw.protocols.length} protocols, ${enumCount} enums${constStr}`
152
+ );
145
153
  }
146
154
  const discoveryTime = ((performance.now() - globalStart) / 1000).toFixed(1);
147
155
  console.log(` Discovery completed in ${discoveryTime}s\n`);
@@ -209,6 +217,7 @@ async function main(): Promise<void> {
209
217
  protocolTargets: string[];
210
218
  integerEnumTargets: string[];
211
219
  stringEnumTargets: string[];
220
+ numericConstantTargets: string[];
212
221
  preIncludes: string[];
213
222
  }
214
223
 
@@ -239,6 +248,7 @@ async function main(): Promise<void> {
239
248
  const protocolTargets: string[] = [];
240
249
  const integerEnumTargets: string[] = [];
241
250
  const stringEnumTargets: string[] = [];
251
+ const numericConstantTargets: string[] = [];
242
252
 
243
253
  // --- Class targets ---
244
254
  for (const className of fw.classes) {
@@ -284,13 +294,21 @@ async function main(): Promise<void> {
284
294
  stringEnumTargets.push(enumName);
285
295
  }
286
296
 
297
+ // --- Numeric constant targets ---
298
+ // No header validation needed — constants are discovered from the same headers
299
+ // that are already included in allFrameworkHeaders.
300
+ for (const constName of fw.numericConstants) {
301
+ numericConstantTargets.push(constName);
302
+ }
303
+
287
304
  // Only create a batch task if there are targets to parse
288
305
  if (
289
306
  allFrameworkHeaders.length > 0 &&
290
307
  (classTargets.length > 0 ||
291
308
  protocolTargets.length > 0 ||
292
309
  integerEnumTargets.length > 0 ||
293
- stringEnumTargets.length > 0)
310
+ stringEnumTargets.length > 0 ||
311
+ numericConstantTargets.length > 0)
294
312
  ) {
295
313
  batchTasks.push({
296
314
  frameworkName: fw.name,
@@ -299,6 +317,7 @@ async function main(): Promise<void> {
299
317
  protocolTargets,
300
318
  integerEnumTargets,
301
319
  stringEnumTargets,
320
+ numericConstantTargets,
302
321
  preIncludes
303
322
  });
304
323
  }
@@ -365,7 +384,8 @@ async function main(): Promise<void> {
365
384
  task.integerEnumTargets,
366
385
  task.stringEnumTargets,
367
386
  task.preIncludes,
368
- task.frameworkName
387
+ task.frameworkName,
388
+ task.numericConstantTargets
369
389
  )
370
390
  .then((result) => {
371
391
  trackProgress(task.frameworkName);
@@ -544,6 +564,22 @@ async function main(): Promise<void> {
544
564
  }
545
565
  }
546
566
 
567
+ // Organize parsed numeric constants by framework
568
+ const frameworkNumericConstants = new Map<string, Map<string, ObjCNumericConstant>>();
569
+ for (const entry of allResults) {
570
+ if (entry.isExtra) continue;
571
+ if (entry.error || !entry.result) continue;
572
+ if (entry.result.numericConstants.size === 0) continue;
573
+
574
+ if (!frameworkNumericConstants.has(entry.task.frameworkName)) {
575
+ frameworkNumericConstants.set(entry.task.frameworkName, new Map());
576
+ }
577
+ const fwConsts = frameworkNumericConstants.get(entry.task.frameworkName)!;
578
+ for (const [name, constant] of entry.result.numericConstants) {
579
+ fwConsts.set(name, constant);
580
+ }
581
+ }
582
+
547
583
  // Collect all parsed structs and struct aliases across all headers
548
584
  const allParsedStructs = new Map<string, ObjCStruct>();
549
585
  const allStructAliases: ObjCStructAlias[] = [];
@@ -1228,6 +1264,15 @@ async function main(): Promise<void> {
1228
1264
  hasFunctions = true;
1229
1265
  }
1230
1266
 
1267
+ // Emit constants file (standalone numeric constants)
1268
+ const fwConsts = frameworkNumericConstants.get(framework.name);
1269
+ let hasConstants = false;
1270
+ if (fwConsts && fwConsts.size > 0) {
1271
+ const constantsContent = emitConstantsFile([...fwConsts.values()]);
1272
+ await writeFile(join(frameworkDir, "constants.ts"), constantsContent);
1273
+ hasConstants = true;
1274
+ }
1275
+
1231
1276
  // Emit framework index
1232
1277
  const indexContent = emitFrameworkIndex(
1233
1278
  framework,
@@ -1246,8 +1291,9 @@ async function main(): Promise<void> {
1246
1291
  const totalEnumCount =
1247
1292
  generatedIntegerEnums.length + generatedStringEnums.length + generatedStringEnumsTypeOnly.length;
1248
1293
  const funcCountStr = hasFunctions ? ` + ${fwFuncs!.size} functions` : "";
1294
+ const constCountStr = hasConstants ? ` + ${fwConsts!.size} constants` : "";
1249
1295
  console.log(
1250
- ` ${framework.name}: ${generatedClasses.length} class files + ${generatedProtocols.length} protocol files + ${totalEnumCount} enum files${funcCountStr} + index.ts`
1296
+ ` ${framework.name}: ${generatedClasses.length} class files + ${generatedProtocols.length} protocol files + ${totalEnumCount} enum files${funcCountStr}${constCountStr} + index.ts`
1251
1297
  );
1252
1298
  }
1253
1299
 
@@ -1307,21 +1353,27 @@ async function main(): Promise<void> {
1307
1353
  let totalProtocols = 0;
1308
1354
  let totalEnums = 0;
1309
1355
  let totalFunctions = 0;
1356
+ let totalConstants = 0;
1310
1357
  for (const fw of frameworksToProcess) {
1311
1358
  const dir = join(SRC_DIR, fw.name);
1312
1359
  const classCount = fw.classes.filter((c) => existsSync(join(dir, `${c}.ts`))).length;
1313
1360
  const protoCount = fw.protocols.filter((p) => existsSync(join(dir, `${p}.ts`))).length;
1314
1361
  const enumCount = [...fw.integerEnums, ...fw.stringEnums].filter((e) => existsSync(join(dir, `${e}.ts`))).length;
1315
1362
  const funcCount = frameworkFunctions.get(fw.name)?.size ?? 0;
1363
+ const constCount = frameworkNumericConstants.get(fw.name)?.size ?? 0;
1316
1364
  const funcStr = funcCount > 0 ? `, ${funcCount} functions` : "";
1317
- console.log(` ${fw.name}: ${classCount} classes, ${protoCount} protocols, ${enumCount} enums${funcStr}`);
1365
+ const constStr = constCount > 0 ? `, ${constCount} constants` : "";
1366
+ console.log(
1367
+ ` ${fw.name}: ${classCount} classes, ${protoCount} protocols, ${enumCount} enums${funcStr}${constStr}`
1368
+ );
1318
1369
  totalClasses += classCount;
1319
1370
  totalProtocols += protoCount;
1320
1371
  totalEnums += enumCount;
1321
1372
  totalFunctions += funcCount;
1373
+ totalConstants += constCount;
1322
1374
  }
1323
1375
  console.log(
1324
- ` Total: ${totalClasses} classes, ${totalProtocols} protocols, ${totalEnums} enums, ${totalFunctions} functions`
1376
+ ` Total: ${totalClasses} classes, ${totalProtocols} protocols, ${totalEnums} enums, ${totalFunctions} functions, ${totalConstants} constants`
1325
1377
  );
1326
1378
 
1327
1379
  // Clean up the compiled ObjC helper binary
@@ -18,7 +18,8 @@ import {
18
18
  parseStringEnums,
19
19
  parseStructs,
20
20
  parseTypedefs,
21
- parseFunctions
21
+ parseFunctions,
22
+ parseNumericConstants
22
23
  } from "./ast-parser.ts";
23
24
 
24
25
  /**
@@ -95,6 +96,10 @@ self.onmessage = async (event: MessageEvent) => {
95
96
  const frameworkHeaderPathSet = new Set<string>(headerPaths);
96
97
  const functions = parseFunctions(ast, frameworkHeaderPathSet, msg.frameworkName ?? "");
97
98
 
99
+ // Parse standalone numeric constants
100
+ const numericConstantTargetSet = new Set<string>(msg.numericConstantTargets ?? []);
101
+ const numericConstants = parseNumericConstants(ast, numericConstantTargetSet);
102
+
98
103
  postMessage({
99
104
  id: msg.id,
100
105
  type: "batch-result",
@@ -106,6 +111,7 @@ self.onmessage = async (event: MessageEvent) => {
106
111
  structAliases: structResult.aliases,
107
112
  typedefs: [...typedefs.entries()],
108
113
  functions: [...functions.entries()],
114
+ numericConstants: [...numericConstants.entries()],
109
115
  // Report what was found vs expected for logging
110
116
  foundClasses: classes.size,
111
117
  foundProtocols: protocols.size,
@@ -209,7 +215,8 @@ self.onmessage = async (event: MessageEvent) => {
209
215
  structs: [...structResult.structs.entries()],
210
216
  structAliases: structResult.aliases,
211
217
  typedefs: [...typedefs.entries()],
212
- functions: [] // parse-all is used for extra headers which don't need function parsing
218
+ functions: [], // parse-all is used for extra headers which don't need function parsing
219
+ numericConstants: [] // parse-all is used for extra headers which don't need constant parsing
213
220
  });
214
221
  } else if (msg.type === "parse-classes") {
215
222
  const targetSet = new Set<string>(msg.targets);
@@ -14,7 +14,8 @@ import type {
14
14
  ObjCStringEnum,
15
15
  ObjCStruct,
16
16
  ObjCStructAlias,
17
- ObjCFunction
17
+ ObjCFunction,
18
+ ObjCNumericConstant
18
19
  } from "./ast-parser.ts";
19
20
 
20
21
  /** Result from a unified parse-all task (classes + protocols + enums + structs from one clang invocation) */
@@ -35,6 +36,8 @@ export interface UnifiedParseResult {
35
36
  typedefs: Map<string, string>;
36
37
  /** Parsed C function declarations (function name → ObjCFunction) */
37
38
  functions: Map<string, ObjCFunction>;
39
+ /** Parsed standalone numeric constants (constant name → ObjCNumericConstant) */
40
+ numericConstants: Map<string, ObjCNumericConstant>;
38
41
  }
39
42
 
40
43
  export interface ClassParseResult {
@@ -248,7 +251,8 @@ export class WorkerPool {
248
251
  structs: new Map(result.structs ?? []),
249
252
  structAliases: result.structAliases ?? [],
250
253
  typedefs: new Map(result.typedefs ?? []),
251
- functions: new Map(result.functions ?? [])
254
+ functions: new Map(result.functions ?? []),
255
+ numericConstants: new Map(result.numericConstants ?? [])
252
256
  };
253
257
  }
254
258
 
@@ -271,7 +275,8 @@ export class WorkerPool {
271
275
  integerEnumTargets: string[],
272
276
  stringEnumTargets: string[],
273
277
  preIncludes: string[],
274
- frameworkName?: string
278
+ frameworkName?: string,
279
+ numericConstantTargets?: string[]
275
280
  ): Promise<UnifiedParseResult> {
276
281
  const result = await this.dispatch({
277
282
  id: this.nextId++,
@@ -282,7 +287,8 @@ export class WorkerPool {
282
287
  integerEnumTargets,
283
288
  stringEnumTargets,
284
289
  preIncludes,
285
- frameworkName
290
+ frameworkName,
291
+ numericConstantTargets
286
292
  });
287
293
  return {
288
294
  classes: new Map(result.classes),
@@ -292,7 +298,8 @@ export class WorkerPool {
292
298
  structs: new Map(result.structs ?? []),
293
299
  structAliases: result.structAliases ?? [],
294
300
  typedefs: new Map(result.typedefs ?? []),
295
- functions: new Map(result.functions ?? [])
301
+ functions: new Map(result.functions ?? []),
302
+ numericConstants: new Map(result.numericConstants ?? [])
296
303
  };
297
304
  }
298
305
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "objcjs-types",
3
- "version": "0.5.1",
4
- "description": "Auto-generated TypeScript type declarations for macOS Objective-C frameworks",
3
+ "version": "0.5.2",
4
+ "description": "Auto-generated TypeScript type declarations for macOS Objective-C frameworks that supplement objc-js",
5
5
  "type": "module",
6
+ "sideEffects": false,
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "exports": {
@@ -33,6 +34,10 @@
33
34
  "./*/functions": {
34
35
  "types": "./dist/*/functions.d.ts",
35
36
  "default": "./dist/*/functions.js"
37
+ },
38
+ "./*/constants": {
39
+ "types": "./dist/*/constants.d.ts",
40
+ "default": "./dist/*/constants.js"
36
41
  }
37
42
  },
38
43
  "files": [
@@ -63,7 +68,7 @@
63
68
  ],
64
69
  "license": "MIT",
65
70
  "peerDependencies": {
66
- "objc-js": "^1.1.0",
71
+ "objc-js": "^1.3.1",
67
72
  "typescript": "^5"
68
73
  },
69
74
  "devDependencies": {