@gtkx/codegen 1.0.0-rc.2 → 1.0.0-rc.3
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 +2 -0
- package/dist/analysis/descriptor-render.d.ts.map +1 -1
- package/dist/analysis/descriptor-render.js +25 -4
- package/dist/analysis/descriptor-render.js.map +1 -1
- package/dist/analysis/ts-type.d.ts.map +1 -1
- package/dist/analysis/ts-type.js +4 -8
- package/dist/analysis/ts-type.js.map +1 -1
- package/dist/docs/api-reference.d.ts.map +1 -1
- package/dist/docs/api-reference.js +4 -8
- package/dist/docs/api-reference.js.map +1 -1
- package/dist/docs/element-page.d.ts.map +1 -1
- package/dist/docs/element-page.js +5 -4
- package/dist/docs/element-page.js.map +1 -1
- package/dist/docs/pipeline.d.ts +2 -0
- package/dist/docs/pipeline.d.ts.map +1 -1
- package/dist/docs/pipeline.js +2 -0
- package/dist/docs/pipeline.js.map +1 -1
- package/dist/fingerprint.d.ts +1 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +3 -0
- package/dist/fingerprint.js.map +1 -1
- package/dist/gi.d.ts +7 -2
- package/dist/gi.d.ts.map +1 -1
- package/dist/gi.js +4 -2
- package/dist/gi.js.map +1 -1
- package/dist/gir/libraries.d.ts +4 -3
- package/dist/gir/libraries.d.ts.map +1 -1
- package/dist/gir/libraries.js +2 -1
- package/dist/gir/libraries.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jsx.d.ts +2 -0
- package/dist/jsx.d.ts.map +1 -1
- package/dist/jsx.js +4 -0
- package/dist/jsx.js.map +1 -1
- package/dist/react/element-config.d.ts +3 -0
- package/dist/react/element-config.d.ts.map +1 -1
- package/dist/react/element-config.js +4 -1
- package/dist/react/element-config.js.map +1 -1
- package/dist/runner.d.ts +2 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +4 -1
- package/dist/runner.js.map +1 -1
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +0 -5
- package/dist/store/gi/callables.js.map +1 -1
- package/dist/store/gi/function.d.ts.map +1 -1
- package/dist/store/gi/function.js +0 -2
- package/dist/store/gi/function.js.map +1 -1
- package/dist/store/gi/method.d.ts.map +1 -1
- package/dist/store/gi/method.js +1 -0
- package/dist/store/gi/method.js.map +1 -1
- package/dist/store/gi/record-constructor.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +5 -4
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +2 -1
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +22 -6
- package/dist/store/gi/record-field-accessor.js.map +1 -1
- package/dist/store/gi/record.d.ts.map +1 -1
- package/dist/store/gi/record.js +0 -7
- package/dist/store/gi/record.js.map +1 -1
- package/dist/store/gi/value-marshalable.d.ts +15 -0
- package/dist/store/gi/value-marshalable.d.ts.map +1 -0
- package/dist/store/gi/value-marshalable.js +66 -0
- package/dist/store/gi/value-marshalable.js.map +1 -0
- package/dist/store/jsx/intrinsic-elements.d.ts +1 -2
- package/dist/store/jsx/intrinsic-elements.d.ts.map +1 -1
- package/dist/store/jsx/intrinsic-elements.js +1 -2
- package/dist/store/jsx/intrinsic-elements.js.map +1 -1
- package/dist/store/jsx/omitted-props.d.ts +10 -0
- package/dist/store/jsx/omitted-props.d.ts.map +1 -0
- package/dist/store/jsx/omitted-props.js +22 -0
- package/dist/store/jsx/omitted-props.js.map +1 -0
- package/dist/store/jsx/pipeline.d.ts +2 -0
- package/dist/store/jsx/pipeline.d.ts.map +1 -1
- package/dist/store/jsx/pipeline.js +2 -0
- package/dist/store/jsx/pipeline.js.map +1 -1
- package/dist/store/jsx/props.d.ts +1 -1
- package/dist/store/jsx/props.d.ts.map +1 -1
- package/dist/store/jsx/props.js +6 -11
- package/dist/store/jsx/props.js.map +1 -1
- package/package.json +3 -4
- package/src/analysis/descriptor-render.ts +35 -3
- package/src/analysis/ts-type.ts +4 -11
- package/src/docs/api-reference.ts +4 -9
- package/src/docs/element-page.ts +5 -9
- package/src/docs/pipeline.ts +3 -0
- package/src/fingerprint.ts +16 -2
- package/src/gi.ts +12 -3
- package/src/gir/libraries.ts +5 -4
- package/src/index.ts +1 -0
- package/src/jsx.ts +5 -0
- package/src/react/element-config.ts +8 -2
- package/src/runner.ts +8 -1
- package/src/store/gi/callables.ts +0 -6
- package/src/store/gi/function.ts +0 -2
- package/src/store/gi/method.ts +1 -0
- package/src/store/gi/record-constructor.ts +9 -4
- package/src/store/gi/record-field-accessor.ts +41 -6
- package/src/store/gi/record.ts +0 -9
- package/src/store/gi/value-marshalable.ts +96 -0
- package/src/store/jsx/intrinsic-elements.ts +0 -9
- package/src/store/jsx/omitted-props.ts +32 -0
- package/src/store/jsx/pipeline.ts +3 -0
- package/src/store/jsx/props.ts +6 -18
- package/dist/store/gi/class-struct-record.d.ts +0 -10
- package/dist/store/gi/class-struct-record.d.ts.map +0 -1
- package/dist/store/gi/class-struct-record.js +0 -52
- package/dist/store/gi/class-struct-record.js.map +0 -1
- package/src/store/gi/class-struct-record.ts +0 -72
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { GirField } from "../../gir/field.js";
|
|
2
|
+
import type { PrimitiveCategory } from "../../gir/primitives.js";
|
|
3
|
+
import type { GirRecord } from "../../gir/record.js";
|
|
4
|
+
import type { TypeId } from "../../gir/type-id.js";
|
|
5
|
+
import type { GirType } from "../../gir/type.js";
|
|
6
|
+
import type { ModuleContext } from "../../writer/context.js";
|
|
7
|
+
|
|
8
|
+
type Scope = { context: ModuleContext; seen: Set<string> };
|
|
9
|
+
|
|
10
|
+
/** Primitive categories that are a pointer at the C level, so copying the bytes aliases the pointee. */
|
|
11
|
+
const POINTER_CATEGORIES: Set<PrimitiveCategory> = new Set<PrimitiveCategory>(["string", "pointer"]);
|
|
12
|
+
|
|
13
|
+
const recordKey = (namespaceName: string, record: GirRecord): string => `${namespaceName}.${record.name}`;
|
|
14
|
+
|
|
15
|
+
const hasOwnCopySemantics = (record: GirRecord): boolean =>
|
|
16
|
+
record.glibGetType !== undefined ||
|
|
17
|
+
((record.glibRefFunc ?? record.copyFunc) !== undefined && (record.glibUnrefFunc ?? record.freeFunc) !== undefined);
|
|
18
|
+
|
|
19
|
+
const isValueSafeArray = (scope: Scope, type: Extract<GirType, { kind: "carray" }>): boolean =>
|
|
20
|
+
type.fixedSize !== undefined && isValueSafeRef(scope, type.element, type.elementCType);
|
|
21
|
+
|
|
22
|
+
const isValueSafeAlias = (scope: Scope, type: Extract<GirType, { kind: "alias" }>): boolean =>
|
|
23
|
+
isValueSafeRef(scope, type.value.target, type.value.targetCType);
|
|
24
|
+
|
|
25
|
+
function isValueSafeType(scope: Scope, type: GirType): boolean {
|
|
26
|
+
switch (type.kind) {
|
|
27
|
+
case "primitive": {
|
|
28
|
+
return !POINTER_CATEGORIES.has(type.category);
|
|
29
|
+
}
|
|
30
|
+
case "enum": {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
case "record": {
|
|
34
|
+
return isValueSafeRecord(scope, type.namespace.name, type.value);
|
|
35
|
+
}
|
|
36
|
+
case "carray": {
|
|
37
|
+
return isValueSafeArray(scope, type);
|
|
38
|
+
}
|
|
39
|
+
case "alias": {
|
|
40
|
+
return isValueSafeAlias(scope, type);
|
|
41
|
+
}
|
|
42
|
+
case "callback":
|
|
43
|
+
case "class":
|
|
44
|
+
case "hashtable":
|
|
45
|
+
case "interface":
|
|
46
|
+
case "list":
|
|
47
|
+
case "varargs": {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function isValueSafeRef(scope: Scope, ref: TypeId | undefined, cType: string | undefined): boolean {
|
|
54
|
+
if (ref === undefined || cType?.endsWith("*") === true) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const type = scope.context.library.typeFor(ref);
|
|
59
|
+
|
|
60
|
+
return type === undefined ? false : isValueSafeType(scope, type);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const isValueSafeField = (scope: Scope, field: GirField): boolean =>
|
|
64
|
+
field.inlineMembers === undefined
|
|
65
|
+
? isValueSafeRef(scope, field.type, field.cType)
|
|
66
|
+
: field.inlineMembers.every((member) => isValueSafeField(scope, member));
|
|
67
|
+
|
|
68
|
+
function isValueSafeRecord(scope: Scope, namespaceName: string, record: GirRecord): boolean {
|
|
69
|
+
const key = recordKey(namespaceName, record);
|
|
70
|
+
|
|
71
|
+
if (scope.seen.has(key) || record.fields.length === 0) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
scope.seen.add(key);
|
|
76
|
+
const isSafe = record.fields.every((field) => isValueSafeField(scope, field));
|
|
77
|
+
scope.seen.delete(key);
|
|
78
|
+
|
|
79
|
+
return isSafe;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Whether a record can be copied by value. A plain struct is duplicated with a byte-wise `g_memdup2`,
|
|
84
|
+
* which shallow-copies whatever the bytes hold, so only a record whose every field is transitively a
|
|
85
|
+
* scalar can be owned, allocated or written into an inline slot. A pointer, a string, a function
|
|
86
|
+
* pointer or an opaque record makes it borrow-only. Records that carry their own copy/free pair are
|
|
87
|
+
* duplicated through that instead and never reach the byte-wise path.
|
|
88
|
+
*/
|
|
89
|
+
const isValueMarshalable = (context: ModuleContext, namespaceName: string, record: GirRecord): boolean =>
|
|
90
|
+
isValueSafeRecord({ context, seen: new Set<string>() }, namespaceName, record);
|
|
91
|
+
|
|
92
|
+
/** Whether a record can be allocated and populated from JavaScript. */
|
|
93
|
+
const isConstructibleRecord = (context: ModuleContext, namespaceName: string, record: GirRecord): boolean =>
|
|
94
|
+
hasOwnCopySemantics(record) || isValueMarshalable(context, namespaceName, record);
|
|
95
|
+
|
|
96
|
+
export { hasOwnCopySemantics, isConstructibleRecord, isValueMarshalable };
|
|
@@ -214,14 +214,6 @@ const hasMatchingAncestorName = (
|
|
|
214
214
|
isMatch: (glibName: string) => boolean,
|
|
215
215
|
): boolean => hasMatchingAncestor(klass, namespace, library, (_klass, glibName) => isMatch(glibName));
|
|
216
216
|
|
|
217
|
-
const hasExposedMethod = (
|
|
218
|
-
klass: GirClass,
|
|
219
|
-
namespace: GirNamespace,
|
|
220
|
-
library: Library,
|
|
221
|
-
methodName: string,
|
|
222
|
-
): boolean =>
|
|
223
|
-
hasMatchingAncestor(klass, namespace, library, (current) => current.methods.some((m) => m.name === methodName));
|
|
224
|
-
|
|
225
217
|
const isIntrinsicElementClass = (klass: GirClass, namespace: GirNamespace, library: Library): boolean =>
|
|
226
218
|
hasMatchingAncestorName(klass, namespace, library, (glibName) => glibName === "GObject");
|
|
227
219
|
|
|
@@ -253,7 +245,6 @@ export {
|
|
|
253
245
|
newlyImplementedInterfaces,
|
|
254
246
|
collectInterfacePropsClasses,
|
|
255
247
|
ancestorGlibNames,
|
|
256
|
-
hasExposedMethod,
|
|
257
248
|
isIntrinsicElementClass,
|
|
258
249
|
collectIntrinsicElementClasses,
|
|
259
250
|
type GlibNamedClass,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Props left out of the generated element props, keyed by GLib type name. */
|
|
2
|
+
type OmittedProps = Record<string, string[]>;
|
|
3
|
+
|
|
4
|
+
const omittedProps: Map<string, Set<string>> = new Map();
|
|
5
|
+
|
|
6
|
+
/** Installs the props each element omits (GLib type name → prop names); set once per run. */
|
|
7
|
+
const setOmittedProps = (props: OmittedProps): void => {
|
|
8
|
+
omittedProps.clear();
|
|
9
|
+
|
|
10
|
+
for (const [glibName, names] of Object.entries(props)) {
|
|
11
|
+
omittedProps.set(glibName, new Set(names));
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Whether the element config declares this prop omitted for the type that declares the property. */
|
|
16
|
+
const isOmittedProp = (glibName: string | undefined, jsName: string): boolean =>
|
|
17
|
+
glibName !== undefined && omittedProps.get(glibName)?.has(jsName) === true;
|
|
18
|
+
|
|
19
|
+
/** Merges omitted-prop maps keyed by GLib type name, concatenating the names each map contributes. */
|
|
20
|
+
const mergeOmitProps = (...maps: OmittedProps[]): OmittedProps => {
|
|
21
|
+
const merged: OmittedProps = {};
|
|
22
|
+
|
|
23
|
+
for (const map of maps) {
|
|
24
|
+
for (const [glibName, names] of Object.entries(map)) {
|
|
25
|
+
merged[glibName] = [...(merged[glibName] ?? []), ...names];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return merged;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { setOmittedProps, isOmittedProp, mergeOmitProps, type OmittedProps };
|
|
@@ -9,6 +9,7 @@ import { buildGirIndex } from "./gir-index.js";
|
|
|
9
9
|
import { collectIntrinsicElementClasses, type GlibNamedClass } from "./intrinsic-elements.js";
|
|
10
10
|
import { generateJsxSection } from "./jsx.js";
|
|
11
11
|
import { generateMetadata } from "./metadata.js";
|
|
12
|
+
import { type OmittedProps, setOmittedProps } from "./omitted-props.js";
|
|
12
13
|
|
|
13
14
|
type JsxNamespaceFile = {
|
|
14
15
|
directory: string;
|
|
@@ -25,6 +26,7 @@ type JsxGenerationOptions = {
|
|
|
25
26
|
reactSubexports?: string[];
|
|
26
27
|
components?: ElementComponentOverrides;
|
|
27
28
|
props?: ElementProps;
|
|
29
|
+
omitProps?: OmittedProps;
|
|
28
30
|
lazyElements?: string[];
|
|
29
31
|
};
|
|
30
32
|
|
|
@@ -47,6 +49,7 @@ type JsxNamespaceContext = {
|
|
|
47
49
|
|
|
48
50
|
const generateJsxFiles = (library: Library, options: JsxGenerationOptions = {}): JsxFiles => {
|
|
49
51
|
setElementProps(options.props ?? {});
|
|
52
|
+
setOmittedProps(options.omitProps ?? {});
|
|
50
53
|
const intrinsicElements = collectIntrinsicElementClasses(library);
|
|
51
54
|
const intrinsicElementByGlibName = new Map(intrinsicElements.map((entry) => [entry.glibName, entry]));
|
|
52
55
|
const girIndex = buildGirIndex(library);
|
package/src/store/jsx/props.ts
CHANGED
|
@@ -9,12 +9,8 @@ import { renderHandlerParameters, renderHandlerResultType } from "../../analysis
|
|
|
9
9
|
import { recordTypeTarget, renderBaseType, type TsTypeTarget } from "../../analysis/ts-type.js";
|
|
10
10
|
import { type GirProperty, isConstructableProperty } from "../../gir/property.js";
|
|
11
11
|
import { renderJsDoc } from "../../writer/doc.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
hasExposedMethod,
|
|
15
|
-
isIntrinsicElementClass,
|
|
16
|
-
signalHandlerName,
|
|
17
|
-
} from "./intrinsic-elements.js";
|
|
12
|
+
import { getGlibName, giNamespaceAlias, isIntrinsicElementClass, signalHandlerName } from "./intrinsic-elements.js";
|
|
13
|
+
import { isOmittedProp } from "./omitted-props.js";
|
|
18
14
|
|
|
19
15
|
type IntrinsicElementPropsEntries = {
|
|
20
16
|
propLines: string[];
|
|
@@ -75,7 +71,7 @@ const appendPropertyLines = (state: PropCollectorState, property: GirProperty, j
|
|
|
75
71
|
const tsType = renderReactPropType(state.types, property.type, false);
|
|
76
72
|
const doc = renderJsDoc(property.doc);
|
|
77
73
|
|
|
78
|
-
if (isObjectProp(state.owner, property
|
|
74
|
+
if (isObjectProp(state.owner.library, property)) {
|
|
79
75
|
state.propLines.push(`${doc}${jsName}?: ${tsType} | ReactElement | null | undefined;`);
|
|
80
76
|
state.objectPropNames.push(jsName);
|
|
81
77
|
|
|
@@ -99,7 +95,7 @@ const acceptCollectorProperty = (state: PropCollectorState, property: GirPropert
|
|
|
99
95
|
|
|
100
96
|
const jsName = toCamelIdentifier(property.name);
|
|
101
97
|
|
|
102
|
-
if (state.seen.has(jsName)) {
|
|
98
|
+
if (state.seen.has(jsName) || isOmittedProp(getGlibName(state.owner.klass), jsName)) {
|
|
103
99
|
return;
|
|
104
100
|
}
|
|
105
101
|
|
|
@@ -215,20 +211,12 @@ const isGObjectType = (library: Library, ref: TypeId | undefined): boolean => {
|
|
|
215
211
|
return isIntrinsicElementClass(resolved.value, resolved.namespace, library);
|
|
216
212
|
};
|
|
217
213
|
|
|
218
|
-
const isObjectProp = (
|
|
214
|
+
const isObjectProp = (library: Library, property: GirProperty): boolean => {
|
|
219
215
|
if (!property.writable || property.constructOnly) {
|
|
220
216
|
return false;
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (jsName === "child" && hasExposedMethod(owner.klass, owner.namespace, owner.library, "set_child")) {
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return true;
|
|
219
|
+
return isGObjectType(library, property.type);
|
|
232
220
|
};
|
|
233
221
|
|
|
234
222
|
const renderSignalHandler = (options: SignalRenderOptions): string => {
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { GirFunction } from "../../gir/function.js";
|
|
2
|
-
import type { Library } from "../../gir/library.js";
|
|
3
|
-
import type { GirRecord } from "../../gir/record.js";
|
|
4
|
-
import type { TypeId } from "../../gir/type-id.js";
|
|
5
|
-
import type { ModuleContext } from "../../writer/context.js";
|
|
6
|
-
declare const isClassStructRecord: (library: Library, namespaceName: string, record: GirRecord) => boolean;
|
|
7
|
-
declare const isClassStructRef: (context: ModuleContext, ref: TypeId | undefined) => boolean;
|
|
8
|
-
declare const hasClassStructReference: (context: ModuleContext, fn: GirFunction) => boolean;
|
|
9
|
-
export { isClassStructRecord, isClassStructRef, hasClassStructReference };
|
|
10
|
-
//# sourceMappingURL=class-struct-record.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"class-struct-record.d.ts","sourceRoot":"","sources":["../../../src/store/gi/class-struct-record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAO7D,QAAA,MAAM,mBAAmB,GAAI,SAAS,OAAO,EAAE,eAAe,MAAM,EAAE,QAAQ,SAAS,KAAG,OAsBzF,CAAC;AAEF,QAAA,MAAM,gBAAgB,GAAI,SAAS,aAAa,EAAE,KAAK,MAAM,GAAG,SAAS,KAAG,OA8B3E,CAAC;AAEF,QAAA,MAAM,uBAAuB,GAAI,SAAS,aAAa,EAAE,IAAI,WAAW,KAAG,OAEK,CAAC;AAEjF,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
const TYPE_STRUCT_ROOTS = new Set(["GObject.TypeClass", "GObject.TypeInterface"]);
|
|
2
|
-
const EXPLICIT_CLASS_STRUCTS = new Set(["Pango.AttrClass"]);
|
|
3
|
-
const qualify = (namespaceName, name) => `${namespaceName}.${name}`;
|
|
4
|
-
const isClassStructRecord = (library, namespaceName, record) => {
|
|
5
|
-
const qualified = qualify(namespaceName, record.name);
|
|
6
|
-
if (TYPE_STRUCT_ROOTS.has(qualified) || EXPLICIT_CLASS_STRUCTS.has(qualified)) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
const first = record.fields[0];
|
|
10
|
-
// A class struct embeds its parent vtable by value (`GTypeClass g_type_class`); an instance
|
|
11
|
-
// struct stores a pointer to it (`GTypeClass *g_class`). Only the first is a vtable.
|
|
12
|
-
if (first?.type === undefined || first.cType?.endsWith("*") === true) {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
const name = library.nameFor(first.type);
|
|
16
|
-
if (name === undefined) {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
return TYPE_STRUCT_ROOTS.has(qualify(name.namespaceName, name.typeName));
|
|
20
|
-
};
|
|
21
|
-
const isClassStructRef = (context, ref) => {
|
|
22
|
-
if (ref === undefined) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
const type = context.library.typeFor(ref);
|
|
26
|
-
if (type === undefined) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
switch (type.kind) {
|
|
30
|
-
case "record": {
|
|
31
|
-
return isClassStructRecord(context.library, type.namespace.name, type.value);
|
|
32
|
-
}
|
|
33
|
-
case "carray":
|
|
34
|
-
case "list": {
|
|
35
|
-
return isClassStructRef(context, type.element);
|
|
36
|
-
}
|
|
37
|
-
case "alias":
|
|
38
|
-
case "callback":
|
|
39
|
-
case "class":
|
|
40
|
-
case "enum":
|
|
41
|
-
case "hashtable":
|
|
42
|
-
case "interface":
|
|
43
|
-
case "primitive":
|
|
44
|
-
case "varargs": {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const hasClassStructReference = (context, fn) => isClassStructRef(context, fn.returnValue.type) ||
|
|
50
|
-
fn.parameters.some((parameter) => isClassStructRef(context, parameter.type));
|
|
51
|
-
export { isClassStructRecord, isClassStructRef, hasClassStructReference };
|
|
52
|
-
//# sourceMappingURL=class-struct-record.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"class-struct-record.js","sourceRoot":"","sources":["../../../src/store/gi/class-struct-record.ts"],"names":[],"mappings":"AAMA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC,CAAC;AAClF,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAE5D,MAAM,OAAO,GAAG,CAAC,aAAqB,EAAE,IAAY,EAAU,EAAE,CAAC,GAAG,aAAa,IAAI,IAAI,EAAE,CAAC;AAE5F,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAE,aAAqB,EAAE,MAAiB,EAAW,EAAE;IAChG,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,sBAAsB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAE/B,4FAA4F;IAC5F,qFAAqF;IACrF,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QACnE,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEzC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,OAAsB,EAAE,GAAuB,EAAW,EAAE;IAClF,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACZ,OAAO,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACjF,CAAC;QACD,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC,CAAC,CAAC;YACV,OAAO,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC;QACD,KAAK,OAAO,CAAC;QACb,KAAK,UAAU,CAAC;QAChB,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,WAAW,CAAC;QACjB,KAAK,WAAW,CAAC;QACjB,KAAK,WAAW,CAAC;QACjB,KAAK,SAAS,CAAC,CAAC,CAAC;YACb,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,OAAsB,EAAE,EAAe,EAAW,EAAE,CACjF,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC;IAC9C,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAEjF,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,CAAC","sourcesContent":["import type { GirFunction } from \"../../gir/function.js\";\nimport type { Library } from \"../../gir/library.js\";\nimport type { GirRecord } from \"../../gir/record.js\";\nimport type { TypeId } from \"../../gir/type-id.js\";\nimport type { ModuleContext } from \"../../writer/context.js\";\n\nconst TYPE_STRUCT_ROOTS = new Set([\"GObject.TypeClass\", \"GObject.TypeInterface\"]);\nconst EXPLICIT_CLASS_STRUCTS = new Set([\"Pango.AttrClass\"]);\n\nconst qualify = (namespaceName: string, name: string): string => `${namespaceName}.${name}`;\n\nconst isClassStructRecord = (library: Library, namespaceName: string, record: GirRecord): boolean => {\n const qualified = qualify(namespaceName, record.name);\n\n if (TYPE_STRUCT_ROOTS.has(qualified) || EXPLICIT_CLASS_STRUCTS.has(qualified)) {\n return true;\n }\n\n const first = record.fields[0];\n\n // A class struct embeds its parent vtable by value (`GTypeClass g_type_class`); an instance\n // struct stores a pointer to it (`GTypeClass *g_class`). Only the first is a vtable.\n if (first?.type === undefined || first.cType?.endsWith(\"*\") === true) {\n return false;\n }\n\n const name = library.nameFor(first.type);\n\n if (name === undefined) {\n return false;\n }\n\n return TYPE_STRUCT_ROOTS.has(qualify(name.namespaceName, name.typeName));\n};\n\nconst isClassStructRef = (context: ModuleContext, ref: TypeId | undefined): boolean => {\n if (ref === undefined) {\n return false;\n }\n\n const type = context.library.typeFor(ref);\n\n if (type === undefined) {\n return false;\n }\n\n switch (type.kind) {\n case \"record\": {\n return isClassStructRecord(context.library, type.namespace.name, type.value);\n }\n case \"carray\":\n case \"list\": {\n return isClassStructRef(context, type.element);\n }\n case \"alias\":\n case \"callback\":\n case \"class\":\n case \"enum\":\n case \"hashtable\":\n case \"interface\":\n case \"primitive\":\n case \"varargs\": {\n return false;\n }\n }\n};\n\nconst hasClassStructReference = (context: ModuleContext, fn: GirFunction): boolean =>\n isClassStructRef(context, fn.returnValue.type) ||\n fn.parameters.some((parameter) => isClassStructRef(context, parameter.type));\n\nexport { isClassStructRecord, isClassStructRef, hasClassStructReference };\n"]}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { GirFunction } from "../../gir/function.js";
|
|
2
|
-
import type { Library } from "../../gir/library.js";
|
|
3
|
-
import type { GirRecord } from "../../gir/record.js";
|
|
4
|
-
import type { TypeId } from "../../gir/type-id.js";
|
|
5
|
-
import type { ModuleContext } from "../../writer/context.js";
|
|
6
|
-
|
|
7
|
-
const TYPE_STRUCT_ROOTS = new Set(["GObject.TypeClass", "GObject.TypeInterface"]);
|
|
8
|
-
const EXPLICIT_CLASS_STRUCTS = new Set(["Pango.AttrClass"]);
|
|
9
|
-
|
|
10
|
-
const qualify = (namespaceName: string, name: string): string => `${namespaceName}.${name}`;
|
|
11
|
-
|
|
12
|
-
const isClassStructRecord = (library: Library, namespaceName: string, record: GirRecord): boolean => {
|
|
13
|
-
const qualified = qualify(namespaceName, record.name);
|
|
14
|
-
|
|
15
|
-
if (TYPE_STRUCT_ROOTS.has(qualified) || EXPLICIT_CLASS_STRUCTS.has(qualified)) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const first = record.fields[0];
|
|
20
|
-
|
|
21
|
-
// A class struct embeds its parent vtable by value (`GTypeClass g_type_class`); an instance
|
|
22
|
-
// struct stores a pointer to it (`GTypeClass *g_class`). Only the first is a vtable.
|
|
23
|
-
if (first?.type === undefined || first.cType?.endsWith("*") === true) {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const name = library.nameFor(first.type);
|
|
28
|
-
|
|
29
|
-
if (name === undefined) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return TYPE_STRUCT_ROOTS.has(qualify(name.namespaceName, name.typeName));
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const isClassStructRef = (context: ModuleContext, ref: TypeId | undefined): boolean => {
|
|
37
|
-
if (ref === undefined) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const type = context.library.typeFor(ref);
|
|
42
|
-
|
|
43
|
-
if (type === undefined) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
switch (type.kind) {
|
|
48
|
-
case "record": {
|
|
49
|
-
return isClassStructRecord(context.library, type.namespace.name, type.value);
|
|
50
|
-
}
|
|
51
|
-
case "carray":
|
|
52
|
-
case "list": {
|
|
53
|
-
return isClassStructRef(context, type.element);
|
|
54
|
-
}
|
|
55
|
-
case "alias":
|
|
56
|
-
case "callback":
|
|
57
|
-
case "class":
|
|
58
|
-
case "enum":
|
|
59
|
-
case "hashtable":
|
|
60
|
-
case "interface":
|
|
61
|
-
case "primitive":
|
|
62
|
-
case "varargs": {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const hasClassStructReference = (context: ModuleContext, fn: GirFunction): boolean =>
|
|
69
|
-
isClassStructRef(context, fn.returnValue.type) ||
|
|
70
|
-
fn.parameters.some((parameter) => isClassStructRef(context, parameter.type));
|
|
71
|
-
|
|
72
|
-
export { isClassStructRecord, isClassStructRef, hasClassStructReference };
|