@gtkx/codegen 1.2.2 → 1.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.
Files changed (199) hide show
  1. package/README.md +2 -1
  2. package/dist/analysis/descriptor-render.d.ts +7 -1
  3. package/dist/analysis/descriptor-render.d.ts.map +1 -1
  4. package/dist/analysis/descriptor-render.js +36 -15
  5. package/dist/analysis/descriptor-render.js.map +1 -1
  6. package/dist/analysis/descriptor.d.ts +4 -1
  7. package/dist/analysis/descriptor.d.ts.map +1 -1
  8. package/dist/analysis/descriptor.js +11 -2
  9. package/dist/analysis/descriptor.js.map +1 -1
  10. package/dist/analysis/param-capability.d.ts +5 -2
  11. package/dist/analysis/param-capability.d.ts.map +1 -1
  12. package/dist/analysis/param-capability.js +36 -4
  13. package/dist/analysis/param-capability.js.map +1 -1
  14. package/dist/analysis/param-structure.d.ts +1 -1
  15. package/dist/analysis/param-structure.d.ts.map +1 -1
  16. package/dist/analysis/param-structure.js.map +1 -1
  17. package/dist/analysis/ts-type.d.ts +1 -1
  18. package/dist/analysis/ts-type.d.ts.map +1 -1
  19. package/dist/analysis/ts-type.js +28 -10
  20. package/dist/analysis/ts-type.js.map +1 -1
  21. package/dist/compile.js +1 -1
  22. package/dist/compile.js.map +1 -1
  23. package/dist/docs/api-reference.d.ts +6 -0
  24. package/dist/docs/api-reference.d.ts.map +1 -1
  25. package/dist/docs/api-reference.js +11 -2
  26. package/dist/docs/api-reference.js.map +1 -1
  27. package/dist/docs/pipeline.d.ts +3 -0
  28. package/dist/docs/pipeline.d.ts.map +1 -1
  29. package/dist/docs/pipeline.js +10 -1
  30. package/dist/docs/pipeline.js.map +1 -1
  31. package/dist/fingerprint.d.ts +5 -0
  32. package/dist/fingerprint.d.ts.map +1 -1
  33. package/dist/fingerprint.js +107 -15
  34. package/dist/fingerprint.js.map +1 -1
  35. package/dist/gi.d.ts +3 -0
  36. package/dist/gi.d.ts.map +1 -1
  37. package/dist/gi.js +29 -7
  38. package/dist/gi.js.map +1 -1
  39. package/dist/gir/external-namespaces.d.ts +8 -0
  40. package/dist/gir/external-namespaces.d.ts.map +1 -0
  41. package/dist/gir/external-namespaces.js +4 -0
  42. package/dist/gir/external-namespaces.js.map +1 -0
  43. package/dist/gir/finish-overrides.d.ts +3 -0
  44. package/dist/gir/finish-overrides.d.ts.map +1 -0
  45. package/dist/gir/finish-overrides.js +5 -0
  46. package/dist/gir/finish-overrides.js.map +1 -0
  47. package/dist/gir/function.d.ts +5 -2
  48. package/dist/gir/function.d.ts.map +1 -1
  49. package/dist/gir/function.js +34 -5
  50. package/dist/gir/function.js.map +1 -1
  51. package/dist/gir/hidden-symbols.d.ts +3 -0
  52. package/dist/gir/hidden-symbols.d.ts.map +1 -0
  53. package/dist/gir/hidden-symbols.js +39 -0
  54. package/dist/gir/hidden-symbols.js.map +1 -0
  55. package/dist/gir/library.d.ts +22 -2
  56. package/dist/gir/library.d.ts.map +1 -1
  57. package/dist/gir/library.js +21 -3
  58. package/dist/gir/library.js.map +1 -1
  59. package/dist/gir/ucs4-overrides.d.ts +3 -0
  60. package/dist/gir/ucs4-overrides.d.ts.map +1 -0
  61. package/dist/gir/ucs4-overrides.js +7 -0
  62. package/dist/gir/ucs4-overrides.js.map +1 -0
  63. package/dist/jsx.d.ts.map +1 -1
  64. package/dist/jsx.js +27 -8
  65. package/dist/jsx.js.map +1 -1
  66. package/dist/runner.d.ts +8 -0
  67. package/dist/runner.d.ts.map +1 -1
  68. package/dist/runner.js +9 -3
  69. package/dist/runner.js.map +1 -1
  70. package/dist/store/external-package-links.d.ts +6 -0
  71. package/dist/store/external-package-links.d.ts.map +1 -0
  72. package/dist/store/external-package-links.js +158 -0
  73. package/dist/store/external-package-links.js.map +1 -0
  74. package/dist/store/gi/callable-doc.d.ts.map +1 -1
  75. package/dist/store/gi/callable-doc.js +4 -4
  76. package/dist/store/gi/callable-doc.js.map +1 -1
  77. package/dist/store/gi/callables.js +1 -1
  78. package/dist/store/gi/callables.js.map +1 -1
  79. package/dist/store/gi/class.d.ts.map +1 -1
  80. package/dist/store/gi/class.js +17 -0
  81. package/dist/store/gi/class.js.map +1 -1
  82. package/dist/store/gi/constructor-props.js +1 -1
  83. package/dist/store/gi/constructor-props.js.map +1 -1
  84. package/dist/store/gi/function.d.ts.map +1 -1
  85. package/dist/store/gi/function.js +2 -1
  86. package/dist/store/gi/function.js.map +1 -1
  87. package/dist/store/gi/gtype-binding.d.ts +2 -1
  88. package/dist/store/gi/gtype-binding.d.ts.map +1 -1
  89. package/dist/store/gi/gtype-binding.js +6 -1
  90. package/dist/store/gi/gtype-binding.js.map +1 -1
  91. package/dist/store/gi/method.d.ts +7 -2
  92. package/dist/store/gi/method.d.ts.map +1 -1
  93. package/dist/store/gi/method.js +126 -30
  94. package/dist/store/gi/method.js.map +1 -1
  95. package/dist/store/gi/param-marshal.d.ts +8 -1
  96. package/dist/store/gi/param-marshal.d.ts.map +1 -1
  97. package/dist/store/gi/param-marshal.js +52 -4
  98. package/dist/store/gi/param-marshal.js.map +1 -1
  99. package/dist/store/gi/record-constructor.d.ts.map +1 -1
  100. package/dist/store/gi/record-constructor.js +2 -3
  101. package/dist/store/gi/record-constructor.js.map +1 -1
  102. package/dist/store/gi/record-field-accessor.d.ts +2 -1
  103. package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
  104. package/dist/store/gi/record-field-accessor.js +9 -3
  105. package/dist/store/gi/record-field-accessor.js.map +1 -1
  106. package/dist/store/gi/runtime-override.js +1 -1
  107. package/dist/store/gi/runtime-override.js.map +1 -1
  108. package/dist/store/gi/signal.js +2 -2
  109. package/dist/store/gi/signal.js.map +1 -1
  110. package/dist/store/gi/vtable.d.ts.map +1 -1
  111. package/dist/store/gi/vtable.js +82 -12
  112. package/dist/store/gi/vtable.js.map +1 -1
  113. package/dist/store/gi-store.d.ts +7 -2
  114. package/dist/store/gi-store.d.ts.map +1 -1
  115. package/dist/store/gi-store.js +19 -4
  116. package/dist/store/gi-store.js.map +1 -1
  117. package/dist/store/jsx/jsx.d.ts.map +1 -1
  118. package/dist/store/jsx/jsx.js +3 -1
  119. package/dist/store/jsx/jsx.js.map +1 -1
  120. package/dist/store/jsx-store.d.ts +8 -1
  121. package/dist/store/jsx-store.d.ts.map +1 -1
  122. package/dist/store/jsx-store.js +9 -2
  123. package/dist/store/jsx-store.js.map +1 -1
  124. package/dist/store/resolve-store.d.ts +2 -1
  125. package/dist/store/resolve-store.d.ts.map +1 -1
  126. package/dist/store/resolve-store.js +2 -1
  127. package/dist/store/resolve-store.js.map +1 -1
  128. package/dist/store/store-fs.d.ts +2 -1
  129. package/dist/store/store-fs.d.ts.map +1 -1
  130. package/dist/store/store-fs.js +8 -3
  131. package/dist/store/store-fs.js.map +1 -1
  132. package/dist/writer/context.d.ts.map +1 -1
  133. package/dist/writer/context.js +8 -0
  134. package/dist/writer/context.js.map +1 -1
  135. package/dist/writer/gtk-doc.d.ts.map +1 -1
  136. package/dist/writer/gtk-doc.js +27 -1
  137. package/dist/writer/gtk-doc.js.map +1 -1
  138. package/overrides/gdk/rgba.ts.ejs +15 -1
  139. package/overrides/glib/index.ts.ejs +3 -0
  140. package/overrides/glib/regex.ts.ejs +66 -0
  141. package/overrides/gobject/index.ts.ejs +3 -0
  142. package/overrides/gobject/object-class.ts.ejs +27 -0
  143. package/overrides/gobject/param-spec-getters.ts.ejs +57 -0
  144. package/overrides/gobject/param-spec.ts.ejs +21 -0
  145. package/overrides/gobject/value.ts.ejs +6 -1
  146. package/overrides/graphene/structs.ts.ejs +38 -3
  147. package/overrides/gtk/index.ts.ejs +2 -0
  148. package/overrides/gtk/widget-class.ts.ejs +28 -0
  149. package/package.json +6 -5
  150. package/src/analysis/descriptor-render.ts +59 -16
  151. package/src/analysis/descriptor.ts +15 -3
  152. package/src/analysis/param-capability.ts +68 -5
  153. package/src/analysis/param-structure.ts +1 -1
  154. package/src/analysis/ts-type.ts +45 -11
  155. package/src/compile.ts +1 -1
  156. package/src/docs/api-reference.ts +20 -2
  157. package/src/docs/pipeline.ts +15 -1
  158. package/src/fingerprint.ts +144 -16
  159. package/src/gi.ts +44 -9
  160. package/src/gir/external-namespaces.ts +8 -0
  161. package/src/gir/finish-overrides.ts +5 -0
  162. package/src/gir/function.ts +52 -14
  163. package/src/gir/hidden-symbols.ts +39 -0
  164. package/src/gir/library.ts +36 -3
  165. package/src/gir/ucs4-overrides.ts +7 -0
  166. package/src/jsx.ts +33 -8
  167. package/src/runner.ts +17 -3
  168. package/src/store/external-package-links.ts +226 -0
  169. package/src/store/gi/callable-doc.ts +8 -4
  170. package/src/store/gi/callables.ts +1 -1
  171. package/src/store/gi/class.ts +29 -0
  172. package/src/store/gi/constructor-props.ts +1 -1
  173. package/src/store/gi/function.ts +2 -1
  174. package/src/store/gi/gtype-binding.ts +8 -1
  175. package/src/store/gi/method.ts +189 -36
  176. package/src/store/gi/param-marshal.ts +67 -4
  177. package/src/store/gi/record-constructor.ts +8 -3
  178. package/src/store/gi/record-field-accessor.ts +11 -2
  179. package/src/store/gi/runtime-override.ts +1 -1
  180. package/src/store/gi/signal.ts +2 -2
  181. package/src/store/gi/vtable.ts +118 -11
  182. package/src/store/gi-store.ts +33 -3
  183. package/src/store/jsx/jsx.ts +3 -1
  184. package/src/store/jsx-store.ts +23 -7
  185. package/src/store/resolve-store.ts +2 -1
  186. package/src/store/store-fs.ts +10 -2
  187. package/src/writer/context.ts +11 -0
  188. package/src/writer/gtk-doc.ts +38 -1
  189. package/overrides/cairo/context.ts.ejs +0 -1269
  190. package/overrides/cairo/font-face.ts.ejs +0 -151
  191. package/overrides/cairo/font-options.ts.ejs +0 -199
  192. package/overrides/cairo/image-surface.ts.ejs +0 -132
  193. package/overrides/cairo/index.ts.ejs +0 -22
  194. package/overrides/cairo/matrix.ts.ejs +0 -171
  195. package/overrides/cairo/pattern.ts.ejs +0 -476
  196. package/overrides/cairo/recording-surface.ts.ejs +0 -102
  197. package/overrides/cairo/region.ts.ejs +0 -237
  198. package/overrides/cairo/scaled-font.ts.ejs +0 -330
  199. package/overrides/cairo/surface.ts.ejs +0 -296
