@gtkx/codegen 1.1.0 → 1.2.1
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 +2 -4
- 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/class.d.ts +7 -2
- package/dist/gir/class.d.ts.map +1 -1
- package/dist/gir/class.js +4 -1
- package/dist/gir/class.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 +2 -4
- package/dist/store/gi/callables.d.ts.map +1 -1
- package/dist/store/gi/callables.js +22 -7
- 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 +63 -17
- 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/gtype-binding.d.ts +2 -1
- package/dist/store/gi/gtype-binding.d.ts.map +1 -1
- package/dist/store/gi/gtype-binding.js +13 -1
- package/dist/store/gi/gtype-binding.js.map +1 -1
- package/dist/store/gi/interface.js +4 -4
- 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.d.ts.map +1 -1
- package/dist/store/gi/record-constructor.js +7 -5
- package/dist/store/gi/record-constructor.js.map +1 -1
- package/dist/store/gi/record-field-accessor.d.ts +3 -2
- package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
- package/dist/store/gi/record-field-accessor.js +42 -12
- 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 +5 -9
- package/dist/store/gi/record.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 +27 -6
- 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/resolve-store.d.ts.map +1 -1
- package/dist/store/resolve-store.js +1 -0
- package/dist/store/resolve-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 +1 -5
- package/src/fingerprint.ts +31 -38
- package/src/gi.ts +9 -2
- package/src/gir/class.ts +12 -3
- 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 +30 -11
- package/src/store/gi/class.ts +96 -21
- package/src/store/gi/constant.ts +1 -1
- package/src/store/gi/enum.ts +2 -6
- package/src/store/gi/gtype-binding.ts +16 -1
- package/src/store/gi/interface.ts +4 -4
- package/src/store/gi/method.ts +4 -9
- package/src/store/gi/property-accessor.ts +22 -193
- package/src/store/gi/record-constructor.ts +7 -5
- package/src/store/gi/record-field-accessor.ts +65 -13
- package/src/store/gi/record.ts +13 -17
- package/src/store/gi/return-wrap.ts +1 -1
- package/src/store/gi/signal.ts +36 -13
- package/src/store/jsx-store.ts +0 -1
- package/src/store/resolve-store.ts +1 -0
- package/src/store/store-fs.ts +3 -9
- package/src/xml.ts +43 -1
package/src/store/gi/record.ts
CHANGED
|
@@ -12,6 +12,14 @@ import { computeRecordFieldSlots } from "./record-layout.js";
|
|
|
12
12
|
import { appendWrapperClassRegistration } from "./registration.js";
|
|
13
13
|
import { isConstructibleRecord } from "./value-marshalable.js";
|
|
14
14
|
|
|
15
|
+
type RecordMembersOptions = {
|
|
16
|
+
context: ModuleContext;
|
|
17
|
+
record: GirRecord;
|
|
18
|
+
className: string;
|
|
19
|
+
callables: Callables;
|
|
20
|
+
gtypeExpr: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
|
|
15
23
|
const isGErrorRecord = (context: ModuleContext, record: GirRecord): boolean =>
|
|
16
24
|
context.namespace.name === "GLib" && record.glibGetType === "g_error_get_type";
|
|
17
25
|
|
|
@@ -30,7 +38,8 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
30
38
|
};
|
|
31
39
|
|
|
32
40
|
generateBindings(context, callables);
|
|
33
|
-
const
|
|
41
|
+
const gtypeExpr = renderSourceGtype(context, record);
|
|
42
|
+
const members = renderRecordMembers({ context, record, className, callables, gtypeExpr });
|
|
34
43
|
const body = indentMembers(members);
|
|
35
44
|
const heritage = isErrorSubclass ? " extends globalThis.Error" : "";
|
|
36
45
|
const doc = getDoc(record);
|
|
@@ -50,29 +59,16 @@ const generateRecord = (context: ModuleContext, record: GirRecord): void => {
|
|
|
50
59
|
});
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
const gtypeExpr = renderSourceGtype(context, record);
|
|
54
|
-
|
|
55
62
|
appendWrapperClassRegistration(context, {
|
|
56
63
|
className,
|
|
57
64
|
gtypeExpr,
|
|
58
65
|
});
|
|
59
66
|
};
|
|
60
67
|
|
|
61
|
-
const renderRecordMembers = (
|
|
62
|
-
context
|
|
63
|
-
record: GirRecord,
|
|
64
|
-
className: string,
|
|
65
|
-
callables: Callables,
|
|
66
|
-
): string[] => {
|
|
68
|
+
const renderRecordMembers = (options: RecordMembersOptions): string[] => {
|
|
69
|
+
const { context, record, className, callables, gtypeExpr } = options;
|
|
67
70
|
const isErrorSubclass = isGErrorRecord(context, record);
|
|
68
|
-
|
|
69
|
-
const { members, claimedNames } = renderPlainTypeMembers({
|
|
70
|
-
context,
|
|
71
|
-
className,
|
|
72
|
-
callables,
|
|
73
|
-
hasGtype: record.glibGetType !== undefined,
|
|
74
|
-
});
|
|
75
|
-
|
|
71
|
+
const { members, claimedNames } = renderPlainTypeMembers({ context, className, callables, gtypeExpr });
|
|
76
72
|
members.unshift(renderRecordConstructor(context, { record, className, callables, isErrorSubclass }));
|
|
77
73
|
const { slots } = computeRecordFieldSlots(context, record.fields, record.isUnion);
|
|
78
74
|
|
|
@@ -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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { camelCase, sourceStringLiteral } from "@gtkx/utils";
|
|
2
|
-
import type { GirClass } from "../../gir/class.js";
|
|
2
|
+
import type { GirClass, GirSignal } from "../../gir/class.js";
|
|
3
3
|
import type { GirCallable, GirParameter, GirReturnValue } from "../../gir/parameter.js";
|
|
4
4
|
import type { GirProperty } from "../../gir/property.js";
|
|
5
5
|
import type { ModuleContext } from "../../writer/context.js";
|
|
@@ -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 + \"'\");"
|
|
@@ -124,10 +139,18 @@ const renderSignalMap = (spec: SignalMapSpec): string => {
|
|
|
124
139
|
const { context, klass, className, isParentlessObjectSubclass, suffix, renderEntry } = spec;
|
|
125
140
|
const extendsRefs = signalMapParentRefs(context, klass, isParentlessObjectSubclass, suffix);
|
|
126
141
|
const extendsClause = extendsRefs.length === 0 ? "" : ` extends ${extendsRefs.join(", ")}`;
|
|
142
|
+
const signals = collectClassSignals(context, klass);
|
|
127
143
|
|
|
128
|
-
const signalEntries =
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
const signalEntries = signals.flatMap((signal) => {
|
|
145
|
+
const value = renderEntry(context, signal);
|
|
146
|
+
const entry = `${signalDoc(signal)}${sourceStringLiteral(signal.name)}: ${value};`;
|
|
147
|
+
|
|
148
|
+
if (!signal.isDetailed) {
|
|
149
|
+
return [entry];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return [entry, `[detail: \`${signal.name}::\${string}\`]: ${value};`];
|
|
153
|
+
});
|
|
131
154
|
|
|
132
155
|
const entries = [...signalEntries, ...renderNotifyDetailEntries(context, klass, suffix)];
|
|
133
156
|
|
|
@@ -191,17 +214,17 @@ const renderSignalConnectInterface = (className: string, isRootObject: boolean):
|
|
|
191
214
|
const lines = [
|
|
192
215
|
`__signals__?: ${map};`,
|
|
193
216
|
`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
217
|
`emit<K extends keyof ${emitMap}>(sigName: K, ...args: ${emitMap}[K]["args"]): ${emitMap}[K]["result"];`,
|
|
196
|
-
"emit(sigName: string, ...args: unknown[]): unknown;",
|
|
197
218
|
];
|
|
198
219
|
|
|
199
|
-
if (
|
|
220
|
+
if (isRootObject) {
|
|
221
|
+
lines.push("emit(sigName: string, ...args: unknown[]): unknown;");
|
|
222
|
+
} else {
|
|
200
223
|
const chainable = (methods: string[], trailing: string): void => {
|
|
201
224
|
for (const method of methods) {
|
|
202
225
|
lines.push(
|
|
226
|
+
deprecatedAliasDoc(method) +
|
|
203
227
|
`${method}<K extends keyof ${map}>(signal: K, handler: ${map}[K]${trailing}): this;`,
|
|
204
|
-
`${method}(signal: string, handler: ${SIGNAL_HANDLER_TYPE}${trailing}): this;`,
|
|
205
228
|
);
|
|
206
229
|
}
|
|
207
230
|
};
|
|
@@ -356,7 +379,7 @@ const renderCallback = (context: ModuleContext, signal: GirCallable): string =>
|
|
|
356
379
|
const forEachInterfaceSignal = (
|
|
357
380
|
context: ModuleContext,
|
|
358
381
|
klass: GirClass,
|
|
359
|
-
consider: (signal:
|
|
382
|
+
consider: (signal: GirSignal) => void,
|
|
360
383
|
): void => {
|
|
361
384
|
for (const iface of resolveInterfaces(context.library, context.namespace.name, klass.implements)) {
|
|
362
385
|
for (const signal of iface.klass.signals) {
|
|
@@ -365,12 +388,12 @@ const forEachInterfaceSignal = (
|
|
|
365
388
|
}
|
|
366
389
|
};
|
|
367
390
|
|
|
368
|
-
const collectClassSignals = (context: ModuleContext, klass: GirClass):
|
|
391
|
+
const collectClassSignals = (context: ModuleContext, klass: GirClass): GirSignal[] => {
|
|
369
392
|
const inheritedNames = collectInheritedSignalNames(context, klass);
|
|
370
393
|
const seen: Set<string> = new Set();
|
|
371
|
-
const result:
|
|
394
|
+
const result: GirSignal[] = [];
|
|
372
395
|
|
|
373
|
-
const consider = (signal:
|
|
396
|
+
const consider = (signal: GirSignal): void => {
|
|
374
397
|
const name = camelCase(signal.name);
|
|
375
398
|
|
|
376
399
|
if (!signal.introspectable || inheritedNames.has(name) || seen.has(name)) {
|
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
|
}
|