@gi-tcg/gts-transpiler 0.4.6 → 0.6.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/dist/index.d.ts +0 -2
- package/dist/index.js +37 -135
- package/package.json +2 -2
- package/src/config.ts +0 -2
- package/src/keywords.ts +0 -1
- package/src/parse/gts_plugin.ts +0 -34
- package/src/transform/gts.ts +2 -89
- package/src/transform/volar/printer.ts +14 -11
- package/src/transform/volar/replacements.ts +11 -1
- package/src/transform/volar/walker.ts +31 -9
- package/src/types.ts +0 -6
- package/src/transform/constants.ts +0 -2
package/dist/index.d.ts
CHANGED
|
@@ -517,8 +517,6 @@ declare function parseLoose(input: string, options?: ParseLooseOptions): Program
|
|
|
517
517
|
interface TranspileOption {
|
|
518
518
|
runtimeImportSource?: string;
|
|
519
519
|
providerImportSource?: string;
|
|
520
|
-
shortcutFunctionPreludes?: string[];
|
|
521
|
-
queryBindings?: string[];
|
|
522
520
|
}
|
|
523
521
|
//#endregion
|
|
524
522
|
//#region ../../node_modules/@volar/source-map/lib/sourceMap.d.ts
|
package/dist/index.js
CHANGED
|
@@ -61,8 +61,7 @@ const specialIdentifiers = [
|
|
|
61
61
|
"of",
|
|
62
62
|
"set",
|
|
63
63
|
"type",
|
|
64
|
-
"define"
|
|
65
|
-
"query"
|
|
64
|
+
"define"
|
|
66
65
|
];
|
|
67
66
|
function loosePlugin() {
|
|
68
67
|
return function loosePluginTransformer(parser) {
|
|
@@ -238,21 +237,6 @@ function gtsPlugin(options = {}) {
|
|
|
238
237
|
}
|
|
239
238
|
return super.parseExprAtom(refDestructuringErrors, forInit, forNew);
|
|
240
239
|
}
|
|
241
|
-
parseMaybeUnary(refDestructuringErrors, sawUnary, incDec, forInit) {
|
|
242
|
-
if (this.isShortcutContext && this.isContextual("query")) {
|
|
243
|
-
const expr = this.gts_parseQueryExpression();
|
|
244
|
-
if (!incDec && this.eat(tokTypes.starstar)) this.unexpected(this.lastTokStart);
|
|
245
|
-
return expr;
|
|
246
|
-
}
|
|
247
|
-
return super.parseMaybeUnary(refDestructuringErrors, sawUnary, incDec, forInit);
|
|
248
|
-
}
|
|
249
|
-
gts_parseQueryExpression(forInit) {
|
|
250
|
-
const node = this.startNode();
|
|
251
|
-
this.next();
|
|
252
|
-
if (this.eat(tokTypes.star)) node.star = true;
|
|
253
|
-
node.argument = this.parseMaybeUnary(null, true, false, forInit);
|
|
254
|
-
return this.finishNode(node, "GTSQueryExpression");
|
|
255
|
-
}
|
|
256
240
|
};
|
|
257
241
|
};
|
|
258
242
|
}
|
|
@@ -712,14 +696,6 @@ const eraseTs = (ast) => {
|
|
|
712
696
|
return walk(ast, null, eraseTsVisitor);
|
|
713
697
|
};
|
|
714
698
|
//#endregion
|
|
715
|
-
//#region src/transform/constants.ts
|
|
716
|
-
const DEFAULT_SHORTCUT_FUNCTION_PRELUDES = ["$"];
|
|
717
|
-
const DEFAULT_QUERY_BINDINGS = [
|
|
718
|
-
"my",
|
|
719
|
-
"opp",
|
|
720
|
-
"macros"
|
|
721
|
-
];
|
|
722
|
-
//#endregion
|
|
723
699
|
//#region src/transform/gts.ts
|
|
724
700
|
const commonGtsVisitor = {
|
|
725
701
|
GTSDirectFunction(node, { visit, state }) {
|
|
@@ -757,7 +733,7 @@ const commonGtsVisitor = {
|
|
|
757
733
|
type: "ArrayExpression",
|
|
758
734
|
elements: [{
|
|
759
735
|
type: "ArrowFunctionExpression",
|
|
760
|
-
params: state.
|
|
736
|
+
params: [state.fnArgId],
|
|
761
737
|
body: {
|
|
762
738
|
type: "BlockStatement",
|
|
763
739
|
body: node.body.map((stmt) => visit(stmt))
|
|
@@ -791,7 +767,7 @@ const commonGtsVisitor = {
|
|
|
791
767
|
GTSShortcutFunctionExpression(node, { visit, state }) {
|
|
792
768
|
return {
|
|
793
769
|
type: "ArrowFunctionExpression",
|
|
794
|
-
params: state.
|
|
770
|
+
params: [state.fnArgId],
|
|
795
771
|
body: visit(node.body),
|
|
796
772
|
expression: node.expression,
|
|
797
773
|
loc: node.loc,
|
|
@@ -808,28 +784,6 @@ const commonGtsVisitor = {
|
|
|
808
784
|
loc: node.loc,
|
|
809
785
|
range: node.range
|
|
810
786
|
};
|
|
811
|
-
},
|
|
812
|
-
GTSQueryExpression(node, { state, visit }) {
|
|
813
|
-
return {
|
|
814
|
-
...node,
|
|
815
|
-
type: "CallExpression",
|
|
816
|
-
optional: false,
|
|
817
|
-
callee: {
|
|
818
|
-
type: "MemberExpression",
|
|
819
|
-
object: state.fnArgId,
|
|
820
|
-
property: node.star ? state.QueryAllLit : state.QueryLit,
|
|
821
|
-
computed: true,
|
|
822
|
-
optional: false
|
|
823
|
-
},
|
|
824
|
-
arguments: [{
|
|
825
|
-
type: "ArrowFunctionExpression",
|
|
826
|
-
body: visit(node.argument),
|
|
827
|
-
params: state.queryParameters,
|
|
828
|
-
expression: true,
|
|
829
|
-
loc: node.argument.loc,
|
|
830
|
-
range: node.argument.range
|
|
831
|
-
}]
|
|
832
|
-
};
|
|
833
787
|
}
|
|
834
788
|
};
|
|
835
789
|
const gtsVisitor = {
|
|
@@ -1099,16 +1053,6 @@ const gtsVisitor = {
|
|
|
1099
1053
|
...commonGtsVisitor
|
|
1100
1054
|
};
|
|
1101
1055
|
const initialTranspileState = (option = {}) => {
|
|
1102
|
-
const shortcutFunctionPreludes = option.shortcutFunctionPreludes ?? DEFAULT_SHORTCUT_FUNCTION_PRELUDES;
|
|
1103
|
-
const queryBindings = option.queryBindings ?? DEFAULT_QUERY_BINDINGS;
|
|
1104
|
-
const fnArgId = {
|
|
1105
|
-
type: "Identifier",
|
|
1106
|
-
name: "__gts_fnArg"
|
|
1107
|
-
};
|
|
1108
|
-
const PreludeLit = {
|
|
1109
|
-
type: "Literal",
|
|
1110
|
-
value: "~prelude"
|
|
1111
|
-
};
|
|
1112
1056
|
return {
|
|
1113
1057
|
createDefineFnId: {
|
|
1114
1058
|
type: "Identifier",
|
|
@@ -1122,66 +1066,14 @@ const initialTranspileState = (option = {}) => {
|
|
|
1122
1066
|
type: "Literal",
|
|
1123
1067
|
value: "~action"
|
|
1124
1068
|
},
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
left: {
|
|
1130
|
-
type: "ObjectPattern",
|
|
1131
|
-
properties: shortcutFunctionPreludes.map((name) => ({
|
|
1132
|
-
type: "Property",
|
|
1133
|
-
computed: false,
|
|
1134
|
-
key: {
|
|
1135
|
-
type: "Identifier",
|
|
1136
|
-
name
|
|
1137
|
-
},
|
|
1138
|
-
value: {
|
|
1139
|
-
type: "Identifier",
|
|
1140
|
-
name
|
|
1141
|
-
},
|
|
1142
|
-
kind: "init",
|
|
1143
|
-
method: false,
|
|
1144
|
-
shorthand: true
|
|
1145
|
-
}))
|
|
1146
|
-
},
|
|
1147
|
-
right: {
|
|
1148
|
-
type: "MemberExpression",
|
|
1149
|
-
object: fnArgId,
|
|
1150
|
-
property: PreludeLit,
|
|
1151
|
-
computed: true,
|
|
1152
|
-
optional: false
|
|
1153
|
-
}
|
|
1154
|
-
}],
|
|
1069
|
+
fnArgId: {
|
|
1070
|
+
type: "Identifier",
|
|
1071
|
+
name: "__gts_fnArg"
|
|
1072
|
+
},
|
|
1155
1073
|
rootVmId: {
|
|
1156
1074
|
type: "Identifier",
|
|
1157
1075
|
name: "__gts_rootVm"
|
|
1158
1076
|
},
|
|
1159
|
-
queryParameters: [{
|
|
1160
|
-
type: "ObjectPattern",
|
|
1161
|
-
properties: queryBindings.map((name) => ({
|
|
1162
|
-
type: "Property",
|
|
1163
|
-
computed: false,
|
|
1164
|
-
key: {
|
|
1165
|
-
type: "Identifier",
|
|
1166
|
-
name
|
|
1167
|
-
},
|
|
1168
|
-
value: {
|
|
1169
|
-
type: "Identifier",
|
|
1170
|
-
name
|
|
1171
|
-
},
|
|
1172
|
-
kind: "init",
|
|
1173
|
-
method: false,
|
|
1174
|
-
shorthand: true
|
|
1175
|
-
}))
|
|
1176
|
-
}],
|
|
1177
|
-
QueryLit: {
|
|
1178
|
-
type: "Literal",
|
|
1179
|
-
value: "~query"
|
|
1180
|
-
},
|
|
1181
|
-
QueryAllLit: {
|
|
1182
|
-
type: "Literal",
|
|
1183
|
-
value: "~queryAll"
|
|
1184
|
-
},
|
|
1185
1077
|
runtimeImportSource: option.runtimeImportSource ?? "@gi-tcg/gts-runtime",
|
|
1186
1078
|
providerImportSource: option.providerImportSource ?? "@gi-tcg/core/gts",
|
|
1187
1079
|
externalizedBindings: [],
|
|
@@ -1306,11 +1198,20 @@ function applyReplacements(state, code, mappings) {
|
|
|
1306
1198
|
let ${payload.typingId} = ${typingIdLhs}.as();
|
|
1307
1199
|
type ${payload.typingId} = typeof ${payload.typingId};
|
|
1308
1200
|
`;
|
|
1309
|
-
} else if (payload.type === "exitAttr")
|
|
1201
|
+
} else if (payload.type === "exitAttr") {
|
|
1202
|
+
const rewrittenMeta = `${payload.oldMetaType}_rewritten`;
|
|
1203
|
+
const mergeFn = `${payload.oldMetaType}_mergeFn`;
|
|
1204
|
+
const mergeFnRet = `${payload.oldMetaType}_mergeFnRet`;
|
|
1205
|
+
replacement = dedent`
|
|
1310
1206
|
type ${payload.returnType} = typeof ${payload.returnType};
|
|
1311
|
-
type ${
|
|
1207
|
+
type ${rewrittenMeta} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType};
|
|
1208
|
+
let ${mergeFn}!: ${payload.defType} extends {
|
|
1209
|
+
[${payload.attrName}]: { mergeMeta: infer M }
|
|
1210
|
+
} ? M : null;
|
|
1211
|
+
let ${mergeFnRet} = ${mergeFn}?.(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
|
|
1212
|
+
type ${payload.newMetaType} = [typeof ${mergeFn}] extends [null] ? ${rewrittenMeta} : typeof ${mergeFnRet};
|
|
1312
1213
|
`;
|
|
1313
|
-
else replacement = "";
|
|
1214
|
+
} else replacement = "";
|
|
1314
1215
|
matchInfos.push({
|
|
1315
1216
|
sourceEnd: offset + match.length,
|
|
1316
1217
|
lengthOffset: replacement.length - match.length
|
|
@@ -1390,6 +1291,7 @@ const exitVM = (state, errorRange) => {
|
|
|
1390
1291
|
collectedAttrs: collectedAttrNames,
|
|
1391
1292
|
errorRange
|
|
1392
1293
|
}));
|
|
1294
|
+
return { finalMetaId };
|
|
1393
1295
|
};
|
|
1394
1296
|
const enterAttr = (state, attrName) => {
|
|
1395
1297
|
const defTypeId = state.vmDefTypeIdStack.at(-1);
|
|
@@ -1425,7 +1327,7 @@ const genBindingTyping = (state, info) => {
|
|
|
1425
1327
|
typingId: info.typingId.name
|
|
1426
1328
|
}));
|
|
1427
1329
|
};
|
|
1428
|
-
const exitAttr = (state, returningId) => {
|
|
1330
|
+
const exitAttr = (state, attrName, innerVMFinalMetaId, returningId) => {
|
|
1429
1331
|
const currentDefId = state.vmDefTypeIdStack.at(-1);
|
|
1430
1332
|
if (!currentDefId) return;
|
|
1431
1333
|
const newMetaTypeId = {
|
|
@@ -1436,6 +1338,8 @@ const exitAttr = (state, returningId) => {
|
|
|
1436
1338
|
state.typingPendingStatements.push(createReplacementHolder(state, {
|
|
1437
1339
|
type: "exitAttr",
|
|
1438
1340
|
defType: currentDefId.name,
|
|
1341
|
+
attrName,
|
|
1342
|
+
innerMetaType: innerVMFinalMetaId.name,
|
|
1439
1343
|
oldMetaType: oldMetaTypeId.name,
|
|
1440
1344
|
newMetaType: newMetaTypeId.name,
|
|
1441
1345
|
returnType: returningId.name
|
|
@@ -1616,10 +1520,11 @@ const gtsToTypingsWalker = {
|
|
|
1616
1520
|
}]
|
|
1617
1521
|
});
|
|
1618
1522
|
enterVMFromAttr(state, returnValue);
|
|
1523
|
+
let exitVMResult;
|
|
1619
1524
|
if (body.namedAttributes) {
|
|
1620
1525
|
visit(body.namedAttributes);
|
|
1621
|
-
exitVM(state, body.namedAttributes.range);
|
|
1622
|
-
} else exitVM(state, name.range);
|
|
1526
|
+
exitVMResult = exitVM(state, body.namedAttributes.range);
|
|
1527
|
+
} else exitVMResult = exitVM(state, name.range);
|
|
1623
1528
|
if (bindingName) {
|
|
1624
1529
|
const export_ = node.bindingAccessModifier !== "private";
|
|
1625
1530
|
const typingId = {
|
|
@@ -1646,7 +1551,7 @@ const gtsToTypingsWalker = {
|
|
|
1646
1551
|
leadingComments: state.defineLeadingComments
|
|
1647
1552
|
});
|
|
1648
1553
|
}
|
|
1649
|
-
exitAttr(state, returnValue);
|
|
1554
|
+
exitAttr(state, attrName, exitVMResult.finalMetaId, returnValue);
|
|
1650
1555
|
return EMPTY;
|
|
1651
1556
|
},
|
|
1652
1557
|
GTSNamedAttributeBlock(node, { state, visit }) {
|
|
@@ -1686,7 +1591,7 @@ const gtsToTypingsWalker = {
|
|
|
1686
1591
|
}
|
|
1687
1592
|
const fn = {
|
|
1688
1593
|
type: "ArrowFunctionExpression",
|
|
1689
|
-
params: state.
|
|
1594
|
+
params: [state.fnArgId],
|
|
1690
1595
|
body: {
|
|
1691
1596
|
type: "BlockStatement",
|
|
1692
1597
|
body: node.directAction.body.map((stmt) => visit(stmt))
|
|
@@ -1761,6 +1666,14 @@ function getPrintOptions(source, state) {
|
|
|
1761
1666
|
getLeadingComments: (node) => node.leadingComments,
|
|
1762
1667
|
getTrailingComments: (node) => node.trailingComments,
|
|
1763
1668
|
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
1669
|
+
beforeWriteNode: ({ range, isUntouched, context }) => {
|
|
1670
|
+
if (isUntouched || !range) return;
|
|
1671
|
+
context.writeMapped("", range.start, range.start, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1672
|
+
},
|
|
1673
|
+
afterWriteNode: ({ range, isUntouched, context }) => {
|
|
1674
|
+
if (isUntouched || !range) return;
|
|
1675
|
+
context.writeMapped("", range.end, range.end, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1676
|
+
},
|
|
1764
1677
|
printers: {
|
|
1765
1678
|
Identifier(node, context) {
|
|
1766
1679
|
const identifier = node;
|
|
@@ -1780,11 +1693,6 @@ function getPrintOptions(source, state) {
|
|
|
1780
1693
|
context.write("\"");
|
|
1781
1694
|
context.writeMapped(text.slice(1, -1), node.range[0], node.range[1], LITERAL_FROM_ID_MAPPING_DATA);
|
|
1782
1695
|
context.write("\"");
|
|
1783
|
-
const generatedEnd = context.generatedOffset;
|
|
1784
|
-
context.createExtraMapping({
|
|
1785
|
-
start: node.range[0],
|
|
1786
|
-
end: node.range[1]
|
|
1787
|
-
}, generatedStart, generatedEnd, VERIFICATION_ONLY_MAPPING_DATA);
|
|
1788
1696
|
} else if (state.attributeNameNodes.has(node) && node.range) context.writeMapped(node.raw ?? JSON.stringify(node.value), node.range[0], node.range[1], ATTRIBUTE_NAME_MAPPING_DATA);
|
|
1789
1697
|
else if (directActionStubRange = state.directActionStubRange.get(node)) context.writeMapped(node.raw ?? JSON.stringify(node.value), directActionStubRange.start, directActionStubRange.start + 1, DIRECT_ACTION_STUB_MAPPING_DATA);
|
|
1790
1698
|
else defaultPrinters.Literal(node, context);
|
|
@@ -1998,13 +1906,7 @@ function transform(ast, option = {}, sourceInfo = {}) {
|
|
|
1998
1906
|
//#region src/config.ts
|
|
1999
1907
|
const DEFAULT_GTS_CONFIG = {
|
|
2000
1908
|
runtimeImportSource: "@gi-tcg/gts-runtime",
|
|
2001
|
-
providerImportSource: "@gi-tcg/core/gts"
|
|
2002
|
-
shortcutFunctionPreludes: ["$"],
|
|
2003
|
-
queryBindings: [
|
|
2004
|
-
"my",
|
|
2005
|
-
"opp",
|
|
2006
|
-
"macros"
|
|
2007
|
-
]
|
|
1909
|
+
providerImportSource: "@gi-tcg/core/gts"
|
|
2008
1910
|
};
|
|
2009
1911
|
function* resolveGtsConfigImpl(filePath, inlineConfig = {}, options) {
|
|
2010
1912
|
const pathModule = options.pathModule || browserPath;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gi-tcg/gts-transpiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
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.3",
|
|
26
26
|
"esrap": "2.2.1",
|
|
27
27
|
"magic-string": "^0.30.21",
|
|
28
28
|
"path-browserify-esm": "^1.0.6",
|
package/src/config.ts
CHANGED
|
@@ -33,8 +33,6 @@ export interface ResolveGtsConfigAsyncOptions extends ResolveGtsConfigBaseOption
|
|
|
33
33
|
const DEFAULT_GTS_CONFIG: Required<GtsConfig> = {
|
|
34
34
|
runtimeImportSource: "@gi-tcg/gts-runtime",
|
|
35
35
|
providerImportSource: "@gi-tcg/core/gts",
|
|
36
|
-
shortcutFunctionPreludes: ["$"],
|
|
37
|
-
queryBindings: ["my", "opp", "macros"],
|
|
38
36
|
};
|
|
39
37
|
|
|
40
38
|
function* resolveGtsConfigImpl(
|
package/src/keywords.ts
CHANGED
package/src/parse/gts_plugin.ts
CHANGED
|
@@ -65,8 +65,6 @@ PrimaryExpression:
|
|
|
65
65
|
ShortcutArgumentExpression:
|
|
66
66
|
":" Identifier
|
|
67
67
|
|
|
68
|
-
UnaryExpression:
|
|
69
|
-
+ query UnaryExpression
|
|
70
68
|
*/
|
|
71
69
|
|
|
72
70
|
export interface GtsPluginOption {
|
|
@@ -318,38 +316,6 @@ export function gtsPlugin(options: GtsPluginOption = {}) {
|
|
|
318
316
|
return super.parseExprAtom(refDestructuringErrors, forInit, forNew);
|
|
319
317
|
}
|
|
320
318
|
|
|
321
|
-
override parseMaybeUnary(
|
|
322
|
-
refDestructuringErrors?: Parse.DestructuringErrors | null,
|
|
323
|
-
sawUnary?: boolean,
|
|
324
|
-
incDec?: boolean,
|
|
325
|
-
forInit?: boolean | "await",
|
|
326
|
-
): AST.Expression {
|
|
327
|
-
if (this.isShortcutContext && this.isContextual("query")) {
|
|
328
|
-
const expr = this.gts_parseQueryExpression();
|
|
329
|
-
if (!incDec && this.eat(tokTypes.starstar)) {
|
|
330
|
-
this.unexpected(this.lastTokStart);
|
|
331
|
-
}
|
|
332
|
-
return expr;
|
|
333
|
-
}
|
|
334
|
-
return super.parseMaybeUnary(
|
|
335
|
-
refDestructuringErrors,
|
|
336
|
-
sawUnary,
|
|
337
|
-
incDec,
|
|
338
|
-
forInit,
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
gts_parseQueryExpression(
|
|
343
|
-
forInit?: boolean | "await",
|
|
344
|
-
): AST.GTSQueryExpression {
|
|
345
|
-
const node = this.startNode() as AST.GTSQueryExpression;
|
|
346
|
-
this.next(); // consume 'query'
|
|
347
|
-
if (this.eat(tokTypes.star)) {
|
|
348
|
-
node.star = true;
|
|
349
|
-
}
|
|
350
|
-
node.argument = this.parseMaybeUnary(null, true, false, forInit);
|
|
351
|
-
return this.finishNode(node, "GTSQueryExpression");
|
|
352
|
-
}
|
|
353
319
|
};
|
|
354
320
|
};
|
|
355
321
|
}
|
package/src/transform/gts.ts
CHANGED
|
@@ -16,11 +16,6 @@ import type {
|
|
|
16
16
|
} from "estree";
|
|
17
17
|
import { walk, type Visitors } from "zimmerframe";
|
|
18
18
|
import { GtsTranspilerError } from "../error.ts";
|
|
19
|
-
import {
|
|
20
|
-
DEFAULT_QUERY_BINDINGS,
|
|
21
|
-
DEFAULT_SHORTCUT_FUNCTION_PRELUDES,
|
|
22
|
-
} from "./constants.ts";
|
|
23
|
-
|
|
24
19
|
export interface ExternalizedBinding {
|
|
25
20
|
bindingName: Identifier;
|
|
26
21
|
export: boolean;
|
|
@@ -30,13 +25,8 @@ export interface TranspileState {
|
|
|
30
25
|
readonly createDefineFnId: Identifier;
|
|
31
26
|
readonly createBindingFnId: Identifier;
|
|
32
27
|
readonly ActionLit: Literal;
|
|
33
|
-
readonly PreludeLit: Literal;
|
|
34
28
|
readonly fnArgId: Identifier;
|
|
35
|
-
readonly shortcutFunctionParameters: Pattern[];
|
|
36
29
|
readonly rootVmId: Identifier;
|
|
37
|
-
readonly queryParameters: Pattern[];
|
|
38
|
-
readonly QueryLit: Literal;
|
|
39
|
-
readonly QueryAllLit: Literal;
|
|
40
30
|
|
|
41
31
|
readonly runtimeImportSource: string;
|
|
42
32
|
readonly providerImportSource: string;
|
|
@@ -80,7 +70,7 @@ export const commonGtsVisitor: Visitors<Node, TranspileState> = {
|
|
|
80
70
|
elements: [
|
|
81
71
|
{
|
|
82
72
|
type: "ArrowFunctionExpression",
|
|
83
|
-
params: state.
|
|
73
|
+
params: [state.fnArgId],
|
|
84
74
|
body: {
|
|
85
75
|
type: "BlockStatement",
|
|
86
76
|
body: node.body.map((stmt) => visit(stmt) as Statement),
|
|
@@ -115,7 +105,7 @@ export const commonGtsVisitor: Visitors<Node, TranspileState> = {
|
|
|
115
105
|
): ArrowFunctionExpression {
|
|
116
106
|
return {
|
|
117
107
|
type: "ArrowFunctionExpression",
|
|
118
|
-
params: state.
|
|
108
|
+
params: [state.fnArgId],
|
|
119
109
|
body: visit(node.body) as Expression | BlockStatement,
|
|
120
110
|
expression: node.expression,
|
|
121
111
|
loc: node.loc,
|
|
@@ -133,30 +123,6 @@ export const commonGtsVisitor: Visitors<Node, TranspileState> = {
|
|
|
133
123
|
range: node.range,
|
|
134
124
|
};
|
|
135
125
|
},
|
|
136
|
-
GTSQueryExpression(node, { state, visit }) {
|
|
137
|
-
return {
|
|
138
|
-
...node,
|
|
139
|
-
type: "CallExpression",
|
|
140
|
-
optional: false,
|
|
141
|
-
callee: {
|
|
142
|
-
type: "MemberExpression",
|
|
143
|
-
object: state.fnArgId,
|
|
144
|
-
property: node.star ? state.QueryAllLit : state.QueryLit,
|
|
145
|
-
computed: true,
|
|
146
|
-
optional: false,
|
|
147
|
-
},
|
|
148
|
-
arguments: [
|
|
149
|
-
{
|
|
150
|
-
type: "ArrowFunctionExpression",
|
|
151
|
-
body: visit(node.argument) as Expression,
|
|
152
|
-
params: state.queryParameters,
|
|
153
|
-
expression: true,
|
|
154
|
-
loc: node.argument.loc,
|
|
155
|
-
range: node.argument.range,
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
};
|
|
159
|
-
},
|
|
160
126
|
};
|
|
161
127
|
|
|
162
128
|
const gtsVisitor: Visitors<Node, TranspileState> = {
|
|
@@ -446,71 +412,18 @@ const gtsVisitor: Visitors<Node, TranspileState> = {
|
|
|
446
412
|
export interface TranspileOption {
|
|
447
413
|
runtimeImportSource?: string;
|
|
448
414
|
providerImportSource?: string;
|
|
449
|
-
shortcutFunctionPreludes?: string[];
|
|
450
|
-
queryBindings?: string[];
|
|
451
415
|
}
|
|
452
416
|
|
|
453
417
|
export const initialTranspileState = (
|
|
454
418
|
option: TranspileOption = {}
|
|
455
419
|
): TranspileState => {
|
|
456
|
-
const shortcutFunctionPreludes =
|
|
457
|
-
option.shortcutFunctionPreludes ?? DEFAULT_SHORTCUT_FUNCTION_PRELUDES;
|
|
458
|
-
const queryBindings = option.queryBindings ?? DEFAULT_QUERY_BINDINGS;
|
|
459
420
|
const fnArgId: Identifier = { type: "Identifier", name: "__gts_fnArg" };
|
|
460
|
-
const PreludeLit: Literal = {
|
|
461
|
-
type: "Literal",
|
|
462
|
-
value: "~prelude",
|
|
463
|
-
};
|
|
464
|
-
const shortcutFunctionParameters: Pattern[] = [
|
|
465
|
-
fnArgId,
|
|
466
|
-
{
|
|
467
|
-
type: "AssignmentPattern",
|
|
468
|
-
left: {
|
|
469
|
-
type: "ObjectPattern",
|
|
470
|
-
properties: shortcutFunctionPreludes.map((name) => ({
|
|
471
|
-
type: "Property",
|
|
472
|
-
computed: false,
|
|
473
|
-
key: { type: "Identifier", name },
|
|
474
|
-
value: { type: "Identifier", name },
|
|
475
|
-
kind: "init",
|
|
476
|
-
method: false,
|
|
477
|
-
shorthand: true,
|
|
478
|
-
})),
|
|
479
|
-
},
|
|
480
|
-
right: {
|
|
481
|
-
type: "MemberExpression",
|
|
482
|
-
object: fnArgId,
|
|
483
|
-
property: PreludeLit,
|
|
484
|
-
computed: true,
|
|
485
|
-
optional: false,
|
|
486
|
-
},
|
|
487
|
-
},
|
|
488
|
-
];
|
|
489
|
-
const queryParameters: Pattern[] = [
|
|
490
|
-
{
|
|
491
|
-
type: "ObjectPattern",
|
|
492
|
-
properties: queryBindings.map((name) => ({
|
|
493
|
-
type: "Property",
|
|
494
|
-
computed: false,
|
|
495
|
-
key: { type: "Identifier", name },
|
|
496
|
-
value: { type: "Identifier", name },
|
|
497
|
-
kind: "init",
|
|
498
|
-
method: false,
|
|
499
|
-
shorthand: true,
|
|
500
|
-
})),
|
|
501
|
-
},
|
|
502
|
-
];
|
|
503
421
|
return {
|
|
504
422
|
createDefineFnId: { type: "Identifier", name: "__gts_createDefine" },
|
|
505
423
|
createBindingFnId: { type: "Identifier", name: "__gts_createBinding" },
|
|
506
424
|
ActionLit: { type: "Literal", value: "~action" },
|
|
507
|
-
PreludeLit,
|
|
508
425
|
fnArgId,
|
|
509
|
-
shortcutFunctionParameters,
|
|
510
426
|
rootVmId: { type: "Identifier", name: "__gts_rootVm" },
|
|
511
|
-
queryParameters,
|
|
512
|
-
QueryLit: { type: "Literal", value: "~query" },
|
|
513
|
-
QueryAllLit: { type: "Literal", value: "~queryAll" },
|
|
514
427
|
|
|
515
428
|
runtimeImportSource: option.runtimeImportSource ?? "@gi-tcg/gts-runtime",
|
|
516
429
|
providerImportSource: option.providerImportSource ?? "@gi-tcg/core/gts",
|
|
@@ -41,6 +41,20 @@ export function getPrintOptions(
|
|
|
41
41
|
getLeadingComments: (node) => (node as Node).leadingComments,
|
|
42
42
|
getTrailingComments: (node) => (node as Node).trailingComments,
|
|
43
43
|
getMappingData: () => DEFAULT_VOLAR_MAPPING_DATA,
|
|
44
|
+
// Add a 0-length mapping before and after each touched node with verification only,
|
|
45
|
+
// so that error squiggles start/ends at those positions can be reflected.
|
|
46
|
+
beforeWriteNode: ({ range, isUntouched, context }) => {
|
|
47
|
+
if (isUntouched || !range) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
context.writeMapped("", range.start, range.start, VERIFICATION_ONLY_MAPPING_DATA);
|
|
51
|
+
},
|
|
52
|
+
afterWriteNode: ({ range, isUntouched, context }) => {
|
|
53
|
+
if (isUntouched || !range) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
context.writeMapped("", range.end, range.end, VERIFICATION_ONLY_MAPPING_DATA);
|
|
57
|
+
},
|
|
44
58
|
printers: {
|
|
45
59
|
// 1) Make the print of dummy identifier print nothing.
|
|
46
60
|
// Exception: if GTS attribute list's last argument is dummy, e.g.
|
|
@@ -94,17 +108,6 @@ export function getPrintOptions(
|
|
|
94
108
|
LITERAL_FROM_ID_MAPPING_DATA,
|
|
95
109
|
);
|
|
96
110
|
context.write('"');
|
|
97
|
-
const generatedEnd = context.generatedOffset;
|
|
98
|
-
// Map error squiggle at quotation mark to the inner content
|
|
99
|
-
context.createExtraMapping(
|
|
100
|
-
{
|
|
101
|
-
start: node.range[0],
|
|
102
|
-
end: node.range[1],
|
|
103
|
-
},
|
|
104
|
-
generatedStart,
|
|
105
|
-
generatedEnd,
|
|
106
|
-
VERIFICATION_ONLY_MAPPING_DATA,
|
|
107
|
-
)
|
|
108
111
|
} else if (state.attributeNameNodes.has(node) && node.range) {
|
|
109
112
|
context.writeMapped(
|
|
110
113
|
node.raw ?? JSON.stringify((node as EspolarAST.Literal).value),
|
|
@@ -51,6 +51,8 @@ type ReplacementPayload =
|
|
|
51
51
|
type: "exitAttr";
|
|
52
52
|
returnType: string;
|
|
53
53
|
defType: string;
|
|
54
|
+
attrName: string;
|
|
55
|
+
innerMetaType: string;
|
|
54
56
|
oldMetaType: string;
|
|
55
57
|
newMetaType: string;
|
|
56
58
|
};
|
|
@@ -194,9 +196,17 @@ export function applyReplacements(
|
|
|
194
196
|
type ${payload.typingId} = typeof ${payload.typingId};
|
|
195
197
|
`;
|
|
196
198
|
} else if (payload.type === "exitAttr") {
|
|
199
|
+
const rewrittenMeta = `${payload.oldMetaType}_rewritten`;
|
|
200
|
+
const mergeFn = `${payload.oldMetaType}_mergeFn`;
|
|
201
|
+
const mergeFnRet = `${payload.oldMetaType}_mergeFnRet`;
|
|
197
202
|
replacement = dedent`
|
|
198
203
|
type ${payload.returnType} = typeof ${payload.returnType};
|
|
199
|
-
type ${
|
|
204
|
+
type ${rewrittenMeta} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType};
|
|
205
|
+
let ${mergeFn}!: ${payload.defType} extends {
|
|
206
|
+
[${payload.attrName}]: { mergeMeta: infer M }
|
|
207
|
+
} ? M : null;
|
|
208
|
+
let ${mergeFnRet} = ${mergeFn}?.(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
|
|
209
|
+
type ${payload.newMetaType} = [typeof ${mergeFn}] extends [null] ? ${rewrittenMeta} : typeof ${mergeFnRet};
|
|
200
210
|
`;
|
|
201
211
|
} else {
|
|
202
212
|
replacement = "";
|
|
@@ -168,7 +168,14 @@ const enterVMFromAttr = (
|
|
|
168
168
|
state.attrsOfCurrentVm.push([]);
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
interface ExitVMResult {
|
|
172
|
+
finalMetaId: Identifier;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const exitVM = (
|
|
176
|
+
state: TypingTranspileState,
|
|
177
|
+
errorRange?: [number, number],
|
|
178
|
+
): ExitVMResult => {
|
|
172
179
|
const currentDefTypeId = state.vmDefTypeIdStack.pop()!;
|
|
173
180
|
const currentMetaId = state.metaTypeIdStack.pop()!;
|
|
174
181
|
const finalMetaId = state.finalMetaTypeIdStack.pop()!;
|
|
@@ -183,17 +190,24 @@ const exitVM = (state: TypingTranspileState, errorRange?: [number, number]) => {
|
|
|
183
190
|
errorRange,
|
|
184
191
|
}),
|
|
185
192
|
);
|
|
193
|
+
return { finalMetaId };
|
|
186
194
|
};
|
|
187
195
|
|
|
196
|
+
interface EnterAttrResult {
|
|
197
|
+
lhsId: Identifier;
|
|
198
|
+
}
|
|
199
|
+
|
|
188
200
|
const enterAttr = (
|
|
189
201
|
state: TypingTranspileState,
|
|
190
202
|
attrName: string,
|
|
191
|
-
):
|
|
203
|
+
): EnterAttrResult => {
|
|
192
204
|
const defTypeId = state.vmDefTypeIdStack.at(-1);
|
|
193
205
|
const metaTypeId = state.metaTypeIdStack.at(-1);
|
|
194
206
|
if (!defTypeId || !metaTypeId) {
|
|
195
207
|
// FIXME error handling?
|
|
196
|
-
return {
|
|
208
|
+
return {
|
|
209
|
+
lhsId: { type: "Identifier", name: "__gts_invalid_attr_obj" },
|
|
210
|
+
};
|
|
197
211
|
}
|
|
198
212
|
state.attrsOfCurrentVm.at(-1)!.push(attrName);
|
|
199
213
|
const lhsId: Identifier = {
|
|
@@ -210,7 +224,7 @@ const enterAttr = (
|
|
|
210
224
|
hintOnly: attrName === ATTR_HINT_ATTR_NAME,
|
|
211
225
|
}),
|
|
212
226
|
);
|
|
213
|
-
return { lhsId
|
|
227
|
+
return { lhsId };
|
|
214
228
|
};
|
|
215
229
|
|
|
216
230
|
const genBindingTyping = (
|
|
@@ -236,7 +250,12 @@ const genBindingTyping = (
|
|
|
236
250
|
);
|
|
237
251
|
};
|
|
238
252
|
|
|
239
|
-
const exitAttr = (
|
|
253
|
+
const exitAttr = (
|
|
254
|
+
state: TypingTranspileState,
|
|
255
|
+
attrName: string,
|
|
256
|
+
innerVMFinalMetaId: Identifier,
|
|
257
|
+
returningId: Identifier,
|
|
258
|
+
) => {
|
|
240
259
|
const currentDefId = state.vmDefTypeIdStack.at(-1);
|
|
241
260
|
if (!currentDefId) {
|
|
242
261
|
return;
|
|
@@ -250,6 +269,8 @@ const exitAttr = (state: TypingTranspileState, returningId: Identifier) => {
|
|
|
250
269
|
createReplacementHolder(state, {
|
|
251
270
|
type: "exitAttr",
|
|
252
271
|
defType: currentDefId.name,
|
|
272
|
+
attrName,
|
|
273
|
+
innerMetaType: innerVMFinalMetaId.name,
|
|
253
274
|
oldMetaType: oldMetaTypeId.name,
|
|
254
275
|
newMetaType: newMetaTypeId.name,
|
|
255
276
|
returnType: returningId.name,
|
|
@@ -473,11 +494,12 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
473
494
|
],
|
|
474
495
|
});
|
|
475
496
|
enterVMFromAttr(state, returnValue);
|
|
497
|
+
let exitVMResult: ExitVMResult;
|
|
476
498
|
if (body.namedAttributes) {
|
|
477
499
|
visit(body.namedAttributes);
|
|
478
|
-
exitVM(state, body.namedAttributes.range);
|
|
500
|
+
exitVMResult = exitVM(state, body.namedAttributes.range);
|
|
479
501
|
} else {
|
|
480
|
-
exitVM(state, name.range);
|
|
502
|
+
exitVMResult = exitVM(state, name.range);
|
|
481
503
|
}
|
|
482
504
|
if (bindingName) {
|
|
483
505
|
const export_ = node.bindingAccessModifier !== "private";
|
|
@@ -505,7 +527,7 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
505
527
|
leadingComments: state.defineLeadingComments,
|
|
506
528
|
});
|
|
507
529
|
}
|
|
508
|
-
exitAttr(state, returnValue);
|
|
530
|
+
exitAttr(state, attrName, exitVMResult.finalMetaId, returnValue);
|
|
509
531
|
return EMPTY;
|
|
510
532
|
},
|
|
511
533
|
GTSNamedAttributeBlock(node, { state, visit }) {
|
|
@@ -561,7 +583,7 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
|
|
|
561
583
|
}
|
|
562
584
|
const fn: ArrowFunctionExpression = {
|
|
563
585
|
type: "ArrowFunctionExpression",
|
|
564
|
-
params: state.
|
|
586
|
+
params: [state.fnArgId],
|
|
565
587
|
body: {
|
|
566
588
|
type: "BlockStatement",
|
|
567
589
|
body: node.directAction.body.map((stmt) => visit(stmt) as Statement),
|
package/src/types.ts
CHANGED
|
@@ -21,7 +21,6 @@ declare module "estree" {
|
|
|
21
21
|
interface ExpressionMap {
|
|
22
22
|
GTSShortcutArgumentExpression: GTSShortcutArgumentExpression;
|
|
23
23
|
GTSShortcutFunctionExpression: GTSShortcutFunctionExpression;
|
|
24
|
-
GTSQueryExpression: GTSQueryExpression;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
interface SimpleCallExpression {
|
|
@@ -77,11 +76,6 @@ declare module "estree" {
|
|
|
77
76
|
expression: boolean;
|
|
78
77
|
}
|
|
79
78
|
|
|
80
|
-
interface GTSQueryExpression extends BaseExpression {
|
|
81
|
-
type: "GTSQueryExpression";
|
|
82
|
-
star?: boolean;
|
|
83
|
-
argument: Expression;
|
|
84
|
-
}
|
|
85
79
|
}
|
|
86
80
|
|
|
87
81
|
declare module "acorn" {
|