@@ -0,0 +1,226 @@
1
+ import { existsSync, readFileSync, realpathSync, rmSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join } from "node:path";
4
+ import { EXTERNAL_NAMESPACES, type ExternalNamespace } from "../gir/external-namespaces.js";
5
+ import { nodeModulesChain } from "./resolve-store.js";
6
+ import { type StoreLink, symlinkRelative } from "./store-fs.js";
7
+
8
+ type ExternalPackageSource = "store" | "hoisted" | "codegen";
9
+
10
+ type ExternalPackageResolution = {
11
+ packageName: string;
12
+ directory: string;
13
+ dir: string;
14
+ source: ExternalPackageSource;
15
+ };
16
+
17
+ const DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
18
+ const codegenRequire = createRequire(import.meta.url);
19
+ const codegenPackageDirs: Map<string, string | undefined> = new Map();
20
+ const ensuredStores: Set<string> = new Set();
21
+
22
+ const storeAnchor = (link: StoreLink): string => dirname(dirname(link.linkDir));
23
+ const namespaceShimDirectory = (entry: ExternalNamespace): string => entry.namespace.toLowerCase();
24
+
25
+ const resolveFromStore = (link: StoreLink, packageName: string): string | undefined => {
26
+ const chain = nodeModulesChain(dirname(storeAnchor(link)));
27
+
28
+ for (const nodeModules of chain) {
29
+ const manifest = join(nodeModules, packageName, "package.json");
30
+
31
+ if (existsSync(manifest)) {
32
+ return dirname(realpathSync(manifest));
33
+ }
34
+ }
35
+
36
+ return undefined;
37
+ };
38
+
39
+ const projectManifestPath = (link: StoreLink): string => join(dirname(storeAnchor(link)), "package.json");
40
+
41
+ const readManifest = (manifestPath: string): Record<string, unknown> | undefined => {
42
+ try {
43
+ return JSON.parse(readFileSync(manifestPath, "utf8")) as Record<string, unknown>;
44
+ } catch {
45
+ return undefined;
46
+ }
47
+ };
48
+
49
+ const sectionNames = (section: unknown): string[] =>
50
+ typeof section === "object" && section !== null ? Object.keys(section) : [];
51
+
52
+ const declaredDependencies = (manifest: Record<string, unknown>): Set<string> =>
53
+ new Set(DEPENDENCY_FIELDS.flatMap((field) => sectionNames(manifest[field])));
54
+
55
+ const isDeclaredByProject = (link: StoreLink, packageName: string): boolean => {
56
+ const manifest = readManifest(projectManifestPath(link));
57
+
58
+ return manifest === undefined || declaredDependencies(manifest).has(packageName);
59
+ };
60
+
61
+ const resolveFromCodegen = (packageName: string): string | undefined => {
62
+ if (codegenPackageDirs.has(packageName)) {
63
+ return codegenPackageDirs.get(packageName);
64
+ }
65
+
66
+ let dir: string | undefined;
67
+
68
+ try {
69
+ dir = dirname(realpathSync(codegenRequire.resolve(`${packageName}/package.json`)));
70
+ } catch {
71
+ dir = undefined;
72
+ }
73
+
74
+ codegenPackageDirs.set(packageName, dir);
75
+
76
+ return dir;
77
+ };
78
+
79
+ const resolveEntry = (link: StoreLink, entry: ExternalNamespace): ExternalPackageResolution | undefined => {
80
+ const directory = namespaceShimDirectory(entry);
81
+ const chainResolved = resolveFromStore(link, entry.packageName);
82
+
83
+ if (chainResolved !== undefined) {
84
+ const source = isDeclaredByProject(link, entry.packageName) ? "store" : "hoisted";
85
+
86
+ return { packageName: entry.packageName, directory, dir: chainResolved, source };
87
+ }
88
+
89
+ const codegenDir = resolveFromCodegen(entry.packageName);
90
+
91
+ if (codegenDir !== undefined) {
92
+ return { packageName: entry.packageName, directory, dir: codegenDir, source: "codegen" };
93
+ }
94
+
95
+ return undefined;
96
+ };
97
+
98
+ const resolveExternalPackages = (link: StoreLink): ExternalPackageResolution[] => {
99
+ const resolutions: ExternalPackageResolution[] = [];
100
+
101
+ for (const entry of EXTERNAL_NAMESPACES) {
102
+ const resolution = resolveEntry(link, entry);
103
+
104
+ if (resolution !== undefined) {
105
+ resolutions.push(resolution);
106
+ }
107
+ }
108
+
109
+ return resolutions;
110
+ };
111
+
112
+ const isLinkedTo = (linkPath: string, dir: string): boolean => {
113
+ try {
114
+ return realpathSync(linkPath) === realpathSync(dir);
115
+ } catch {
116
+ return false;
117
+ }
118
+ };
119
+
120
+ const applyLink = (storeDir: string, resolution: ExternalPackageResolution): void => {
121
+ const linkPath = join(storeDir, "node_modules", resolution.packageName);
122
+
123
+ if (resolution.source === "codegen") {
124
+ if (!isLinkedTo(linkPath, resolution.dir)) {
125
+ symlinkRelative(linkPath, resolution.dir);
126
+ }
127
+
128
+ return;
129
+ }
130
+
131
+ rmSync(linkPath, { recursive: true, force: true });
132
+ };
133
+
134
+ const tryApplyLink = (storeDir: string, resolution: ExternalPackageResolution): void => {
135
+ try {
136
+ applyLink(storeDir, resolution);
137
+ } catch {
138
+ return;
139
+ }
140
+ };
141
+
142
+ const ensureExternalPackageLinks = (link: StoreLink): void => {
143
+ if (ensuredStores.has(link.storeDir)) {
144
+ return;
145
+ }
146
+
147
+ if (!existsSync(join(link.storeDir, "package.json"))) {
148
+ return;
149
+ }
150
+
151
+ for (const resolution of resolveExternalPackages(link)) {
152
+ tryApplyLink(link.storeDir, resolution);
153
+ }
154
+
155
+ ensuredStores.add(link.storeDir);
156
+ };
157
+
158
+ const resetExternalPackageLinks = (storeDir: string): void => {
159
+ ensuredStores.delete(storeDir);
160
+ };
161
+
162
+ const externalPackageNotice = (resolution: ExternalPackageResolution): string =>
163
+ `${resolution.packageName} is not installed in this project, so the copy @gtkx/codegen depends on was ` +
164
+ `linked into the generated store; add ${resolution.packageName} to your dependencies, because GTKX 2.0 ` +
165
+ "stops doing this.";
166
+
167
+ const hoistedPackageNotice = (resolution: ExternalPackageResolution): string =>
168
+ `${resolution.packageName} is not declared in this project's package.json and only resolves because ` +
169
+ `your package manager hoisted it; add ${resolution.packageName} to your dependencies, because GTKX 2.0 ` +
170
+ "requires the direct dependency.";
171
+
172
+ const hasShim = (storeDir: string, entry: ExternalNamespace): boolean =>
173
+ existsSync(join(storeDir, namespaceShimDirectory(entry), "index.js"));
174
+
175
+ const hasStoreLocalLink = (storeDir: string, packageName: string): boolean =>
176
+ existsSync(join(storeDir, "node_modules", packageName, "package.json"));
177
+
178
+ const unresolvableMessage = (link: StoreLink, entry: ExternalNamespace): string =>
179
+ `Cannot resolve ${entry.packageName} from ${storeAnchor(link)} or from @gtkx/codegen; ` +
180
+ "install it next to @gtkx/runtime.";
181
+
182
+ const linkFailedMessage = (link: StoreLink, entry: ExternalNamespace): string =>
183
+ `Cannot link ${entry.packageName} into the generated store at ${link.storeDir}; ` +
184
+ `install ${entry.packageName} next to @gtkx/runtime.`;
185
+
186
+ const entryNotice = (link: StoreLink, entry: ExternalNamespace): string | undefined => {
187
+ if (!hasShim(link.storeDir, entry)) {
188
+ return undefined;
189
+ }
190
+
191
+ const resolution = resolveEntry(link, entry);
192
+
193
+ if (resolution === undefined) {
194
+ throw new Error(unresolvableMessage(link, entry));
195
+ }
196
+
197
+ if (resolution.source === "store") {
198
+ return undefined;
199
+ }
200
+
201
+ if (resolution.source === "hoisted") {
202
+ return hoistedPackageNotice(resolution);
203
+ }
204
+
205
+ if (!hasStoreLocalLink(link.storeDir, resolution.packageName)) {
206
+ throw new Error(linkFailedMessage(link, entry));
207
+ }
208
+
209
+ return externalPackageNotice(resolution);
210
+ };
211
+
212
+ const externalPackageNotices = (link: StoreLink): string[] => {
213
+ const notices: string[] = [];
214
+
215
+ for (const entry of EXTERNAL_NAMESPACES) {
216
+ const notice = entryNotice(link, entry);
217
+
218
+ if (notice !== undefined) {
219
+ notices.push(notice);
220
+ }
221
+ }
222
+
223
+ return notices;
224
+ };
225
+
226
+ export { ensureExternalPackageLinks, externalPackageNotices, resetExternalPackageLinks };
@@ -12,7 +12,7 @@ import {
12
12
  } from "../../analysis/param-structure.js";
