@gtkx/runtime 2.0.0-beta.1 → 2.0.0-beta.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/descriptors.d.ts +2 -1
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +5 -1
- package/dist/descriptors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +17 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +13 -0
- package/dist/internal.js.map +1 -1
- package/dist/listeners.d.ts +3 -13
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +12 -12
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +5 -3
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +36 -9
- package/dist/mixin.js.map +1 -1
- package/dist/object.d.ts +14 -3
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +20 -27
- package/dist/object.js.map +1 -1
- package/dist/properties.d.ts +4 -2
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +69 -16
- package/dist/properties.js.map +1 -1
- package/dist/property-brand.d.ts +5 -0
- package/dist/property-brand.d.ts.map +1 -0
- package/dist/property-brand.js +5 -0
- package/dist/property-brand.js.map +1 -0
- package/dist/register-class.d.ts +102 -20
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +19 -37
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -4
- package/dist/registry.js.map +1 -1
- package/dist/signal-brand.d.ts +12 -0
- package/dist/signal-brand.d.ts.map +1 -0
- package/dist/signal-brand.js +6 -0
- package/dist/signal-brand.js.map +1 -0
- package/dist/signal.d.ts +39 -2
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +75 -5
- package/dist/signal.js.map +1 -1
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +1 -1
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +2 -1
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +28 -7
- package/dist/value.js.map +1 -1
- package/package.json +4 -4
- package/src/descriptors.ts +7 -0
- package/src/index.ts +2 -2
- package/src/internal.ts +42 -0
- package/src/listeners.ts +21 -26
- package/src/mixin.ts +55 -9
- package/src/object.ts +57 -7
- package/src/properties.ts +94 -17
- package/src/property-brand.ts +5 -0
- package/src/register-class.ts +296 -95
- package/src/registry.ts +4 -4
- package/src/signal-brand.ts +29 -0
- package/src/signal.ts +177 -6
- package/src/type.ts +1 -1
- package/src/value.ts +40 -5
package/src/signal.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Descriptor, ExternalObject, Handle } from "@gtkx/native";
|
|
2
|
-
import { toCamelIdentifier, upperFirst } from "@gtkx/utils";
|
|
2
|
+
import { type AnyClass, toCamelIdentifier, upperFirst } from "@gtkx/utils";
|
|
3
|
+
import type { ResolvedSignalEmitMap, ResolvedSignalMap } from "./signal-brand.js";
|
|
3
4
|
import { type Arg, isCallerAllocatedArg, isInoutArg, isOutputArg } from "./arg.js";
|
|
4
5
|
import { bind } from "./bind.js";
|
|
5
6
|
import { wrapCallback } from "./callback.js";
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
voidT,
|
|
20
21
|
} from "./descriptors.js";
|
|
21
22
|
import { LIB, VALUE_SIZE, VALUE_T } from "./library.js";
|
|
22
|
-
import { getHandle } from "./registry.js";
|
|
23
|
+
import { getClassType, getHandle, getInstanceType } from "./registry.js";
|
|
23
24
|
import { packTupleResult } from "./tuple.js";
|
|
24
25
|
import { TYPE_INVALID, type TypedClass, typeInterfaces, typeParent } from "./type.js";
|
|
25
26
|
import {
|
|
@@ -37,6 +38,55 @@ import {
|
|
|
37
38
|
/** Function invoked when a connected GObject signal is emitted. */
|
|
38
39
|
type SignalHandler = (...args: unknown[]) => unknown;
|
|
39
40
|
|
|
41
|
+
const isSignalHandler = (value: unknown): value is SignalHandler => typeof value === "function";
|
|
42
|
+
|
|
43
|
+
type DeclaredSignalMap<T> = T extends { __signals__?: infer TSignals } ? NonNullable<TSignals> : never;
|
|
44
|
+
type SignalMap<T> = ResolvedSignalMap<T, DeclaredSignalMap<T>>;
|
|
45
|
+
type SignalName<T> = Extract<keyof SignalMap<T>, string>;
|
|
46
|
+
type DeclaredSignalEmitMap<T> = T extends { __signalEmit__?: infer TSignals }
|
|
47
|
+
? NonNullable<TSignals>
|
|
48
|
+
: T extends { __signals__?: infer TSignals }
|
|
49
|
+
? {
|
|
50
|
+
[K in keyof NonNullable<TSignals>]: NonNullable<TSignals>[K] extends (
|
|
51
|
+
...args: infer TArgs
|
|
52
|
+
) => infer TResult
|
|
53
|
+
? { args: TArgs; result: TResult }
|
|
54
|
+
: never;
|
|
55
|
+
}
|
|
56
|
+
: never;
|
|
57
|
+
type SignalEmitMap<T> = ResolvedSignalEmitMap<T, DeclaredSignalEmitMap<T>>;
|
|
58
|
+
type SignalEmitName<T> = Extract<keyof SignalEmitMap<T>, string>;
|
|
59
|
+
type SignalEmitArguments<T, K extends SignalEmitName<T>> = SignalEmitMap<T>[K] extends {
|
|
60
|
+
args: infer TArgs extends unknown[];
|
|
61
|
+
}
|
|
62
|
+
? TArgs
|
|
63
|
+
: never;
|
|
64
|
+
type SignalEmitResult<T, K extends SignalEmitName<T>> = SignalEmitMap<T>[K] extends {
|
|
65
|
+
result: infer TResult;
|
|
66
|
+
}
|
|
67
|
+
? TResult
|
|
68
|
+
: never;
|
|
69
|
+
|
|
70
|
+
type SignalConnector = (
|
|
71
|
+
instance: object,
|
|
72
|
+
signal: string,
|
|
73
|
+
handler: SignalHandler,
|
|
74
|
+
isAfter?: boolean,
|
|
75
|
+
) => number;
|
|
76
|
+
type SignalEmitter = (instance: object, signal: string, args: unknown[]) => unknown;
|
|
77
|
+
type SignalDispatch = {
|
|
78
|
+
connect: SignalConnector;
|
|
79
|
+
emit: SignalEmitter;
|
|
80
|
+
};
|
|
81
|
+
type SignalDispatchSpec = {
|
|
82
|
+
connect: SignalConnector;
|
|
83
|
+
emit: SignalEmitter;
|
|
84
|
+
};
|
|
85
|
+
type PendingSignalDispatch = {
|
|
86
|
+
ownerType: bigint;
|
|
87
|
+
spec: SignalDispatchSpec;
|
|
88
|
+
};
|
|
89
|
+
|
|
40
90
|
type DeclaredSignalTypes = {
|
|
41
91
|
paramTypes: bigint[];
|
|
42
92
|
returnType?: bigint;
|
|
@@ -70,6 +120,8 @@ type EmitArg = Arg & {
|
|
|
70
120
|
};
|
|
71
121
|
|
|
72
122
|
const connectionTable: WeakMap<object, Map<string, Set<number>>> = new WeakMap();
|
|
123
|
+
const signalDispatchTable: Map<number, SignalDispatch> = new Map();
|
|
124
|
+
const pendingSignalDispatches: Map<string, PendingSignalDispatch[]> = new Map();
|
|
73
125
|
const gQuarkFromString = bind(LIB, "g_quark_from_string", [stringT("borrowed")], uint32T);
|
|
74
126
|
const gSignalLookup = bind(LIB, "g_signal_lookup", [stringT("borrowed"), biguint64T], uint32T);
|
|
75
127
|
const gSignalName = bind(LIB, "g_signal_name", [uint32T], stringT("borrowed"));
|
|
@@ -114,6 +166,15 @@ const getSignalBaseName = (signal: string): string => {
|
|
|
114
166
|
return detailIndex === -1 ? signal : signal.slice(0, detailIndex);
|
|
115
167
|
};
|
|
116
168
|
|
|
169
|
+
const canonicalSignalName = (signal: string): string => getSignalBaseName(signal).replaceAll("_", "-");
|
|
170
|
+
|
|
171
|
+
const canonicalDetailedSignalName = (signal: string): string => {
|
|
172
|
+
const detailIndex = signal.indexOf("::");
|
|
173
|
+
const base = canonicalSignalName(signal);
|
|
174
|
+
|
|
175
|
+
return detailIndex === -1 ? base : `${base}${signal.slice(detailIndex)}`;
|
|
176
|
+
};
|
|
177
|
+
|
|
117
178
|
function getSignalDetailQuark(signal: string): number {
|
|
118
179
|
const detailIndex = signal.indexOf("::");
|
|
119
180
|
|
|
@@ -180,7 +241,7 @@ function hasSignalListener(instance: object, signals?: string[]): boolean {
|
|
|
180
241
|
}
|
|
181
242
|
|
|
182
243
|
const names =
|
|
183
|
-
signals === undefined ? bySignal.keys().toArray() : signals.map((signal) =>
|
|
244
|
+
signals === undefined ? bySignal.keys().toArray() : signals.map((signal) => canonicalSignalName(signal));
|
|
184
245
|
|
|
185
246
|
return names.some((name) => {
|
|
186
247
|
const handlerIds = bySignal.get(name);
|
|
@@ -242,7 +303,7 @@ function connectSignal(instance: object, signal: string, spec: SignalConnectSpec
|
|
|
242
303
|
const key = `${String(type)}\0${getSignalBaseName(signal)}`;
|
|
243
304
|
const closure = newCCallbackClosure(key, callback, wrapped);
|
|
244
305
|
const handlerId = gSignalConnectClosure(getHandle(instance), signal, closure, isAfter) as number;
|
|
245
|
-
trackConnection(instance,
|
|
306
|
+
trackConnection(instance, canonicalSignalName(signal), handlerId);
|
|
246
307
|
|
|
247
308
|
return handlerId;
|
|
248
309
|
}
|
|
@@ -254,7 +315,7 @@ function overrideSignalClassClosure(type: bigint, signalId: number, handler: Sig
|
|
|
254
315
|
function connectClosureSignal(instance: object, signal: string, handler: SignalHandler, isAfter: boolean): number {
|
|
255
316
|
const closure = toClosure((...args: unknown[]) => Reflect.apply(handler, null, args.slice(1)));
|
|
256
317
|
const handlerId = gSignalConnectClosure(getHandle(instance), signal, closure, isAfter) as number;
|
|
257
|
-
trackConnection(instance,
|
|
318
|
+
trackConnection(instance, canonicalSignalName(signal), handlerId);
|
|
258
319
|
|
|
259
320
|
return handlerId;
|
|
260
321
|
}
|
|
@@ -350,19 +411,129 @@ function emitSignal(instance: object, signal: string, args: EmitArg[], returns?:
|
|
|
350
411
|
return packTupleResult(readEmitOutputs(reads), fromValue(returnValue), true);
|
|
351
412
|
}
|
|
352
413
|
|
|
414
|
+
function installSignalDispatch(
|
|
415
|
+
klass: AnyClass,
|
|
416
|
+
names: readonly string[],
|
|
417
|
+
spec: SignalDispatchSpec,
|
|
418
|
+
): void {
|
|
419
|
+
const ownerType = getClassType(klass);
|
|
420
|
+
|
|
421
|
+
for (const rawName of names) {
|
|
422
|
+
const name = canonicalSignalName(rawName);
|
|
423
|
+
pendingSignalDispatches.getOrInsertComputed(name, () => []).push({ ownerType, spec });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const resolvePendingSignalDispatch = (signalId: number, name: string): SignalDispatch | undefined => {
|
|
428
|
+
const pending = pendingSignalDispatches.get(name) ?? [];
|
|
429
|
+
|
|
430
|
+
for (let index = pending.length - 1; index >= 0; index -= 1) {
|
|
431
|
+
const entry = pending[index];
|
|
432
|
+
|
|
433
|
+
if (
|
|
434
|
+
entry !== undefined &&
|
|
435
|
+
entry.ownerType !== TYPE_INVALID &&
|
|
436
|
+
signalIdFor(entry.ownerType, name) === signalId
|
|
437
|
+
) {
|
|
438
|
+
signalDispatchTable.set(signalId, entry.spec);
|
|
439
|
+
|
|
440
|
+
return entry.spec;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return undefined;
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
const signalDispatchFor = (instance: object, signal: string): SignalDispatch | undefined => {
|
|
448
|
+
const name = canonicalSignalName(signal);
|
|
449
|
+
const instanceType = getInstanceType(instance);
|
|
450
|
+
|
|
451
|
+
if (instanceType === TYPE_INVALID) {
|
|
452
|
+
return undefined;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const signalId = signalIdFor(instanceType, name);
|
|
456
|
+
|
|
457
|
+
if (signalId === 0) {
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return signalDispatchTable.get(signalId) ?? resolvePendingSignalDispatch(signalId, name);
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
const connectDispatcherFor = (instance: object, signal: string): SignalConnector => {
|
|
465
|
+
const dispatch = signalDispatchFor(instance, signal);
|
|
466
|
+
|
|
467
|
+
if (dispatch === undefined) {
|
|
468
|
+
throw new TypeError("connectSignal: unknown signal");
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return dispatch.connect;
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
const emitDispatcherFor = (instance: object, signal: string): SignalEmitter => {
|
|
475
|
+
const dispatch = signalDispatchFor(instance, signal);
|
|
476
|
+
|
|
477
|
+
if (dispatch === undefined) {
|
|
478
|
+
throw new TypeError("emitSignal: unknown signal");
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return dispatch.emit;
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
function signalConnect<T extends object, K extends SignalName<NoInfer<T>>>(
|
|
485
|
+
instance: T,
|
|
486
|
+
signal: K,
|
|
487
|
+
handler: SignalMap<NoInfer<T>>[K],
|
|
488
|
+
isAfter?: boolean,
|
|
489
|
+
): number {
|
|
490
|
+
return connectSignalByName(instance, signal, handler, isAfter);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function connectSignalByName(
|
|
494
|
+
instance: object,
|
|
495
|
+
signal: string,
|
|
496
|
+
handler: unknown,
|
|
497
|
+
isAfter?: boolean,
|
|
498
|
+
): number {
|
|
499
|
+
if (!isSignalHandler(handler)) {
|
|
500
|
+
throw new TypeError("connectSignal: handler must be a function");
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return connectDispatcherFor(instance, signal)(instance, signal, handler, isAfter);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function emitSignalByName(instance: object, signal: string, args: unknown[]): unknown {
|
|
507
|
+
return emitDispatcherFor(instance, signal)(instance, signal, args);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function signalEmit<T extends object, K extends SignalEmitName<NoInfer<T>>>(
|
|
511
|
+
instance: T,
|
|
512
|
+
signal: K,
|
|
513
|
+
...args: SignalEmitArguments<NoInfer<T>, K>
|
|
514
|
+
): SignalEmitResult<NoInfer<T>, K> {
|
|
515
|
+
return emitSignalByName(instance, signal, args) as SignalEmitResult<NoInfer<T>, K>;
|
|
516
|
+
}
|
|
517
|
+
|
|
353
518
|
export {
|
|
519
|
+
canonicalDetailedSignalName,
|
|
520
|
+
canonicalSignalName,
|
|
354
521
|
signalForHandlerName,
|
|
355
522
|
getSignalBaseName,
|
|
356
523
|
signalIdFor,
|
|
357
524
|
connectClosureSignal,
|
|
358
525
|
connectSignal,
|
|
526
|
+
connectSignalByName,
|
|
359
527
|
type DeclaredSignalTypes,
|
|
360
528
|
disconnectSignal,
|
|
361
529
|
emitDeclaredSignal,
|
|
362
530
|
emitSignal,
|
|
531
|
+
emitSignalByName,
|
|
363
532
|
hasSignalListener,
|
|
364
533
|
isSignalHandlerConnected,
|
|
534
|
+
installSignalDispatch,
|
|
365
535
|
overrideSignalClassClosure,
|
|
366
|
-
|
|
536
|
+
signalConnect,
|
|
537
|
+
signalEmit,
|
|
367
538
|
type SignalHandler,
|
|
368
539
|
};
|
package/src/type.ts
CHANGED
|
@@ -86,7 +86,7 @@ const TYPE_VARIANT: bigint = typeFromName("GVariant");
|
|
|
86
86
|
/** GType tag for a Unicode character stored as `guint`. */
|
|
87
87
|
const TYPE_UNICHAR: bigint = typeFromName("guint");
|
|
88
88
|
const getErrorType: () => bigint = lazyType("GError");
|
|
89
|
-
const getStrvType
|
|
89
|
+
const getStrvType = (): bigint => resolveType(LIB, "g_strv_get_type");
|
|
90
90
|
|
|
91
91
|
const PLAIN_DESCRIPTOR_TYPES: Partial<Record<Descriptor["kind"], bigint>> = {
|
|
92
92
|
boolean: TYPE_BOOLEAN,
|
package/src/value.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
int32T,
|
|
18
18
|
type ObjectDescriptor,
|
|
19
19
|
objectT,
|
|
20
|
+
preserveArrayNull,
|
|
20
21
|
stringT,
|
|
21
22
|
uint8T,
|
|
22
23
|
uint32T,
|
|
@@ -133,11 +134,25 @@ const objectValueFundamentals: Set<bigint> = new Set([TYPE_OBJECT, TYPE_INTERFAC
|
|
|
133
134
|
const paramValueType = bindValueType("param", PARAM_T);
|
|
134
135
|
const variantValueType = bindValueType("variant", VARIANT_T);
|
|
135
136
|
const pointerValueType = bindValueType("pointer", uint64T);
|
|
136
|
-
const
|
|
137
|
+
const strvDescriptor = arrayT(stringT("borrowed"));
|
|
138
|
+
const nullableStrvDescriptor = preserveArrayNull(arrayT(stringT("borrowed")));
|
|
139
|
+
const setStrvBoxed = bind(LIB, "g_value_set_boxed", [VALUE_T, strvDescriptor], voidT);
|
|
140
|
+
const getStrvBoxed = bind(LIB, "g_value_get_boxed", [VALUE_T], strvDescriptor);
|
|
141
|
+
const getNullableStrvBoxed = bind(
|
|
142
|
+
LIB,
|
|
143
|
+
"g_value_get_boxed",
|
|
144
|
+
[VALUE_T],
|
|
145
|
+
nullableStrvDescriptor,
|
|
146
|
+
);
|
|
137
147
|
|
|
138
148
|
const strvValueType: ValueType = {
|
|
139
149
|
set: setStrvValue,
|
|
140
|
-
get:
|
|
150
|
+
get: getStrvBoxed,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const nullableStrvValueType: ValueType = {
|
|
154
|
+
set: setStrvValue,
|
|
155
|
+
get: getNullableStrvBoxed,
|
|
141
156
|
};
|
|
142
157
|
|
|
143
158
|
const setByteArrayBoxed = bind(LIB, "g_value_set_boxed", [VALUE_T, byteArrayT()], voidT);
|
|
@@ -412,7 +427,7 @@ function setWrappedBoxedValue(value: ExternalObject<Handle>, type: bigint, boxed
|
|
|
412
427
|
|
|
413
428
|
const arrayValueType = (descriptor: ArrayDescriptor): ValueType => {
|
|
414
429
|
if (descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array") {
|
|
415
|
-
return strvValueType;
|
|
430
|
+
return descriptor.preserveNull === true ? nullableStrvValueType : strvValueType;
|
|
416
431
|
}
|
|
417
432
|
|
|
418
433
|
if (descriptor.arrayKind === "gbytearray") {
|
|
@@ -728,6 +743,9 @@ function fromValue(value: ExternalObject<Handle>): unknown {
|
|
|
728
743
|
return get(value);
|
|
729
744
|
}
|
|
730
745
|
|
|
746
|
+
const fromObjectPropertyValue = (value: ExternalObject<Handle>): unknown =>
|
|
747
|
+
getValueType(value) === getStrvType() ? nullableStrvValueType.get(value) : fromValue(value);
|
|
748
|
+
|
|
731
749
|
const objectValueWithFallback = (
|
|
732
750
|
descriptor: ObjectDescriptor,
|
|
733
751
|
value: ExternalObject<Handle>,
|
|
@@ -739,9 +757,25 @@ const objectValueWithFallback = (
|
|
|
739
757
|
return { wrapped: wrapObject(objectValueType.get(value), descriptor.fallbackClass) };
|
|
740
758
|
};
|
|
741
759
|
|
|
760
|
+
const arrayValueGetterForDescriptor = (descriptor: ArrayDescriptor): ValueGetter | undefined => {
|
|
761
|
+
if (descriptor.arrayKind === "gbytearray") {
|
|
762
|
+
return byteArrayValueGetterFor(descriptor.isBytes === true);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array"
|
|
766
|
+
? arrayValueType(descriptor).get
|
|
767
|
+
: undefined;
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
const fromArrayValueForDescriptor = (descriptor: ArrayDescriptor, value: ExternalObject<Handle>): unknown => {
|
|
771
|
+
const get = arrayValueGetterForDescriptor(descriptor);
|
|
772
|
+
|
|
773
|
+
return get === undefined ? fromValue(value) : get(value);
|
|
774
|
+
};
|
|
775
|
+
|
|
742
776
|
const fromValueForDescriptor = (descriptor: Descriptor, value: ExternalObject<Handle>): unknown => {
|
|
743
|
-
if (descriptor.kind === "array"
|
|
744
|
-
return
|
|
777
|
+
if (descriptor.kind === "array") {
|
|
778
|
+
return fromArrayValueForDescriptor(descriptor, value);
|
|
745
779
|
}
|
|
746
780
|
|
|
747
781
|
if (descriptor.kind === "object") {
|
|
@@ -815,6 +849,7 @@ export {
|
|
|
815
849
|
tryToValueHandle,
|
|
816
850
|
ValueMarshalError,
|
|
817
851
|
fromValue,
|
|
852
|
+
fromObjectPropertyValue,
|
|
818
853
|
fromValueForDescriptor,
|
|
819
854
|
valueGuardOverrideFor,
|
|
820
855
|
newValueForDescriptor,
|