@ttsc/factory 0.22.0 → 0.23.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/README.md +2 -0
- package/lib/comments.d.ts +5 -4
- package/lib/comments.js +40 -2
- package/lib/comments.js.map +1 -1
- package/lib/comments.mjs +40 -2
- package/lib/comments.mjs.map +1 -1
- package/package.json +1 -1
- package/src/comments.ts +54 -6
package/README.md
CHANGED
|
@@ -123,6 +123,8 @@ new TsPrinter().print(node);
|
|
|
123
123
|
|
|
124
124
|
Companion helpers: `addSyntheticTrailingComment`, `get`/`setSyntheticLeadingComments`, `get`/`setSyntheticTrailingComments`.
|
|
125
125
|
|
|
126
|
+
Synthetic comments are side-band data: they do not add properties to the node, so comments can be attached to frozen nodes. Compatible copies loaded in the same JavaScript realm share the versioned weak stores, including a CommonJS `require()` and an ES module `import()` of one installation or multiple installed copies. If a hardened realm prevents adding the registry to its global object before the first copy loads, each module falls back to private weak stores: comments and frozen nodes still work within that copy, but copies cannot exchange comments. A copy from an older release that predates this registry likewise cannot see comments written by a newer copy (or expose its private comments to one); upgrade every copy that exchanges nodes.
|
|
127
|
+
|
|
126
128
|
## Coverage
|
|
127
129
|
|
|
128
130
|
The factory and printer cover the constructs most used for code generation: identifiers, literals, the common expressions, types (keyword / reference / union / intersection / array / tuple / type-literal / function / operator / ...), statements, classes & interfaces, enums, functions & arrow functions, and import / export declarations. Coverage is easy to extend — add the node under `src/ast/`, a builder under `src/factory/`, and a `case` to the printer.
|
package/lib/comments.d.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The legacy TypeScript compiler stores synthesized comments on a side-band
|
|
6
6
|
* `node.emitNode` slot rather than on the node itself; this module reproduces
|
|
7
|
-
* that behaviour with
|
|
8
|
-
* interfaces stay free of printer-only metadata
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* that behaviour with realm-shared {@link WeakMap}s so the
|
|
8
|
+
* {@link import("./ast").Node} interfaces stay free of printer-only metadata and
|
|
9
|
+
* frozen nodes remain valid targets. {@link TsPrinter} consults these stores
|
|
10
|
+
* while emitting and renders the comments verbatim — a leading comment is
|
|
11
|
+
* printed before the node, a trailing comment after it.
|
|
11
12
|
*
|
|
12
13
|
* ```typescript
|
|
13
14
|
* import factory, {
|
package/lib/comments.js
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setSyntheticTrailingComments = exports.setSyntheticLeadingComments = exports.getSyntheticTrailingComments = exports.getSyntheticLeadingComments = exports.addSyntheticTrailingComment = exports.addSyntheticLeadingComment = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* One versioned registry per JavaScript realm.
|
|
6
|
+
*
|
|
7
|
+
* A package can be loaded through both its CommonJS and ESM entry points, and
|
|
8
|
+
* package managers may install multiple physical copies. Module-local WeakMaps
|
|
9
|
+
* make those copies silently lose each other's comments even though factory
|
|
10
|
+
* nodes are otherwise structural. A well-known, versioned key gives every
|
|
11
|
+
* compatible copy the same side-band stores without writing metadata to the
|
|
12
|
+
* node, so `Object.freeze(node)` keeps working as it did before.
|
|
13
|
+
*
|
|
14
|
+
* The version belongs to the stored value shape. A future incompatible shape
|
|
15
|
+
* must use another key rather than reinterpret an older registry.
|
|
16
|
+
*/
|
|
17
|
+
const SYNTHETIC_COMMENT_STORES = Symbol.for("@ttsc/factory.syntheticComments.v1");
|
|
18
|
+
const createCommentStores = () => ({
|
|
19
|
+
leading: new WeakMap(),
|
|
20
|
+
trailing: new WeakMap(),
|
|
21
|
+
});
|
|
22
|
+
const localCommentStores = createCommentStores();
|
|
23
|
+
const commentStores = () => {
|
|
24
|
+
const existing = Reflect.get(globalThis, SYNTHETIC_COMMENT_STORES);
|
|
25
|
+
if (existing !== undefined)
|
|
26
|
+
return existing;
|
|
27
|
+
try {
|
|
28
|
+
Object.defineProperty(globalThis, SYNTHETIC_COMMENT_STORES, {
|
|
29
|
+
configurable: false,
|
|
30
|
+
enumerable: false,
|
|
31
|
+
value: localCommentStores,
|
|
32
|
+
writable: false,
|
|
33
|
+
});
|
|
34
|
+
return localCommentStores;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Hardened realms can prohibit new global properties. Preserve the
|
|
38
|
+
// historical single-module behaviour there instead of making package load
|
|
39
|
+
// fail; cross-copy sharing necessarily requires a realm-owned rendezvous.
|
|
40
|
+
return localCommentStores;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const { leading: leadingStore, trailing: trailingStore } = commentStores();
|
|
6
44
|
const append = (store, node, comment) => {
|
|
7
45
|
const list = store.get(node);
|
|
8
46
|
if (list !== undefined)
|
package/lib/comments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"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"}
|
package/lib/comments.mjs
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* One versioned registry per JavaScript realm.
|
|
3
|
+
*
|
|
4
|
+
* A package can be loaded through both its CommonJS and ESM entry points, and
|
|
5
|
+
* package managers may install multiple physical copies. Module-local WeakMaps
|
|
6
|
+
* make those copies silently lose each other's comments even though factory
|
|
7
|
+
* nodes are otherwise structural. A well-known, versioned key gives every
|
|
8
|
+
* compatible copy the same side-band stores without writing metadata to the
|
|
9
|
+
* node, so `Object.freeze(node)` keeps working as it did before.
|
|
10
|
+
*
|
|
11
|
+
* The version belongs to the stored value shape. A future incompatible shape
|
|
12
|
+
* must use another key rather than reinterpret an older registry.
|
|
13
|
+
*/
|
|
14
|
+
const SYNTHETIC_COMMENT_STORES = Symbol.for("@ttsc/factory.syntheticComments.v1");
|
|
15
|
+
const createCommentStores = () => ({
|
|
16
|
+
leading: new WeakMap(),
|
|
17
|
+
trailing: new WeakMap(),
|
|
18
|
+
});
|
|
19
|
+
const localCommentStores = createCommentStores();
|
|
20
|
+
const commentStores = () => {
|
|
21
|
+
const existing = Reflect.get(globalThis, SYNTHETIC_COMMENT_STORES);
|
|
22
|
+
if (existing !== undefined)
|
|
23
|
+
return existing;
|
|
24
|
+
try {
|
|
25
|
+
Object.defineProperty(globalThis, SYNTHETIC_COMMENT_STORES, {
|
|
26
|
+
configurable: false,
|
|
27
|
+
enumerable: false,
|
|
28
|
+
value: localCommentStores,
|
|
29
|
+
writable: false,
|
|
30
|
+
});
|
|
31
|
+
return localCommentStores;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Hardened realms can prohibit new global properties. Preserve the
|
|
35
|
+
// historical single-module behaviour there instead of making package load
|
|
36
|
+
// fail; cross-copy sharing necessarily requires a realm-owned rendezvous.
|
|
37
|
+
return localCommentStores;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const { leading: leadingStore, trailing: trailingStore } = commentStores();
|
|
3
41
|
const append = (store, node, comment) => {
|
|
4
42
|
const list = store.get(node);
|
|
5
43
|
if (list !== undefined)
|
package/lib/comments.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.mjs","sources":["../src/comments.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"comments.mjs","sources":["../src/comments.ts"],"sourcesContent":[null],"names":[],"mappings":"AAiEA;;;;;;;;;;;;AAYG;AACH,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CACzC,oCAAoC,CACrC;AAED,MAAM,mBAAmB,GAAG,OAA+B;IACzD,OAAO,EAAE,IAAI,OAAO,EAAgC;IACpD,QAAQ,EAAE,IAAI,OAAO,EAAgC;AACtD,CAAA,CAAC;AAEF,MAAM,kBAAkB,GAAG,mBAAmB,EAAE;AAEhD,MAAM,aAAa,GAAG,MAA6B;IACjD,MAAM,QAAQ,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,wBAAwB,CAAC;IAC3E,IAAI,QAAQ,KAAK,SAAS;AAAE,QAAA,OAAO,QAAkC;AACrE,IAAA,IAAI;AACF,QAAA,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,wBAAwB,EAAE;AAC1D,YAAA,YAAY,EAAE,KAAK;AACnB,YAAA,UAAU,EAAE,KAAK;AACjB,YAAA,KAAK,EAAE,kBAAkB;AACzB,YAAA,QAAQ,EAAE,KAAK;AAChB,SAAA,CAAC;AACF,QAAA,OAAO,kBAAkB;IAC3B;AAAE,IAAA,MAAM;;;;AAIN,QAAA,OAAO,kBAAkB;IAC3B;AACF,CAAC;AAED,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE;AAE1E,MAAM,MAAM,GAAG,CACb,KAA4C,EAC5C,IAAY,EACZ,OAA2B,KACnB;IACR,MAAM,IAAI,GAAqC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9D,IAAI,IAAI,KAAK,SAAS;AAAE,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;;QACrC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;AAYG;AACI,MAAM,0BAA0B,GAAG,CACxC,IAAO,EACP,IAAgC,EAChC,IAAY,EACZ,kBAA4B,KACvB;AACL,IAAA,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;AAC9D,IAAA,OAAO,IAAI;AACb;AAEA;;;;;;;;;;;;AAYG;AACI,MAAM,2BAA2B,GAAG,CACzC,IAAO,EACP,IAAgC,EAChC,IAAY,EACZ,kBAA4B,KACvB;AACL,IAAA,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;AAC/D,IAAA,OAAO,IAAI;AACb;AAEA;AACO,MAAM,2BAA2B,GAAG,CACzC,IAAU,KAC2B,YAAY,CAAC,GAAG,CAAC,IAAI;AAE5D;AACO,MAAM,4BAA4B,GAAG,CAC1C,IAAU,KAC2B,aAAa,CAAC,GAAG,CAAC,IAAI;AAE7D;;;;;AAKG;MACU,2BAA2B,GAAG,CACzC,IAAO,EACP,QAAmD,KAC9C;IACL,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QACjD,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;;AACrC,QAAA,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;AAC9B,IAAA,OAAO,IAAI;AACb;AAEA;;;;;AAKG;MACU,4BAA4B,GAAG,CAC1C,IAAO,EACP,QAAmD,KAC9C;IACL,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QACjD,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;;AACtC,QAAA,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;AAC/B,IAAA,OAAO,IAAI;AACb;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttsc/factory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Self-contained legacy-style TypeScript AST factory and printer for source code generation, surviving the TypeScript-Go (tsgo) migration. Zero dependencies, no `typescript` import.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"exports": {
|
package/src/comments.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The legacy TypeScript compiler stores synthesized comments on a side-band
|
|
6
6
|
* `node.emitNode` slot rather than on the node itself; this module reproduces
|
|
7
|
-
* that behaviour with
|
|
8
|
-
* interfaces stay free of printer-only metadata
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* that behaviour with realm-shared {@link WeakMap}s so the
|
|
8
|
+
* {@link import("./ast").Node} interfaces stay free of printer-only metadata and
|
|
9
|
+
* frozen nodes remain valid targets. {@link TsPrinter} consults these stores
|
|
10
|
+
* while emitting and renders the comments verbatim — a leading comment is
|
|
11
|
+
* printed before the node, a trailing comment after it.
|
|
11
12
|
*
|
|
12
13
|
* ```typescript
|
|
13
14
|
* import factory, {
|
|
@@ -57,8 +58,55 @@ export interface SynthesizedComment {
|
|
|
57
58
|
hasLeadingNewLine?: boolean;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
interface SyntheticCommentStores {
|
|
62
|
+
leading: WeakMap<object, SynthesizedComment[]>;
|
|
63
|
+
trailing: WeakMap<object, SynthesizedComment[]>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* One versioned registry per JavaScript realm.
|
|
68
|
+
*
|
|
69
|
+
* A package can be loaded through both its CommonJS and ESM entry points, and
|
|
70
|
+
* package managers may install multiple physical copies. Module-local WeakMaps
|
|
71
|
+
* make those copies silently lose each other's comments even though factory
|
|
72
|
+
* nodes are otherwise structural. A well-known, versioned key gives every
|
|
73
|
+
* compatible copy the same side-band stores without writing metadata to the
|
|
74
|
+
* node, so `Object.freeze(node)` keeps working as it did before.
|
|
75
|
+
*
|
|
76
|
+
* The version belongs to the stored value shape. A future incompatible shape
|
|
77
|
+
* must use another key rather than reinterpret an older registry.
|
|
78
|
+
*/
|
|
79
|
+
const SYNTHETIC_COMMENT_STORES = Symbol.for(
|
|
80
|
+
"@ttsc/factory.syntheticComments.v1",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const createCommentStores = (): SyntheticCommentStores => ({
|
|
84
|
+
leading: new WeakMap<object, SynthesizedComment[]>(),
|
|
85
|
+
trailing: new WeakMap<object, SynthesizedComment[]>(),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const localCommentStores = createCommentStores();
|
|
89
|
+
|
|
90
|
+
const commentStores = (): SyntheticCommentStores => {
|
|
91
|
+
const existing: unknown = Reflect.get(globalThis, SYNTHETIC_COMMENT_STORES);
|
|
92
|
+
if (existing !== undefined) return existing as SyntheticCommentStores;
|
|
93
|
+
try {
|
|
94
|
+
Object.defineProperty(globalThis, SYNTHETIC_COMMENT_STORES, {
|
|
95
|
+
configurable: false,
|
|
96
|
+
enumerable: false,
|
|
97
|
+
value: localCommentStores,
|
|
98
|
+
writable: false,
|
|
99
|
+
});
|
|
100
|
+
return localCommentStores;
|
|
101
|
+
} catch {
|
|
102
|
+
// Hardened realms can prohibit new global properties. Preserve the
|
|
103
|
+
// historical single-module behaviour there instead of making package load
|
|
104
|
+
// fail; cross-copy sharing necessarily requires a realm-owned rendezvous.
|
|
105
|
+
return localCommentStores;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const { leading: leadingStore, trailing: trailingStore } = commentStores();
|
|
62
110
|
|
|
63
111
|
const append = (
|
|
64
112
|
store: WeakMap<object, SynthesizedComment[]>,
|