13
13
  import { renderJsDoc } from "../../writer/doc.js";
14
14
  import { annotationSpec, THROWS_TEXT } from "./doc-spec.js";
15
- import { isCallbackParameter, returnedOutParameters } from "./method.js";
15
+ import { isCallbackParameter, returnedOutParameters, shouldTrimFinishBoolean } from "./method.js";
16
16
 
17
17
  type CallableDocOptions = {
18
18
  finishFn?: GirFunction | undefined;
@@ -53,9 +53,9 @@ const tupleReturnsText = (primary: string | undefined, outs: InputParameter[]):
53
53
  return bullets.length === 0 ? undefined : `Tuple of:\n\n${bullets.join("\n")}`;
54
54
  };
55
55
 
56
- const returnsText = (context: ModuleContext, fn: GirFunction): string | undefined => {
56
+ const returnsText = (context: ModuleContext, fn: GirFunction, isPrimaryTrimmed: boolean): string | undefined => {
57
57
  const outs = returnedOutParameters(context, fn);
58
- const isPrimaryOmitted = shouldOmitPrimaryReturn(context.library, fn.returnValue);
58
+ const isPrimaryOmitted = isPrimaryTrimmed || shouldOmitPrimaryReturn(context.library, fn.returnValue);
59
59
  const primary = isPrimaryOmitted ? undefined : fn.returnValue.doc;
60
60
 
61
61
  if (outs.length === 0) {
@@ -92,7 +92,11 @@ const callableSpec = (context: ModuleContext, callable: GirFunction, options: Ca
92
92
  (parameter) => options.finishFn !== undefined && isCallbackParameter(context, parameter),
93
93
  options.renames,
94
94
  ),
95
- returns: returnsText(context, options.finishFn ?? callable),
95
+ returns: returnsText(
96
+ context,
97
+ options.finishFn ?? callable,
98
+ options.finishFn !== undefined && shouldTrimFinishBoolean(context, options.finishFn),
99
+ ),
96
100
  throws: canCallableThrow(callable, options.finishFn) ? THROWS_TEXT : undefined,
97
101
  });
98
102
 
@@ -358,7 +358,7 @@ const renderPromisifiedCallable = (
358
358
  const body = renderPromisifiedBody(
359
359
  context,
360
360
  callable,
361
- finishCallExpression(callable, finishFn, member.ownerName),
361
+ { fn: finishFn, expression: finishCallExpression(callable, finishFn, member.ownerName) },
362
362
  toCamelIdentifier(cIdentifier),
363
363
  );
364
364
 
@@ -247,6 +247,35 @@ const appendClassRegistrations = (context: ModuleContext, klass: GirClass, class
247
247
  gtypeExpr,
248
248
  vfuncs: renderVfuncMetadata(context, klass),
249
249
  });
250
+
251
+ appendClassStructRegistration(context, klass, className, gtypeExpr);
252
+ };
253
+
254
+ const appendClassStructRegistration = (
255
+ context: ModuleContext,
256
+ klass: GirClass,
257
+ className: string,
258
+ gtypeExpr: string | undefined,
259
+ ): void => {
260
+ const typeStruct = klass.glibTypeStruct;
261
+
262
+ if (gtypeExpr === undefined || typeStruct === undefined) {
263
+ return;
264
+ }
265
+
266
+ const resolved = context.library.resolveType(context.namespace.name, typeStruct);
267
+
268
+ if (resolved?.kind !== "record" || !isEmittableEntity(resolved.value)) {
269
+ return;
270
+ }
271
+
272
+ const structName = sanitizeTypeIdentifier(resolved.value.name);
273
+ context.addRuntimeImport("registerClassStruct");
274
+
275
+ context.module.appendRegistration(`registerClassStruct(${className}, ${structName});`, [
276
+ className,
277
+ structName,
278
+ ]);
250
279
  };
