@gtkx/codegen 1.1.0 → 1.2.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/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +14 -10
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/descriptor.d.ts +11 -5
- package/dist/analysis/descriptor.d.ts.map +1 -1
- package/dist/analysis/descriptor.js +25 -9
- package/dist/analysis/descriptor.js.map +1 -1
- package/dist/analysis/interface-conflicts.d.ts +3 -1
- package/dist/analysis/interface-conflicts.d.ts.map +1 -1
- package/dist/analysis/interface-conflicts.js +3 -8
- package/dist/analysis/interface-conflicts.js.map +1 -1
- package/dist/analysis/ts-type.d.ts +3 -2
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +16 -9
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/analysis/type-shape.d.ts +3 -2
- package/dist/analysis/type-shape.d.ts.map +1 -1
- package/dist/analysis/type-shape.js +2 -1
- package/dist/analysis/type-shape.js.map +1 -1
- package/dist/compile.d.ts +4 -5
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +56 -4
- package/dist/compile.js.map +1 -1
- package/dist/docs/api-reference.d.ts +2 -0
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +1 -1
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/pipeline.d.ts +1 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +10 -3
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/docs/symbol-page.d.ts.map +1 -1
- package/dist/docs/symbol-page.js +1 -3
- package/dist/docs/symbol-page.js.map +1 -1
- package/dist/fingerprint.d.ts +11 -5
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +22 -19
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +1 -0
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +7 -2
- package/dist/gi.js.map +1 -1
- package/dist/gir/gir-path.d.ts +1 -1
- package/dist/gir/gir-path.js +1 -1
- package/dist/gir/gir-path.js.map +1 -1
- package/dist/gir/library.d.ts +5 -1
- package/dist/gir/library.d.ts.map +1 -1
- package/dist/gir/library.js +8 -1
- package/dist/gir/library.js.map +1 -1
- package/dist/gir/parse.d.ts.map +1 -1
- package/dist/gir/parse.js +4 -1
- package/dist/gir/parse.js.map +1 -1
- package/dist/gir/primitives.js +1 -1
- package/dist/gir/primitives.js.map +1 -1
- package/dist/khronos/args.d.ts.map +1 -1
- package/dist/khronos/args.js +8 -6
- package/dist/khronos/args.js.map +1 -1
- package/dist/khronos/render.d.ts.map +1 -1
- package/dist/khronos/render.js +8 -4
- package/dist/khronos/render.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +5 -3
- package/dist/runner.js.map +1 -1
- package/dist/staging.d.ts.map +1 -1
- package/dist/staging.js +1 -1
- package/dist/staging.js.map +1 -1
- package/dist/store/compile-store.d.ts +0 -1
- package/dist/store/compile-store.d.ts.map +1 -1
- package/dist/store/compile-store.js +7 -34
- package/dist/store/compile-store.js.map +1 -1
- package/dist/store/gi/callables.d.ts +1 -3
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +19 -4
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/class.d.ts.map +1 -1
- package/dist/store/gi/class.js +48 -9
- package/dist/store/gi/class.js.map +1 -1
- package/dist/store/gi/constant.js +1 -1
- package/dist/store/gi/constant.js.map +1 -1
- package/dist/store/gi/enum.d.ts.map +1 -1
- package/dist/store/gi/enum.js +2 -5
- package/dist/store/gi/enum.js.map +1 -1
- package/dist/store/gi/interface.js +2 -2
- package/dist/store/gi/interface.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +4 -7
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/property-accessor.d.ts +0 -3
- package/dist/store/gi/property-accessor.d.ts.map +1 -1
- package/dist/store/gi/property-accessor.js +15 -108
- package/dist/store/gi/property-accessor.js.map +1 -1
- package/dist/store/gi/record-constructor.js +3 -3
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +15 -3
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/return-wrap.js +1 -1
- package/dist/store/gi/return-wrap.js.map +1 -1
- package/dist/store/gi/signal.d.ts.map +1 -1
- package/dist/store/gi/signal.js +25 -4
- package/dist/store/gi/signal.js.map +1 -1
- package/dist/store/jsx-store.d.ts.map +1 -1
- package/dist/store/jsx-store.js +0 -1
- package/dist/store/jsx-store.js.map +1 -1
- package/dist/store/store-fs.d.ts +0 -1
- package/dist/store/store-fs.d.ts.map +1 -1
- package/dist/store/store-fs.js +2 -7
- package/dist/store/store-fs.js.map +1 -1
- package/dist/xml.d.ts +1 -0
- package/dist/xml.d.ts.map +1 -1
- package/dist/xml.js +28 -1
- package/dist/xml.js.map +1 -1
- package/overrides/gobject/object.ts.ejs +2 -0
- package/package.json +3 -3
- package/src/analysis/descriptor-render.ts +19 -10
- package/src/analysis/descriptor.ts +43 -9
- package/src/analysis/interface-conflicts.ts +6 -8
- package/src/analysis/ts-type.ts +30 -11
- package/src/analysis/type-shape.ts +5 -2
- package/src/compile.ts +87 -6
- package/src/docs/api-reference.ts +3 -1
- package/src/docs/pipeline.ts +13 -7
- package/src/docs/symbol-page.ts +0 -4
- package/src/fingerprint.ts +31 -38
- package/src/gi.ts +9 -2
- package/src/gir/gir-path.ts +1 -1
- package/src/gir/library.ts +9 -1
- package/src/gir/parse.ts +6 -1
- package/src/gir/primitives.ts +1 -1
- package/src/khronos/args.ts +9 -6
- package/src/khronos/render.ts +8 -6
- package/src/runner.ts +7 -3
- package/src/staging.ts +1 -3
- package/src/store/compile-store.ts +7 -40
- package/src/store/gi/callables.ts +26 -7
- package/src/store/gi/class.ts +63 -7
- package/src/store/gi/constant.ts +1 -1
- package/src/store/gi/enum.ts +2 -6
- package/src/store/gi/interface.ts +2 -2
- package/src/store/gi/method.ts +4 -9
- package/src/store/gi/property-accessor.ts +22 -193
- package/src/store/gi/record-constructor.ts +3 -3
- package/src/store/gi/record-field-accessor.ts +18 -3
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +30 -4
- package/src/store/jsx-store.ts +0 -1
- package/src/store/store-fs.ts +3 -9
- package/src/xml.ts +43 -1
|
@@ -366,6 +366,21 @@ const visitInlineStructFields = (
|
|
|
366
366
|
}
|
|
367
367
|
};
|
|
368
368
|
|
|
369
|
+
const inlineLeafCount = (context: ModuleContext, fields: GirField[]): number => {
|
|
370
|
+
let count = 0;
|
|
371
|
+
|
|
372
|
+
visitInlineStructFields(context, fields, 0, {
|
|
373
|
+
leaf: () => {
|
|
374
|
+
count += 1;
|
|
375
|
+
},
|
|
376
|
+
nested: (_jsName, nested) => {
|
|
377
|
+
count += inlineLeafCount(context, nested);
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
return count;
|
|
382
|
+
};
|
|
383
|
+
|
|
369
384
|
const elementAccessExpr = (descriptor: string, offset: number): string =>
|
|
370
385
|
`read(__array, ${descriptor}, __base + ${String(offset)})`;
|
|
371
386
|
|
|
@@ -452,7 +467,7 @@ const structArrayGetterBlock = (options: StructArrayAccessorOptions): string =>
|
|
|
452
467
|
};
|
|
453
468
|
|
|
454
469
|
const structArraySetterStatements = (context: ModuleContext, options: StructArrayAccessorOptions): string => {
|
|
455
|
-
const { elementDescriptor, offset, elementSize, elementFields } = options;
|
|
470
|
+
const { elementDescriptor, offset, elementSize, elementFields, lengthExpr } = options;
|
|
456
471
|
const writes: string[] = [];
|
|
457
472
|
|
|
458
473
|
appendElementWriteStatements(context, {
|
|
@@ -468,7 +483,7 @@ const structArraySetterStatements = (context: ModuleContext, options: StructArra
|
|
|
468
483
|
`const __descriptor = ${elementDescriptor};`,
|
|
469
484
|
`const __array = read(getHandle(this), __descriptor, ${String(offset)}) as ReturnType<typeof getHandle>;`,
|
|
470
485
|
"for (const [__index, __element] of __value.entries()) {",
|
|
471
|
-
indent(loop
|
|
486
|
+
indent(`if (__index >= ${lengthExpr}) {\n break;\n}\n\n${loop}`, 1),
|
|
472
487
|
"}",
|
|
473
488
|
`write(getHandle(this), __descriptor, ${String(offset)}, __array);`,
|
|
474
489
|
].join("\n");
|
|
@@ -543,7 +558,7 @@ const resolveStructArray = (context: ModuleContext, target: StructArrayTarget):
|
|
|
543
558
|
|
|
544
559
|
const shape = resolveStructArrayShape(context, elements, siblingFields);
|
|
545
560
|
|
|
546
|
-
if (shape === undefined) {
|
|
561
|
+
if (shape === undefined || inlineLeafCount(context, elements.elementFields) === 0) {
|
|
547
562
|
return undefined;
|
|
548
563
|
}
|
|
549
564
|
|
|
@@ -10,7 +10,7 @@ type WrapReturnOptions = {
|
|
|
10
10
|
valueExpression: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["gtype", "bigint64", "biguint64"]);
|
|
13
|
+
const BIGINT_CATEGORIES: Set<PrimitiveCategory> = new Set(["gtype", "bigint64", "biguint64", "pointer"]);
|
|
14
14
|
|
|
15
15
|
const wrapReturnValue = (context: ModuleContext, options: WrapReturnOptions): string => {
|
|
16
16
|
const { ref, isNullable, valueExpression } = options;
|
package/src/store/gi/signal.ts
CHANGED
|
@@ -48,6 +48,21 @@ const SIGNAL_HANDLER_TYPE = "(...args: any[]) => any";
|
|
|
48
48
|
const SIGNALS_SUFFIX = "Signals";
|
|
49
49
|
const SIGNAL_EMIT_SUFFIX = "SignalEmit";
|
|
50
50
|
|
|
51
|
+
const DEPRECATED_SIGNAL_ALIASES: Map<string, string> = new Map([
|
|
52
|
+
["addEventListener", "on"],
|
|
53
|
+
["removeEventListener", "off"],
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
const deprecatedAliasDoc = (method: string): string => {
|
|
57
|
+
const replacement = DEPRECATED_SIGNAL_ALIASES.get(method);
|
|
58
|
+
|
|
59
|
+
if (replacement === undefined) {
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return `/** @deprecated Since 1.2. Use \`${replacement}\` instead. Removed in v2. */\n`;
|
|
64
|
+
};
|
|
65
|
+
|
|
51
66
|
const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[] => {
|
|
52
67
|
if (klass.glibGetType === undefined) {
|
|
53
68
|
return [];
|
|
@@ -68,7 +83,7 @@ const renderSignalMembers = (context: ModuleContext, klass: GirClass): string[]
|
|
|
68
83
|
|
|
69
84
|
const connectDefault = isRootObject
|
|
70
85
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + signal + \"'\");"
|
|
71
|
-
: "default:\n return super.connect(signal, handler, isAfter);";
|
|
86
|
+
: "default:\n return super.connect(signal as never, handler as never, isAfter);";
|
|
72
87
|
|
|
73
88
|
const emitDefault = isRootObject
|
|
74
89
|
? "default:\n throw new globalThis.Error(\"Unknown signal '\" + sigName + \"'\");"
|
|
@@ -129,7 +144,11 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
129
144
|
(signal) => `${signalDoc(signal)}${sourceStringLiteral(signal.name)}: ${renderEntry(context, signal)};`,
|
|
130
145
|
);
|
|
131
146
|
|
|
132
|
-
const entries = [
|
|
147
|
+
const entries = [
|
|
148
|
+
...signalEntries,
|
|
149
|
+
...renderNotifyDetailEntries(context, klass, suffix),
|
|
150
|
+
...renderCustomNotifyEntry(context, klass, suffix),
|
|
151
|
+
];
|
|
133
152
|
|
|
134
153
|
return renderBracedOrEmpty(`export interface ${className}${suffix}${extendsClause}`, entries.join("\n"));
|
|
135
154
|
};
|
|
@@ -137,6 +156,14 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
137
156
|
const signalDoc = (signal: GirCallable): string =>
|
|
138
157
|
renderJsDoc(signal.doc, undefined, handlerSpec(signal, signal.parameters));
|
|
139
158
|
|
|
159
|
+
const renderCustomNotifyEntry = (context: ModuleContext, klass: GirClass, suffix: string): string[] => {
|
|
160
|
+
if (context.namespace.name !== "GObject" || klass.name !== "Object") {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return [`[detail: \`notify::\${string}\`]: ${gobjectObjectMapRef(context, suffix)}["notify"];`];
|
|
165
|
+
};
|
|
166
|
+
|
|
140
167
|
const renderNotifyDetailEntries = (context: ModuleContext, klass: GirClass, suffix: string): string[] => {
|
|
141
168
|
const notifyValue = `${gobjectObjectMapRef(context, suffix)}["notify"]`;
|
|
142
169
|
|
|
@@ -191,7 +218,6 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
191
218
|
const lines = [
|
|
192
219
|
`__signals__?: ${map};`,
|
|
193
220
|
`connect<K extends keyof ${map}>(signal: K, handler: ${map}[K], isAfter?: boolean): number;`,
|
|
194
|
-
`connect(signal: string, handler: ${SIGNAL_HANDLER_TYPE}, isAfter?: boolean): number;`,
|
|
195
221
|
`emit<K extends keyof ${emitMap}>(sigName: K, ...args: ${emitMap}[K]["args"]): ${emitMap}[K]["result"];`,
|
|
196
222
|
"emit(sigName: string, ...args: unknown[]): unknown;",
|
|
197
223
|
];
|
|
@@ -200,8 +226,8 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
200
226
|
const chainable = (methods: string[], trailing: string): void => {
|
|
201
227
|
for (const method of methods) {
|
|
202
228
|
lines.push(
|
|
229
|
+
deprecatedAliasDoc(method) +
|
|
203
230
|
`${method}<K extends keyof ${map}>(signal: K, handler: ${map}[K]${trailing}): this;`,
|
|
204
|
-
`${method}(signal: string, handler: ${SIGNAL_HANDLER_TYPE}${trailing}): this;`,
|
|
205
231
|
);
|
|
206
232
|
}
|
|
207
233
|
};
|
package/src/store/jsx-store.ts
CHANGED
package/src/store/store-fs.ts
CHANGED
|
@@ -50,7 +50,6 @@ type WriteStoreParams = {
|
|
|
50
50
|
files: SourceModule[];
|
|
51
51
|
manifest: Manifest;
|
|
52
52
|
rawFiles?: RawFile[];
|
|
53
|
-
requiresEnvReference?: boolean;
|
|
54
53
|
};
|
|
55
54
|
|
|
56
55
|
const STORE_DIR_MODE = 0o755;
|
|
@@ -98,18 +97,13 @@ const writeStore = (params: WriteStoreParams): void => {
|
|
|
98
97
|
};
|
|
99
98
|
|
|
100
99
|
const buildTempStore = (tmp: string, params: WriteStoreParams): void => {
|
|
100
|
+
writePackageJson(tmp, params.manifest);
|
|
101
|
+
|
|
101
102
|
for (const file of params.files) {
|
|
102
103
|
writeSourceFile(tmp, file.fileName, file.source);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
compileStore({
|
|
106
|
-
storeDir: tmp,
|
|
107
|
-
files: params.files,
|
|
108
|
-
packageName: params.manifest.name,
|
|
109
|
-
...(params.requiresEnvReference !== undefined && { requiresEnvReference: params.requiresEnvReference }),
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
writePackageJson(tmp, params.manifest);
|
|
106
|
+
compileStore({ storeDir: tmp, files: params.files, packageName: params.manifest.name });
|
|
113
107
|
const rawFiles = params.rawFiles ?? [];
|
|
114
108
|
|
|
115
109
|
for (const raw of rawFiles) {
|
package/src/xml.ts
CHANGED
|
@@ -7,8 +7,12 @@ type XmlFileInput = {
|
|
|
7
7
|
parser: XMLParser;
|
|
8
8
|
label: string;
|
|
9
9
|
path: string;
|
|
10
|
+
malformedRemedy?: string;
|
|
10
11
|
};
|
|
11
12
|
|
|
13
|
+
const HIGHEST_CONTROL_CODE = 0x1F;
|
|
14
|
+
const LEGAL_CONTROL_CODES: Set<number> = new Set([0x09, 0x0A, 0x0D]);
|
|
15
|
+
|
|
12
16
|
const createXmlParser = (options: Partial<X2jOptions>): XMLParser =>
|
|
13
17
|
new XMLParser({
|
|
14
18
|
ignoreAttributes: false,
|
|
@@ -46,13 +50,51 @@ const positionSuffix = (error: unknown): string => {
|
|
|
46
50
|
return ` (line ${String(line)}, column ${String(col)})`;
|
|
47
51
|
};
|
|
48
52
|
|
|
53
|
+
const isIllegalControlCode = (code: number): boolean =>
|
|
54
|
+
code <= HIGHEST_CONTROL_CODE && !LEGAL_CONTROL_CODES.has(code);
|
|
55
|
+
|
|
56
|
+
const escapedCode = (code: number): string => `[U+${code.toString(16).toUpperCase().padStart(4, "0")}]`;
|
|
57
|
+
|
|
58
|
+
const escapeControlCodes = (text: string): string => {
|
|
59
|
+
let escaped = "";
|
|
60
|
+
|
|
61
|
+
for (const character of text) {
|
|
62
|
+
const code = character.codePointAt(0) ?? 0;
|
|
63
|
+
escaped += isIllegalControlCode(code) ? escapedCode(code) : character;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return escaped;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const offendingLine = (xml: string, error: unknown): string => {
|
|
70
|
+
const line = isRecord(error) ? error.line : undefined;
|
|
71
|
+
|
|
72
|
+
if (typeof line !== "number") {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const text = xml.split("\n")[line - 1];
|
|
77
|
+
|
|
78
|
+
if (text === undefined) {
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return `\n ${escapeControlCodes(text.replace(/^[ \t]+/, "").replace(/\r$/, ""))}`;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const remedySuffix = (input: XmlFileInput, xml: string, error: unknown): string => {
|
|
86
|
+
const remedy = input.malformedRemedy;
|
|
87
|
+
|
|
88
|
+
return remedy === undefined ? "" : `${offendingLine(xml, error)}\n${remedy}`;
|
|
89
|
+
};
|
|
90
|
+
|
|
49
91
|
const assertWellFormed = (input: XmlFileInput, xml: string): void => {
|
|
50
92
|
try {
|
|
51
93
|
SyntaxValidator.validate(xml);
|
|
52
94
|
} catch (error) {
|
|
53
95
|
throw new Error(
|
|
54
96
|
`The ${input.label} at ${input.path} is not well-formed XML: ` +
|
|
55
|
-
`${errorMessage(error)}${positionSuffix(error)}`,
|
|
97
|
+
`${errorMessage(error)}${positionSuffix(error)}${remedySuffix(input, xml, error)}`,
|
|
56
98
|
{ cause: error },
|
|
57
99
|
);
|
|
58
100
|
}
|