@gi-tcg/gts-transpiler 0.4.4 → 0.4.5
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/index.js
CHANGED
|
@@ -1293,7 +1293,7 @@ function applyReplacements(state, code, mappings) {
|
|
|
1293
1293
|
? ${payload.attrName} /* have duplicate, disable this */
|
|
1294
1294
|
: never
|
|
1295
1295
|
);
|
|
1296
|
-
let ${payload.lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${omittedKeys}>;
|
|
1296
|
+
let ${payload.lhs}!: ${payload.hintOnly ? `{}` : `{ ${Meta}: ${payload.metaType} }`} & Omit<${payload.defType}, ${omittedKeys}>;
|
|
1297
1297
|
`;
|
|
1298
1298
|
} else if (payload.type === "createBindingTyping") {
|
|
1299
1299
|
const typingIdLhs = `${payload.typingId}_lhs`;
|
|
@@ -1328,6 +1328,7 @@ function applyReplacements(state, code, mappings) {
|
|
|
1328
1328
|
//#endregion
|
|
1329
1329
|
//#region src/transform/volar/walker.ts
|
|
1330
1330
|
const EMPTY = { type: "EmptyStatement" };
|
|
1331
|
+
const ATTR_HINT_ATTR_NAME = JSON.stringify("~attrNameHint");
|
|
1331
1332
|
const enterVMFromRoot = (state) => {
|
|
1332
1333
|
let defTypeId = {
|
|
1333
1334
|
type: "Identifier",
|
|
@@ -1407,7 +1408,8 @@ const enterAttr = (state, attrName) => {
|
|
|
1407
1408
|
defType: defTypeId.name,
|
|
1408
1409
|
metaType: metaTypeId.name,
|
|
1409
1410
|
lhs: lhsId.name,
|
|
1410
|
-
attrName
|
|
1411
|
+
attrName,
|
|
1412
|
+
hintOnly: attrName === ATTR_HINT_ATTR_NAME
|
|
1411
1413
|
}));
|
|
1412
1414
|
return { lhsId };
|
|
1413
1415
|
};
|
|
@@ -1439,6 +1441,19 @@ const exitAttr = (state, returningId) => {
|
|
|
1439
1441
|
returnType: returningId.name
|
|
1440
1442
|
}));
|
|
1441
1443
|
};
|
|
1444
|
+
const insertHintStatement = (state, whiteSpaceStart, whiteSpaceEnd) => {
|
|
1445
|
+
const { lhsId } = enterAttr(state, ATTR_HINT_ATTR_NAME);
|
|
1446
|
+
state.typingPendingStatements.push({
|
|
1447
|
+
type: "GTSAttributeNameHintStatement",
|
|
1448
|
+
object: lhsId,
|
|
1449
|
+
whiteSpaceStart,
|
|
1450
|
+
whiteSpaceEnd
|
|
1451
|
+
});
|
|
1452
|
+
exitAttr(state, {
|
|
1453
|
+
type: "Identifier",
|
|
1454
|
+
name: `__gts_attrRet_hint_${state.idCounter++}`
|
|
1455
|
+
});
|
|
1456
|
+
};
|
|
1442
1457
|
const gtsToTypingsWalker = {
|
|
1443
1458
|
Program(node, { state, visit }) {
|
|
1444
1459
|
const body = [];
|
|
@@ -1638,7 +1653,17 @@ const gtsToTypingsWalker = {
|
|
|
1638
1653
|
return EMPTY;
|
|
1639
1654
|
},
|
|
1640
1655
|
GTSNamedAttributeBlock(node, { state, visit }) {
|
|
1641
|
-
|
|
1656
|
+
const attributeListEnd = node.directAction?.range?.[0] ?? node.range?.[1] ?? -1;
|
|
1657
|
+
const attributeListStart = node.attributes[0]?.range?.[0] ?? attributeListEnd;
|
|
1658
|
+
if (node.range && attributeListStart > node.range[0] + 1) insertHintStatement(state, node.range[0] + 1, attributeListStart - 1);
|
|
1659
|
+
for (let i = 0; i < node.attributes.length; i++) {
|
|
1660
|
+
const attribute = node.attributes[i];
|
|
1661
|
+
visit(attribute);
|
|
1662
|
+
let nextTokenStart;
|
|
1663
|
+
if (i < node.attributes.length - 1) nextTokenStart = node.attributes[i + 1].range?.[0] ?? -1;
|
|
1664
|
+
else nextTokenStart = attributeListEnd;
|
|
1665
|
+
if (attribute.range && nextTokenStart > attribute.range[1]) insertHintStatement(state, attribute.range[1], nextTokenStart - 1);
|
|
1666
|
+
}
|
|
1642
1667
|
if (node.directAction) {
|
|
1643
1668
|
const stubStatement = {
|
|
1644
1669
|
type: "ExpressionStatement",
|
|
@@ -1695,6 +1720,7 @@ const gtsToTypingsWalker = {
|
|
|
1695
1720
|
}
|
|
1696
1721
|
}]
|
|
1697
1722
|
});
|
|
1723
|
+
exitAttr(state, returnValue);
|
|
1698
1724
|
}
|
|
1699
1725
|
return EMPTY;
|
|
1700
1726
|
},
|
|
@@ -1735,6 +1761,7 @@ function getPrintOptions(source, state) {
|
|
|
1735
1761
|
if (state.attributeNameNodes.has(node)) return false;
|
|
1736
1762
|
return state.sourceNodes.has(node);
|
|
1737
1763
|
},
|
|
1764
|
+
printCommentsOnUntouchedNodes: true,
|
|
1738
1765
|
getLeadingComments: (node) => node.leadingComments,
|
|
1739
1766
|
getTrailingComments: (node) => node.trailingComments,
|
|
1740
1767
|
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
@@ -1804,6 +1831,12 @@ function getPrintOptions(source, state) {
|
|
|
1804
1831
|
end: state.contentStartOffset + 1
|
|
1805
1832
|
}, context.generatedOffset, context.generatedOffset + 1, DEFAULT_VOLAR_MAPPING_DATA);
|
|
1806
1833
|
}
|
|
1834
|
+
},
|
|
1835
|
+
GTSAttributeNameHintStatement(node, context) {
|
|
1836
|
+
context.writeNode(node.object);
|
|
1837
|
+
context.write(".");
|
|
1838
|
+
context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
|
|
1839
|
+
context.write(";");
|
|
1807
1840
|
}
|
|
1808
1841
|
},
|
|
1809
1842
|
experimentalGetLeftParenSourceRange: (node) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gi-tcg/gts-transpiler",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/piovium/gts.git"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@sveltejs/acorn-typescript": "^1.0.8",
|
|
23
23
|
"acorn": "^8.15.0",
|
|
24
24
|
"dedent": "^1.7.2",
|
|
25
|
-
"espolar": "^0.6.
|
|
25
|
+
"espolar": "^0.6.1",
|
|
26
26
|
"esrap": "2.2.1",
|
|
27
27
|
"magic-string": "^0.30.21",
|
|
28
28
|
"path-browserify-esm": "^1.0.6",
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type AST as EspolarAST,
|
|
11
11
|
defaultPrinters,
|
|
12
12
|
type SourceRange,
|
|
13
|
+
type PrinterContext,
|
|
13
14
|
} from "espolar";
|
|
14
15
|
import type { CodeInformation } from "@volar/language-core";
|
|
15
16
|
import {
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
LITERAL_FROM_ID_MAPPING_DATA,
|
|
20
21
|
VERIFICATION_ONLY_MAPPING_DATA,
|
|
21
22
|
} from "./mappings.ts";
|
|
22
|
-
import type { TypingTranspileState } from "./walker.ts";
|
|
23
|
+
import type { TypingTranspileState, GTSAttributeNameHintStatement } from "./walker.ts";
|
|
23
24
|
|
|
24
25
|
export function getPrintOptions(
|
|
25
26
|
source: string,
|
|
@@ -36,6 +37,7 @@ export function getPrintOptions(
|
|
|
36
37
|
}
|
|
37
38
|
return state.sourceNodes.has(node as Node);
|
|
38
39
|
},
|
|
40
|
+
printCommentsOnUntouchedNodes: true,
|
|
39
41
|
getLeadingComments: (node) => (node as Node).leadingComments,
|
|
40
42
|
getTrailingComments: (node) => (node as Node).trailingComments,
|
|
41
43
|
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
@@ -186,6 +188,14 @@ export function getPrintOptions(
|
|
|
186
188
|
);
|
|
187
189
|
}
|
|
188
190
|
},
|
|
191
|
+
// @ts-expect-error This is a custom node type that don't have typing.
|
|
192
|
+
// @see `GTSAttributeNameHintStatement`
|
|
193
|
+
GTSAttributeNameHintStatement(node: GTSAttributeNameHintStatement, context: PrinterContext<CodeInformation>) {
|
|
194
|
+
context.writeNode(node.object as EspolarAST.Node);
|
|
195
|
+
context.write(".");
|
|
196
|
+
context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
|
|
197
|
+
context.write(";");
|
|
198
|
+
}
|
|
189
199
|
},
|
|
190
200
|
// Enable triggering signature completion
|
|
191
201
|
experimentalGetLeftParenSourceRange: (node) => {
|
|
@@ -38,6 +38,7 @@ type ReplacementPayload =
|
|
|
38
38
|
metaType: string;
|
|
39
39
|
lhs: string;
|
|
40
40
|
attrName: string;
|
|
41
|
+
hintOnly: boolean;
|
|
41
42
|
}
|
|
42
43
|
| {
|
|
43
44
|
type: "createBindingTyping";
|
|
@@ -179,7 +180,7 @@ export function applyReplacements(
|
|
|
179
180
|
? ${payload.attrName} /* have duplicate, disable this */
|
|
180
181
|
: never
|
|
181
182
|
);
|
|
182
|
-
let ${payload.lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${omittedKeys}>;
|
|
183
|
+
let ${payload.lhs}!: ${payload.hintOnly ? `{}` : `{ ${Meta}: ${payload.metaType} }`} & Omit<${payload.defType}, ${omittedKeys}>;
|
|
183
184
|
`;
|
|
184
185
|
} else if (payload.type === "createBindingTyping") {
|
|
185
186
|
const typingIdLhs = `${payload.typingId}_lhs`;
|
|
@@ -92,7 +92,25 @@ export interface TypingTranspileState extends TranspileState {
|
|
|
92
92
|
contentStartOffset: number;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Map whitespaces inside named attribute blocks to include a "NameHintStatement", which printed
|
|
97
|
+
* as following:
|
|
98
|
+
* ```ts
|
|
99
|
+
* __gts_attr_obj. ;
|
|
100
|
+
* // ^~~~~~ these whitespaces are mapped from source
|
|
101
|
+
* ```
|
|
102
|
+
* so that when user press Ctrl+Space inside whitespace characters, they can get hint of available
|
|
103
|
+
* attribute names inside this block.
|
|
104
|
+
*/
|
|
105
|
+
export interface GTSAttributeNameHintStatement {
|
|
106
|
+
type: "GTSAttributeNameHintStatement";
|
|
107
|
+
object: Identifier;
|
|
108
|
+
whiteSpaceStart: number;
|
|
109
|
+
whiteSpaceEnd: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
95
112
|
const EMPTY: EmptyStatement = { type: "EmptyStatement" };
|
|
113
|
+
const ATTR_HINT_ATTR_NAME = JSON.stringify("~attrNameHint");
|
|
96
114
|
|
|
97
115
|
const enterVMFromRoot = (state: TypingTranspileState) => {
|
|
98
116
|
let defTypeId: Identifier = {
|
|
@@ -174,7 +192,7 @@ const enterAttr = (
|
|
|
174
192
|
const defTypeId = state.vmDefTypeIdStack.at(-1);
|
|
175
193
|
const metaTypeId = state.metaTypeIdStack.at(-1);
|
|
176
194
|
if (!defTypeId || !metaTypeId) {
|
|
177
|
-
//
|
|
195
|
+
// FIXME error handling?
|
|
178
196
|
return { lhsId: { type: "Identifier", name: "__gts_invalid_attr_obj" } };
|
|
179
197
|
}
|
|
180
198
|
state.attrsOfCurrentVm.at(-1)!.push(attrName);
|
|
@@ -189,6 +207,7 @@ const enterAttr = (
|
|
|
189
207
|
metaType: metaTypeId.name,
|
|
190
208
|
lhs: lhsId.name,
|
|
191
209
|
attrName,
|
|
210
|
+
hintOnly: attrName === ATTR_HINT_ATTR_NAME,
|
|
192
211
|
}),
|
|
193
212
|
);
|
|
194
213
|
return { lhsId: lhsId };
|
|
@@ -238,6 +257,25 @@ const exitAttr = (state: TypingTranspileState, returningId: Identifier) => {
|
|
|
238
257
|
);
|
|
239
258
|
};
|
|
240
259
|
|
|
260
|
+
const insertHintStatement = (
|
|
261
|
+
state: TypingTranspileState,
|
|
262
|
+
whiteSpaceStart: number,
|
|
263
|
+
whiteSpaceEnd: number,
|
|
264
|
+
) => {
|
|
265
|
+
const { lhsId } = enterAttr(state, ATTR_HINT_ATTR_NAME);
|
|
266
|
+
state.typingPendingStatements.push({
|
|
267
|
+
type: "GTSAttributeNameHintStatement",
|
|
268
|
+
object: lhsId,
|
|
269
|
+
whiteSpaceStart,
|
|
270
|
+
whiteSpaceEnd,
|
|
271
|
+
} satisfies GTSAttributeNameHintStatement as any);
|
|
272
|
+
const returnValue: Identifier = {
|
|
273
|
+
type: "Identifier",
|
|
274
|
+
name: `__gts_attrRet_hint_${state.idCounter++}`,
|
|
275
|
+
};
|
|
276
|
+
exitAttr(state, returnValue);
|
|
277
|
+
};
|
|
278
|
+
|
|
241
279
|
export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
242
280
|
Program(node, { state, visit }) {
|
|
243
281
|
const body: Program["body"] = [];
|
|
@@ -471,8 +509,35 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
471
509
|
return EMPTY;
|
|
472
510
|
},
|
|
473
511
|
GTSNamedAttributeBlock(node, { state, visit }) {
|
|
474
|
-
|
|
475
|
-
|
|
512
|
+
// Insert hint statement around each attribute name:
|
|
513
|
+
// ```
|
|
514
|
+
// define foo {
|
|
515
|
+
// // (1) hidden hint
|
|
516
|
+
// bar 1; // (2a) hidden hint
|
|
517
|
+
// baz 2; // (2b) hidden hint
|
|
518
|
+
// }
|
|
519
|
+
// ```
|
|
520
|
+
const attributeListEnd =
|
|
521
|
+
node.directAction?.range?.[0] ?? node.range?.[1] ?? -1;
|
|
522
|
+
const attributeListStart =
|
|
523
|
+
node.attributes[0]?.range?.[0] ?? attributeListEnd;
|
|
524
|
+
// (1)
|
|
525
|
+
if (node.range && attributeListStart > node.range[0] + 1) {
|
|
526
|
+
insertHintStatement(state, node.range[0] + 1, attributeListStart - 1);
|
|
527
|
+
}
|
|
528
|
+
for (let i = 0; i < node.attributes.length; i++) {
|
|
529
|
+
const attribute = node.attributes[i];
|
|
530
|
+
visit(attribute);
|
|
531
|
+
let nextTokenStart: number;
|
|
532
|
+
if (i < node.attributes.length - 1) {
|
|
533
|
+
nextTokenStart = node.attributes[i + 1].range?.[0] ?? -1;
|
|
534
|
+
} else {
|
|
535
|
+
nextTokenStart = attributeListEnd;
|
|
536
|
+
}
|
|
537
|
+
// (2)
|
|
538
|
+
if (attribute.range && nextTokenStart > attribute.range[1]) {
|
|
539
|
+
insertHintStatement(state, attribute.range[1], nextTokenStart - 1);
|
|
540
|
+
}
|
|
476
541
|
}
|
|
477
542
|
if (node.directAction) {
|
|
478
543
|
const stubStatement: ExpressionStatement = {
|
|
@@ -529,6 +594,7 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
529
594
|
},
|
|
530
595
|
],
|
|
531
596
|
});
|
|
597
|
+
exitAttr(state, returnValue);
|
|
532
598
|
}
|
|
533
599
|
return EMPTY;
|
|
534
600
|
},
|