251
280
 
252
281
  const addAncestorInterfaceKeys = (context: ModuleContext, ancestor: ResolvedAncestor, keys: Set<string>): void => {
@@ -76,7 +76,7 @@ const renderRootConstructor = (context: ModuleContext): string => {
76
76
  context.addRuntimeTypeImport("AnyClass");
77
77
  context.addRuntimeImport("getClassType");
78
78
  context.addRuntimeImport("newObjectWithProperties");
79
- const body = "newObjectWithProperties(getClassType(this.constructor as AnyClass), props, this);";
79
+ const body = "return newObjectWithProperties(getClassType(this.constructor as AnyClass), props, this);";
80
80
 
81
81
  return renderBlock("constructor(props: object = {})", body);
82
82
  };
@@ -48,6 +48,7 @@ const renderFnExpression = (context: ModuleContext, fn: GirFunction): string | u
48
48
  args: arrayLiteral(params),
49
49
  returns: returnPlan.descriptor,
50
50
  isReturnSkipped: returnPlan.isSkipped,
51
+ isReturnUnpacked: returnPlan.isUnpacked,
51
52
  canThrow: fn.throws,
52
53
  });
53
54
  };
@@ -132,7 +133,7 @@ const matchNamespaceFinish = (context: ModuleContext, fn: GirFunction): Namespac
132
133
  const renderPromisifiedNamespaceFunction = (options: NamespaceFunctionOptions, finish: NamespaceFinish): string => {
133
134
  const { context, fn, exportName, bindingName } = options;
134
135
  const { signature, returnType } = renderPromisifiedSignature(context, fn, finish.fn);
135
- const body = renderPromisifiedBody(context, fn, finish.exportName, bindingName);
136
+ const body = renderPromisifiedBody(context, fn, { fn: finish.fn, expression: finish.exportName }, bindingName);
136
137
 
137
138
  return renderBlock(`export function ${exportName}(${signature}): ${returnType}`, body);
138
139
  };
