@gi-tcg/gts-transpiler 0.4.4 → 0.4.6
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,16 @@ 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
|
+
`${state.idCounter++}`;
|
|
1453
|
+
};
|
|
1442
1454
|
const gtsToTypingsWalker = {
|
|
1443
1455
|
Program(node, { state, visit }) {
|
|
1444
1456
|
const body = [];
|
|
@@ -1638,7 +1650,17 @@ const gtsToTypingsWalker = {
|
|
|
1638
1650
|
return EMPTY;
|
|
1639
1651
|
},
|
|
1640
1652
|
GTSNamedAttributeBlock(node, { state, visit }) {
|
|
1641
|
-
|
|
1653
|
+
const attributeListEnd = node.directAction?.range?.[0] ?? node.range?.[1] ?? -1;
|
|
1654
|
+
const attributeListStart = node.attributes[0]?.range?.[0] ?? attributeListEnd;
|
|
1655
|
+
if (node.range && attributeListStart > node.range[0] + 1) insertHintStatement(state, node.range[0] + 1, attributeListStart - 1);
|
|
1656
|
+
for (let i = 0; i < node.attributes.length; i++) {
|
|
1657
|
+
const attribute = node.attributes[i];
|
|
1658
|
+
visit(attribute);
|
|
1659
|
+
let nextTokenStart;
|
|
1660
|
+
if (i < node.attributes.length - 1) nextTokenStart = node.attributes[i + 1].range?.[0] ?? -1;
|
|
1661
|
+
else nextTokenStart = attributeListEnd;
|
|
1662
|
+
if (attribute.range && nextTokenStart > attribute.range[1]) insertHintStatement(state, attribute.range[1], nextTokenStart - 1);
|
|
1663
|
+
}
|
|
1642
1664
|
if (node.directAction) {
|
|
1643
1665
|
const stubStatement = {
|
|
1644
1666
|
type: "ExpressionStatement",
|
|
@@ -1735,6 +1757,7 @@ function getPrintOptions(source, state) {
|
|
|
1735
1757
|
if (state.attributeNameNodes.has(node)) return false;
|
|
1736
1758
|
return state.sourceNodes.has(node);
|
|
1737
1759
|
},
|
|
1760
|
+
printCommentsOnUntouchedNodes: true,
|
|
1738
1761
|
getLeadingComments: (node) => node.leadingComments,
|
|
1739
1762
|
getTrailingComments: (node) => node.trailingComments,
|
|
1740
1763
|
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
@@ -1804,6 +1827,12 @@ function getPrintOptions(source, state) {
|
|
|
1804
1827
|
end: state.contentStartOffset + 1
|
|
1805
1828
|
}, context.generatedOffset, context.generatedOffset + 1, DEFAULT_VOLAR_MAPPING_DATA);
|
|
1806
1829
|
}
|
|
1830
|
+
},
|
|
1831
|
+
GTSAttributeNameHintStatement(node, context) {
|
|
1832
|
+
context.writeNode(node.object);
|
|
1833
|
+
context.write(".");
|
|
1834
|
+
context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
|
|
1835
|
+
context.write(";");
|
|
1807
1836
|
}
|
|
1808
1837
|
},
|
|
1809
1838
|
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.6",
|
|
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
|
+
// do NOT exitAttr (rewrite meta) since hint is a incomplete structure
|
|
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,8 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
529
594
|
},
|
|
530
595
|
],
|
|
531
596
|
});
|
|
597
|
+
// rewriting meta is unnecessary since direct action must be the last attribute
|
|
598
|
+
// exitAttr(state, returnValue);
|
|
532
599
|
}
|
|
533
600
|
return EMPTY;
|
|
534
601
|
},
|