@@ -10,6 +10,13 @@ type TypeSource = {
10
10
  const gtypeTsType = (context: ModuleContext): string =>
11
11
  context.namespace.name === "GObject" ? "Type" : PRIMITIVE_TS_TYPE.gtype;
12
12
 
13
+ const gtypeParamTsType = (context: ModuleContext): string => {
14
+ context.addRuntimeTypeImport("AnyClass");
15
+ context.addRuntimeTypeImport("TypedClass");
16
+
17
+ return `${gtypeTsType(context)} | AnyClass<TypedClass>`;
18
+ };
19
+
13
20
  const gtypeMemberDeclaration = (context: ModuleContext): string => `declare __type__: ${gtypeTsType(context)};`;
14
21
 
15
22
  const renderInternGtype = (context: ModuleContext, typeName: string | undefined): string | undefined => {
@@ -48,4 +55,4 @@ const renderSourceGtype = (context: ModuleContext, source: TypeSource): string |
48
55
  ? undefined
49
56
  : renderGtypeExpression(context, source.glibGetType, source.glibTypeName);
50
57
 
51
- export { gtypeTsType, gtypeMemberDeclaration, renderSourceGtype };
58
+ export { gtypeTsType, gtypeParamTsType, gtypeMemberDeclaration, renderSourceGtype };