@gi-tcg/gts-transpiler 0.2.0 → 0.3.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/index.js CHANGED
@@ -77,7 +77,7 @@ function loosePlugin() {
77
77
  return super.parseIdent(liberal);
78
78
  }
79
79
  };
80
- _proxiedThis = new Proxy(this, {
80
+ #proxiedThis = new Proxy(this, {
81
81
  get: (target, prop) => {
82
82
  if (prop === "parseIdent") {
83
83
  return this._patchedParseIdent;
@@ -96,7 +96,7 @@ function loosePlugin() {
96
96
  return this.finishNode(dummy, "Identifier");
97
97
  }
98
98
  parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
99
- return super.parseSubscript.call(this._proxiedThis, base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
99
+ return super.parseSubscript.call(this.#proxiedThis, base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
100
100
  }
101
101
  };
102
102
  };
@@ -137,13 +137,17 @@ function gtsPlugin(options = {}) {
137
137
  }
138
138
  gts_parseNamedAttributeDefinition() {
139
139
  const node = this.startNode();
140
+ const start = this.start;
140
141
  let name;
141
142
  if (this.type.label === "string") {
142
143
  name = this.parseExprAtom();
144
+ if (typeof name.value === "string" && name.value.startsWith("~")) {
145
+ this.raise(start, `Attribute name starts with '~' is reserved for internal use.`);
146
+ }
143
147
  } else if (this.type.label === "name") {
144
148
  name = this.parseIdent();
145
149
  } else {
146
- this.raise(this.start, "Expected attribute name");
150
+ this.raise(start, "Expected attribute name");
147
151
  }
148
152
  node.name = name;
149
153
  node.body = this.gts_parseAttributeBody();
@@ -277,7 +281,7 @@ function gtsPlugin(options = {}) {
277
281
  return super.parseExprAtom(refDestructuringErrors, forInit, forNew);
278
282
  }
279
283
  parseMaybeUnary(refDestructuringErrors, sawUnary, incDec, forInit) {
280
- if (this.isContextual("query")) {
284
+ if (this.isShortcutContext && this.isContextual("query")) {
281
285
  const expr = this.gts_parseQueryExpression();
282
286
  if (!incDec && this.eat(tokTypes2.starstar)) {
283
287
  this.unexpected(this.lastTokStart);
@@ -556,6 +560,59 @@ class GtsTranspilerError extends Error {
556
560
  }
557
561
  }
558
562
 
563
+ // packages/transpiler/src/parse/record_call_lparen_plugin.ts
564
+ import { tokTypes as tokTypes3 } from "acorn";
565
+ function recordCallLParenPlugin() {
566
+ return function recordCallLParenPluginTransformer(parser) {
567
+ return class RecordCallLParenParser extends parser {
568
+ parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
569
+ let recordedLParenLoc = null;
570
+ if (!noCalls && this.type === tokTypes3.parenL) {
571
+ recordedLParenLoc = {
572
+ start: this.startLoc,
573
+ end: this.endLoc
574
+ };
575
+ }
576
+ const result = super.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
577
+ if (recordedLParenLoc && result.type === "CallExpression") {
578
+ result.lParenLoc = recordedLParenLoc;
579
+ }
580
+ return result;
581
+ }
582
+ _capturedLParenLocFromNew = null;
583
+ _patchedEat = (type) => {
584
+ if (type === tokTypes3.parenL) {
585
+ this._capturedLParenLocFromNew = {
586
+ start: this.startLoc,
587
+ end: this.endLoc
588
+ };
589
+ }
590
+ return this.eat(type);
591
+ };
592
+ #proxiedThis = new Proxy(this, {
593
+ get: (target, prop) => {
594
+ if (prop === "eat") {
595
+ return this._patchedEat;
596
+ }
597
+ const value = Reflect.get(target, prop);
598
+ if (typeof value === "function") {
599
+ return value.bind(target);
600
+ }
601
+ return value;
602
+ }
603
+ });
604
+ parseNew() {
605
+ const result = super.parseNew.apply(this.#proxiedThis);
606
+ if (this._capturedLParenLocFromNew && result.type === "NewExpression") {
607
+ result.lParenLoc = this._capturedLParenLocFromNew;
608
+ this._capturedLParenLocFromNew = null;
609
+ }
610
+ return result;
611
+ }
612
+ };
613
+ };
614
+ }
615
+
559
616
  // packages/transpiler/src/parse/index.ts
560
617
  var TsParser = Parser.extend(tsPlugin());
561
618
  function parse(input, options) {
@@ -580,10 +637,9 @@ function parse(input, options) {
580
637
  }
581
638
  function parseLoose(input, options) {
582
639
  try {
583
- const GtsParser = TsParser.extend(loosePlugin(), gtsPlugin({
584
- ...options,
585
- allowEmptyShortcutMember: true,
586
- allowEmptyPositionalAttribute: true
640
+ const GtsParser = TsParser.extend(loosePlugin(), ...options?.recordCallLParens ? [recordCallLParenPlugin()] : [], gtsPlugin({
641
+ allowEmptyShortcutMember: options?.allowEmptyPositionalAttribute || true,
642
+ allowEmptyPositionalAttribute: options?.allowEmptyPositionalAttribute || true
587
643
  }));
588
644
  const { onComment, addComments } = getCommentHandlers(input, []);
589
645
  const ast = GtsParser.parse(input, {
@@ -802,7 +858,7 @@ var commonGtsVisitor = {
802
858
  kind: "init",
803
859
  method: false,
804
860
  shorthand: false,
805
- value: state.ActionId,
861
+ value: state.ActionLit,
806
862
  loc: node.loc
807
863
  },
808
864
  {
@@ -896,6 +952,15 @@ var commonGtsVisitor = {
896
952
  type: "Literal",
897
953
  value: !!node.star
898
954
  }
955
+ },
956
+ {
957
+ type: "Property",
958
+ key: { type: "Identifier", name: "context" },
959
+ computed: false,
960
+ kind: "init",
961
+ method: false,
962
+ shorthand: false,
963
+ value: state.fnArgId
899
964
  }
900
965
  ]
901
966
  }
@@ -908,14 +973,10 @@ var gtsVisitor = {
908
973
  const body = [];
909
974
  for (const stmt of node.body) {
910
975
  const visited = visit(stmt);
911
- if (visited.type !== "EmptyStatement") {
912
- body.push(visited);
913
- }
914
- if (state.pendingStatements.length > 0) {
915
- body.push(...state.pendingStatements);
916
- state.pendingStatements = [];
917
- }
976
+ body.push(visited);
918
977
  }
978
+ body.unshift(...state.bindingStatements);
979
+ state.bindingStatements = [];
919
980
  if (state.hasQueryExpressions) {
920
981
  body.unshift({
921
982
  type: "ImportDeclaration",
@@ -944,16 +1005,6 @@ var gtsVisitor = {
944
1005
  type: "ImportSpecifier",
945
1006
  imported: { type: "Identifier", name: "createBinding" },
946
1007
  local: state.createBindingFnId
947
- },
948
- {
949
- type: "ImportSpecifier",
950
- imported: { type: "Identifier", name: "Action" },
951
- local: state.ActionId
952
- },
953
- {
954
- type: "ImportSpecifier",
955
- imported: { type: "Identifier", name: "Prelude" },
956
- local: state.preludeSymbolId
957
1008
  }
958
1009
  ],
959
1010
  source: { type: "Literal", value: state.runtimeImportSource },
@@ -990,8 +1041,7 @@ var gtsVisitor = {
990
1041
  };
991
1042
  const newBindings = state.externalizedBindings;
992
1043
  state.externalizedBindings = [];
993
- const statements = [];
994
- statements.push({
1044
+ state.bindingStatements.push({
995
1045
  type: "VariableDeclaration",
996
1046
  kind: "const",
997
1047
  declarations: [
@@ -1003,7 +1053,7 @@ var gtsVisitor = {
1003
1053
  ],
1004
1054
  loc: node.loc
1005
1055
  });
1006
- statements.push({
1056
+ state.bindingStatements.push({
1007
1057
  type: "VariableDeclaration",
1008
1058
  kind: "const",
1009
1059
  declarations: [
@@ -1040,31 +1090,26 @@ var gtsVisitor = {
1040
1090
  ]
1041
1091
  };
1042
1092
  if (binding.export) {
1043
- statements.push({
1093
+ state.bindingStatements.push({
1044
1094
  type: "ExportNamedDeclaration",
1045
1095
  declaration: decl,
1046
1096
  specifiers: [],
1047
1097
  attributes: []
1048
1098
  });
1049
1099
  } else {
1050
- statements.push(decl);
1100
+ state.bindingStatements.push(decl);
1051
1101
  }
1052
1102
  }
1053
- statements.push({
1103
+ return {
1054
1104
  type: "ExpressionStatement",
1055
1105
  expression: {
1056
1106
  type: "CallExpression",
1057
1107
  optional: false,
1058
- callee: {
1059
- ...state.createDefineFnId,
1060
- loc: node.loc
1061
- },
1108
+ callee: state.createDefineFnId,
1062
1109
  arguments: [state.rootVmId, nodeVarId]
1063
1110
  },
1064
1111
  loc: node.loc
1065
- });
1066
- state.pendingStatements.push(...statements);
1067
- return { type: "EmptyStatement" };
1112
+ };
1068
1113
  },
1069
1114
  GTSNamedAttributeDefinition(node, { visit, state }) {
1070
1115
  const namedBody = visit(node.body);
@@ -1196,9 +1241,9 @@ var initialTranspileState = (option = {}) => {
1196
1241
  const shortcutFunctionPreludes = option.shortcutFunctionPreludes ?? DEFAULT_SHORTCUT_FUNCTION_PRELUDES;
1197
1242
  const queryBindings = option.queryBindings ?? DEFAULT_QUERY_BINDINGS;
1198
1243
  const fnArgId = { type: "Identifier", name: "__gts_fnArg" };
1199
- const preludeSymbolId = {
1200
- type: "Identifier",
1201
- name: "__gts_Prelude"
1244
+ const PreludeLit = {
1245
+ type: "Literal",
1246
+ value: "~prelude"
1202
1247
  };
1203
1248
  const shortcutFunctionParameters = [
1204
1249
  fnArgId,
@@ -1219,7 +1264,7 @@ var initialTranspileState = (option = {}) => {
1219
1264
  right: {
1220
1265
  type: "MemberExpression",
1221
1266
  object: fnArgId,
1222
- property: preludeSymbolId,
1267
+ property: PreludeLit,
1223
1268
  computed: true,
1224
1269
  optional: false
1225
1270
  }
@@ -1242,8 +1287,8 @@ var initialTranspileState = (option = {}) => {
1242
1287
  return {
1243
1288
  createDefineFnId: { type: "Identifier", name: "__gts_createDefine" },
1244
1289
  createBindingFnId: { type: "Identifier", name: "__gts_createBinding" },
1245
- ActionId: { type: "Identifier", name: "__gts_Action" },
1246
- preludeSymbolId,
1290
+ ActionLit: { type: "Literal", value: "~action" },
1291
+ PreludeLit,
1247
1292
  fnArgId,
1248
1293
  shortcutFunctionParameters,
1249
1294
  rootVmId: { type: "Identifier", name: "__gts_rootVm" },
@@ -1266,7 +1311,7 @@ var initialTranspileState = (option = {}) => {
1266
1311
  externalizedBindings: [],
1267
1312
  hasQueryExpressions: false,
1268
1313
  defineIdCounter: 0,
1269
- pendingStatements: []
1314
+ bindingStatements: []
1270
1315
  };
1271
1316
  };
1272
1317
  var gtsToTs = (ast, option = {}) => {
@@ -1277,7 +1322,6 @@ var gtsToTs = (ast, option = {}) => {
1277
1322
  // packages/transpiler/src/transform/volar/index.ts
1278
1323
  import { walk as walk5 } from "zimmerframe";
1279
1324
  import { print } from "esrap";
1280
- import tsPrinter from "esrap/languages/ts";
1281
1325
 
1282
1326
  // packages/transpiler/src/transform/volar/replacements.ts
1283
1327
  var createReplacementHolder = (state, value) => {
@@ -1303,31 +1347,94 @@ var createReplacementHolder = (state, value) => {
1303
1347
  };
1304
1348
  function applyReplacements(state, code) {
1305
1349
  const replacementRegex = new RegExp("\\b" + state.replacementTag.name + "`(.*?)`", "gm");
1306
- const {
1307
- symbolsId: { NamedDefinition, Meta }
1308
- } = state;
1350
+ const { NamedDefinitionLit, MetaLit } = state;
1351
+ const NamedDefinition = JSON.stringify(NamedDefinitionLit.value);
1352
+ const Meta = JSON.stringify(MetaLit.value);
1353
+ const oneLine = (strings, ...values) => strings.reduce((result, chunk, index) => result + chunk + (index < values.length ? values[index] : ""), "").replace(/\n[ \t]*/g, " ").trim();
1309
1354
  return code.replace(replacementRegex, (_, rawPayload) => {
1310
1355
  const payload = JSON.parse(rawPayload);
1311
- if (payload.type === "enterVMFromRoot") {
1312
- return `type ${payload.defType} = (typeof ${payload.vm})[${NamedDefinition.name}]; type ${payload.metaType} = ${payload.defType}[${Meta.name}];`;
1356
+ if (payload.type === "preface") {
1357
+ return oneLine`
1358
+ namespace ${state.utilNsId.name} {
1359
+ export type UniqueKeyProbSegment = "__gts_unique_prob_seg__";
1360
+ export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
1361
+ }
1362
+ `;
1363
+ } else if (payload.type === "enterVMFromRoot") {
1364
+ return oneLine`
1365
+ type ${payload.defType} = (typeof ${payload.vm})[${NamedDefinition}];
1366
+ type ${payload.metaType} = ${payload.defType}[${Meta}];
1367
+ `;
1313
1368
  } else if (payload.type === "enterVMFromAttr") {
1314
- return `type ${payload.defType} = ${payload.returnType} extends { namedDefinition: infer Def } ? Def : { [${Meta.name}]: unknown }; type ${payload.metaType} = ${payload.defType}[${Meta.name}];`;
1369
+ return oneLine`
1370
+ type ${payload.defType} = ${payload.returnType} extends { namedDefinition: infer Def } ? Def : { ${Meta}: unknown };
1371
+ type ${payload.metaType} = ${payload.defType}[${Meta}];
1372
+ `;
1315
1373
  } else if (payload.type === "exitVM") {
1316
1374
  const lhs = `${payload.finalMetaType}_lhs`;
1317
1375
  const requiredAttrsNs = `${payload.finalMetaType}_rans`;
1318
1376
  const collectedAttrsExpr = `${payload.collectedAttrs.join(" | ")}`;
1319
1377
  const needleString = `"${requiredAttrsNs}_NeedleString" as any as "required attributes are missing"`;
1320
1378
  if (payload.errorLoc) {
1321
- state.additionalMappings.set(payload.errorLoc, needleString);
1379
+ state.extraMappings.set(payload.errorLoc, needleString);
1322
1380
  }
1323
- return `type ${payload.finalMetaType} = ${payload.metaType}; const ${lhs}: { [${Meta.name}]: ${payload.metaType} } & Omit<${payload.defType}, ${Meta.name}> = 0 as any; type ${lhs} = typeof ${lhs}; namespace ${requiredAttrsNs} { export type Collected = ${collectedAttrsExpr}; export type Expected = { [K in keyof ${payload.defType}]: ${lhs}[K] extends { required(this: ${lhs}): true } ? K : never }[keyof ${payload.defType}]; }; ((_: ${requiredAttrsNs}.Expected extends ${requiredAttrsNs}.Collected ? string : ${requiredAttrsNs}.Expected) => 0)(${needleString});`;
1381
+ return oneLine`
1382
+ type ${payload.finalMetaType} = ${payload.metaType};
1383
+ let ${lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${Meta}>;
1384
+ type ${lhs} = typeof ${lhs};
1385
+ namespace ${requiredAttrsNs} {
1386
+ export type Collected = ${collectedAttrsExpr};
1387
+ export type Expected = { [K in keyof ${payload.defType}]: ${lhs}[K] extends { required(this: ${lhs}): true } ? K : never }[keyof ${payload.defType}];
1388
+ };
1389
+ ((_: ${requiredAttrsNs}.Expected extends ${requiredAttrsNs}.Collected ? string : ${requiredAttrsNs}.Expected) => 0)(${needleString});
1390
+ `;
1324
1391
  } else if (payload.type === "enterAttr") {
1325
- return `const ${payload.lhs}: { [${Meta.name}]: ${payload.metaType} } & Omit<${payload.defType}, ${Meta.name}> = 0 as any;`;
1392
+ const uniqueKeyLhs = `${payload.lhs}_uniqueKey_lhs`;
1393
+ const uniqueKey = `${payload.lhs}_uniqueKey`;
1394
+ const uniqueKeyForThis = `${payload.lhs}_uniqueKeyFor_${payload.lhs}`;
1395
+ const uniqueKeyHelperIntf = `${payload.defType}_uniqueKeyProbeHelper`;
1396
+ const omittedKeys = `${payload.lhs}_omittedKeys`;
1397
+ return oneLine`
1398
+ type ${uniqueKeyLhs} = {
1399
+ ${Meta}: ${payload.metaType};
1400
+ uniqueKey: ${payload.defType} extends { [${payload.attrName}]: { uniqueKey: infer UniqueKey } } ? UniqueKey : () => 0;
1401
+
1402
+ let ${uniqueKeyLhs}!: ${uniqueKeyLhs};
1403
+ let ${uniqueKey} = ${uniqueKeyLhs}.uniqueKey();
1404
+ type ${uniqueKey} = typeof ${uniqueKey};
1405
+ let ${uniqueKeyForThis}!: \`\${${uniqueKey}}\${${state.utilNsId.name}.UniqueKeyProbSegment}${payload.lhs}\`;
1406
+ interface ${uniqueKeyHelperIntf} {
1407
+ [${uniqueKeyForThis}]: 1;
1408
+ }
1409
+ type ${omittedKeys} = ${Meta} | (
1410
+ ${uniqueKey} extends 0
1411
+ ? never /* no unique requirement */
1412
+ : string extends keyof ${uniqueKeyHelperIntf}
1413
+ ? keyof ${payload.defType} /* too loose, disable all */
1414
+ : ${state.utilNsId.name}.UnionToIntersection<
1415
+ keyof ${uniqueKeyHelperIntf} & \`\${${uniqueKey}}\${${state.utilNsId.name}.UniqueKeyProbSegment}\${string}\`
1416
+ > extends never
1417
+ ? ${payload.attrName} /* have duplicate, disable this */
1418
+ : never
1419
+ );
1420
+ let ${payload.lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${omittedKeys}>;
1421
+ `;
1326
1422
  } else if (payload.type === "createBindingTyping") {
1327
1423
  const typingIdLhs = `${payload.typingId}_lhs`;
1328
- return `type ${typingIdLhs} = { [${Meta.name}]: ${payload.finalMetaType}; as: ${payload.defType}[${payload.attrName}] extends { as: infer As } ? As : unknown }; let ${typingIdLhs}!: ${typingIdLhs}; let ${payload.typingId} = ${typingIdLhs}.as(); type ${payload.typingId} = typeof ${payload.typingId};`;
1424
+ return oneLine`
1425
+ type ${typingIdLhs} = {
1426
+ ${Meta}: ${payload.finalMetaType};
1427
+ as: ${payload.defType} extends { [${payload.attrName}]: { as: infer As } } ? As : unknown;
1428
+ };
1429
+ let ${typingIdLhs}!: ${typingIdLhs};
1430
+ let ${payload.typingId} = ${typingIdLhs}.as();
1431
+ type ${payload.typingId} = typeof ${payload.typingId};
1432
+ `;
1329
1433
  } else if (payload.type === "exitAttr") {
1330
- return `type ${payload.returnType} = typeof ${payload.returnType}; type ${payload.newMetaType} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType}`;
1434
+ return oneLine`
1435
+ type ${payload.returnType} = typeof ${payload.returnType};
1436
+ type ${payload.newMetaType} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType}
1437
+ `;
1331
1438
  } else {
1332
1439
  return "";
1333
1440
  }
@@ -1344,59 +1451,7 @@ var ANY_INIT = {
1344
1451
  expression: { type: "Literal", value: 0 },
1345
1452
  typeAnnotation: ANY
1346
1453
  };
1347
- var emitPreface = (state) => {
1348
- if (state.prefaceInserted) {
1349
- return;
1350
- }
1351
- const symbolsLhs = {
1352
- type: "TSQualifiedName",
1353
- left: { type: "Identifier", name: state.rootVmId.name },
1354
- right: { type: "Identifier", name: "_symbols" }
1355
- };
1356
- for (const symbolName of [
1357
- "Meta",
1358
- "Action",
1359
- "NamedDefinition",
1360
- "Prelude"
1361
- ]) {
1362
- const init = {
1363
- type: "TSTypeQuery",
1364
- exprName: {
1365
- type: "TSQualifiedName",
1366
- left: symbolsLhs,
1367
- right: { type: "Identifier", name: symbolName }
1368
- }
1369
- };
1370
- const symbolId = symbolName === "Action" ? state.ActionId : symbolName === "Prelude" ? state.preludeSymbolId : state.symbolsId[symbolName];
1371
- state.typingPendingStatements.push({
1372
- type: "TSTypeAliasDeclaration",
1373
- id: symbolId,
1374
- typeAnnotation: init
1375
- }, {
1376
- type: "VariableDeclaration",
1377
- kind: "const",
1378
- declarations: [
1379
- {
1380
- type: "VariableDeclarator",
1381
- id: {
1382
- ...symbolId,
1383
- typeAnnotation: {
1384
- type: "TSTypeAnnotation",
1385
- typeAnnotation: {
1386
- type: "TSTypeReference",
1387
- typeName: symbolId
1388
- }
1389
- }
1390
- },
1391
- init: ANY_INIT
1392
- }
1393
- ]
1394
- });
1395
- }
1396
- state.prefaceInserted = true;
1397
- };
1398
1454
  var enterVMFromRoot = (state) => {
1399
- emitPreface(state);
1400
1455
  let defTypeId = {
1401
1456
  type: "Identifier",
1402
1457
  name: `__gts_rootVmDefType_${state.idCounter++}`
@@ -1473,7 +1528,8 @@ var enterAttr = (state, attrName) => {
1473
1528
  type: "enterAttr",
1474
1529
  defType: defTypeId.name,
1475
1530
  metaType: metaTypeId.name,
1476
- lhs: lhsId.name
1531
+ lhs: lhsId.name,
1532
+ attrName
1477
1533
  }));
1478
1534
  return { lhsId };
1479
1535
  };
@@ -1539,8 +1595,7 @@ var gtsToTypingsWalker = {
1539
1595
  }
1540
1596
  }
1541
1597
  }
1542
- ],
1543
- leadingComments: extBinding.leadingComments
1598
+ ]
1544
1599
  };
1545
1600
  if (extBinding.export) {
1546
1601
  body.unshift({
@@ -1548,31 +1603,18 @@ var gtsToTypingsWalker = {
1548
1603
  declaration: varDecl,
1549
1604
  specifiers: [],
1550
1605
  source: null,
1551
- attributes: []
1606
+ attributes: [],
1607
+ leadingComments: extBinding.leadingComments
1552
1608
  });
1553
1609
  } else {
1610
+ varDecl.leadingComments = extBinding.leadingComments;
1554
1611
  body.unshift(varDecl);
1555
1612
  }
1556
1613
  }
1557
- if (state.prefaceInserted) {
1558
- body.unshift({
1559
- type: "ImportDeclaration",
1560
- specifiers: [
1561
- {
1562
- type: "ImportDefaultSpecifier",
1563
- local: state.rootVmId
1564
- }
1565
- ],
1566
- source: {
1567
- type: "Literal",
1568
- value: `${state.providerImportSource}/vm`
1569
- },
1570
- attributes: []
1571
- });
1572
- }
1573
1614
  if (state.hasQueryExpressions) {
1574
1615
  body.unshift({
1575
1616
  type: "ImportDeclaration",
1617
+ diagnosticsOnTop: true,
1576
1618
  specifiers: [
1577
1619
  {
1578
1620
  type: "ImportDefaultSpecifier",
@@ -1586,6 +1628,23 @@ var gtsToTypingsWalker = {
1586
1628
  attributes: []
1587
1629
  });
1588
1630
  }
1631
+ body.unshift({
1632
+ type: "ImportDeclaration",
1633
+ diagnosticsOnTop: true,
1634
+ specifiers: [
1635
+ {
1636
+ type: "ImportDefaultSpecifier",
1637
+ local: state.rootVmId
1638
+ }
1639
+ ],
1640
+ source: {
1641
+ type: "Literal",
1642
+ value: `${state.providerImportSource}/vm`
1643
+ },
1644
+ attributes: []
1645
+ }, createReplacementHolder(state, {
1646
+ type: "preface"
1647
+ }));
1589
1648
  return {
1590
1649
  ...node,
1591
1650
  body
@@ -1600,15 +1659,18 @@ var gtsToTypingsWalker = {
1600
1659
  GTSNamedAttributeDefinition(node, { visit, state }) {
1601
1660
  const { name, body, bindingName } = node;
1602
1661
  const attrName = JSON.stringify(name.type === "Literal" ? String(name.value) : name.name);
1662
+ const attributeNameToken = state.leafTokens.find((t) => t.loc === name.loc);
1663
+ if (attributeNameToken) {
1664
+ attributeNameToken.sourceLengthOffset = 1;
1665
+ }
1603
1666
  const { lhsId } = enterAttr(state, attrName);
1667
+ state.extraMappings.set(`${name.loc?.start.line}:${name.loc?.start.column}`, `${lhsId.name}${name.type === "Literal" ? `[` : `.`}`);
1604
1668
  const positionals = body.positionalAttributes.attributes.map((attr) => {
1605
1669
  if (attr.type === "Identifier" && /^[a-z_]/.test(attr.name)) {
1606
1670
  const token = state.leafTokens.find((t) => t.loc === attr.loc);
1607
1671
  if (token) {
1608
- token.locationAdjustment = {
1609
- startOffset: 1,
1610
- generatedLength: attr.name.length + 2
1611
- };
1672
+ token.generatedStartOffset = 1;
1673
+ token.generatedLength = attr.name.length + 2;
1612
1674
  }
1613
1675
  return {
1614
1676
  type: "Literal",
@@ -1684,7 +1746,11 @@ var gtsToTypingsWalker = {
1684
1746
  visit(attr);
1685
1747
  }
1686
1748
  if (node.directAction) {
1687
- const { lhsId } = enterAttr(state, state.ActionId.name);
1749
+ const attrName = JSON.stringify(state.ActionLit.value);
1750
+ const { lhsId } = enterAttr(state, attrName);
1751
+ const actionNotExistsReplacementStr = `${lhsId.name}[${attrName}]`;
1752
+ const actionNotExistsErrorLoc = `${node.directAction.loc?.start.line}:${node.directAction.loc?.start.column}`;
1753
+ state.extraMappings.set(actionNotExistsErrorLoc, actionNotExistsReplacementStr);
1688
1754
  const fn = {
1689
1755
  type: "ArrowFunctionExpression",
1690
1756
  params: state.shortcutFunctionParameters,
@@ -1711,7 +1777,7 @@ var gtsToTypingsWalker = {
1711
1777
  callee: {
1712
1778
  type: "MemberExpression",
1713
1779
  object: lhsId,
1714
- property: state.ActionId,
1780
+ property: state.ActionLit,
1715
1781
  computed: true,
1716
1782
  optional: false
1717
1783
  },
@@ -1810,8 +1876,7 @@ function buildSrcToGenMap(source_map, line_offsets, generated_code) {
1810
1876
  function getGeneratedPosition(src_line, src_column, srcToGenMap) {
1811
1877
  const key = `${src_line}:${src_column}`;
1812
1878
  const positions = srcToGenMap.get(key);
1813
- if (!positions || positions.length === 0) {}
1814
- return positions?.[0];
1879
+ return positions || [];
1815
1880
  }
1816
1881
  function createLineOffsets(content) {
1817
1882
  const lines = content.split(`
@@ -1828,39 +1893,41 @@ function locToOffset(line, column, line_offsets) {
1828
1893
  if (line < 1 || line > line_offsets.length) {}
1829
1894
  return line_offsets[line - 1] + column;
1830
1895
  }
1831
- function convertToVolarMappings(generated, source, sourceMap, tokens, additionalMappings) {
1896
+ function convertToVolarMappings(generated, source, sourceMap, tokens, extraMappings) {
1832
1897
  const sourceLineOffsets = createLineOffsets(source);
1833
1898
  const generatedLineOffsets = createLineOffsets(generated);
1834
1899
  const srcToGenMap = buildSrcToGenMap(sourceMap, generatedLineOffsets, generated);
1835
1900
  const mappings = [];
1836
1901
  for (const token of tokens) {
1837
1902
  let sourceStart = locToOffset(token.loc.start.line, token.loc.start.column, sourceLineOffsets);
1903
+ sourceStart += token.sourceStartOffset ?? 0;
1838
1904
  const sourceEnd = locToOffset(token.loc.end.line, token.loc.end.column, sourceLineOffsets);
1839
1905
  let sourceLength = token.sourceLength ?? sourceEnd - sourceStart;
1840
- const genLineCol = getGeneratedPosition(token.loc.start.line, token.loc.start.column, srcToGenMap);
1906
+ sourceLength += token.sourceLengthOffset ?? 0;
1907
+ const [genLineCol] = getGeneratedPosition(token.loc.start.line, token.loc.start.column, srcToGenMap);
1841
1908
  if (!genLineCol) {
1842
1909
  continue;
1843
1910
  }
1844
1911
  let genStart = locToOffset(genLineCol.line, genLineCol.column, generatedLineOffsets);
1845
- if (token.locationAdjustment) {
1912
+ if (token.isDummy) {
1913
+ while (sourceStart > 0 && /\s/.test(source[sourceStart - 1])) {
1914
+ sourceStart--;
1915
+ sourceLength++;
1916
+ }
1917
+ }
1918
+ const generatedLength = token.generatedLength ?? sourceLength;
1919
+ if (typeof token.generatedStartOffset === "number" && token.generatedStartOffset > 0) {
1846
1920
  mappings.push({
1847
1921
  sourceOffsets: [sourceStart],
1848
1922
  generatedOffsets: [genStart],
1849
1923
  lengths: [0],
1850
- generatedLengths: [token.locationAdjustment.generatedLength],
1924
+ generatedLengths: [generatedLength],
1851
1925
  data: {
1852
1926
  verification: true
1853
1927
  }
1854
1928
  });
1855
- genStart += token.locationAdjustment.startOffset;
1929
+ genStart += token.generatedStartOffset;
1856
1930
  }
1857
- if (token.isDummy) {
1858
- while (sourceStart > 0 && /\s/.test(source[sourceStart - 1])) {
1859
- sourceStart--;
1860
- sourceLength++;
1861
- }
1862
- }
1863
- const generatedLength = token.generatedLength ?? sourceLength;
1864
1931
  mappings.push({
1865
1932
  sourceOffsets: [sourceStart],
1866
1933
  generatedOffsets: [genStart],
@@ -1869,7 +1936,20 @@ function convertToVolarMappings(generated, source, sourceMap, tokens, additional
1869
1936
  data: DEFAULT_VOLAR_MAPPING_DATA
1870
1937
  });
1871
1938
  }
1872
- for (const [loc, codeSnippet] of additionalMappings) {
1939
+ const locMapsToTop = getGeneratedPosition(1, 0, srcToGenMap);
1940
+ for (const loc of locMapsToTop) {
1941
+ const offset = locToOffset(loc.line, loc.column, generatedLineOffsets);
1942
+ mappings.push({
1943
+ sourceOffsets: [0],
1944
+ generatedOffsets: [offset],
1945
+ lengths: [0],
1946
+ generatedLengths: [0],
1947
+ data: {
1948
+ verification: true
1949
+ }
1950
+ });
1951
+ }
1952
+ for (const [loc, codeSnippet] of extraMappings) {
1873
1953
  const generatedStart = generated.indexOf(codeSnippet);
1874
1954
  if (generatedStart === -1) {
1875
1955
  continue;
@@ -1912,26 +1992,138 @@ function isLeafNode(node) {
1912
1992
  return true;
1913
1993
  }
1914
1994
  function collectLeafTokens(ast) {
1915
- const tokens = [];
1916
- walk4(ast, tokens, {
1917
- _(node, { state, next }) {
1995
+ const state = {
1996
+ tokens: []
1997
+ };
1998
+ walk4(ast, state, {
1999
+ _(node, { state: state2, next }) {
1918
2000
  if (isLeafNode(node) && node.loc) {
1919
2001
  const token = {
1920
2002
  loc: node.loc
1921
2003
  };
1922
- if (node.isDummy) {
2004
+ if ("isDummy" in node && node.isDummy) {
1923
2005
  token.isDummy = true;
1924
2006
  token.sourceLength = 0;
1925
2007
  token.generatedLength = 1;
1926
2008
  }
1927
- state.push(token);
2009
+ state2.tokens.push(token);
2010
+ }
2011
+ next();
2012
+ },
2013
+ NewExpression(node, { state: state2, next }) {
2014
+ const lParenLoc = node.lParenLoc;
2015
+ if (lParenLoc) {
2016
+ state2.tokens.push({
2017
+ loc: lParenLoc
2018
+ });
2019
+ }
2020
+ next();
2021
+ },
2022
+ CallExpression(node, { state: state2, next }) {
2023
+ const lParenLoc = node.lParenLoc;
2024
+ if (lParenLoc) {
2025
+ state2.tokens.push({
2026
+ loc: lParenLoc
2027
+ });
1928
2028
  }
1929
2029
  next();
1930
2030
  }
1931
2031
  });
1932
- return tokens;
2032
+ return state.tokens;
1933
2033
  }
1934
2034
 
2035
+ // packages/transpiler/src/transform/volar/printer.ts
2036
+ import tsPrinter from "esrap/languages/ts";
2037
+ var printer = tsPrinter({
2038
+ getLeadingComments: (node) => node.leadingComments,
2039
+ getTrailingComments: (node) => node.trailingComments
2040
+ });
2041
+ var prevIdentifier = printer.Identifier;
2042
+ printer.Identifier = function(node, context) {
2043
+ if (node.isDummy) {
2044
+ const text = Reflect.get(node, "lastArg") ? "," : "";
2045
+ context.write(text, node);
2046
+ } else {
2047
+ prevIdentifier(node, context);
2048
+ }
2049
+ };
2050
+ var prevCallNewExpression = printer.CallExpression;
2051
+ var newCallNewExpression = function(node, context) {
2052
+ const lastArg = node.arguments.at(-1);
2053
+ if (lastArg) {
2054
+ Reflect.set(lastArg, "lastArg", true);
2055
+ }
2056
+ if (!node.lParenLoc) {
2057
+ return prevCallNewExpression(node, context);
2058
+ }
2059
+ let hasDeferredWrite = false;
2060
+ let interceptionDone = false;
2061
+ const lParenFakeNode = {
2062
+ loc: node.lParenLoc
2063
+ };
2064
+ const patchedWrite = (text, node2) => {
2065
+ if (text === "(") {
2066
+ hasDeferredWrite = true;
2067
+ } else {
2068
+ context.write(text, node2);
2069
+ }
2070
+ };
2071
+ const patchedVisit = (node2) => {
2072
+ if (hasDeferredWrite) {
2073
+ context.write("(");
2074
+ }
2075
+ return context.visit(node2);
2076
+ };
2077
+ const patchedAppend = (subcontext) => {
2078
+ if (hasDeferredWrite) {
2079
+ context.write("(", lParenFakeNode);
2080
+ interceptionDone = true;
2081
+ }
2082
+ return context.append(subcontext);
2083
+ };
2084
+ const proxiedContext = new Proxy(context, {
2085
+ get(target, prop) {
2086
+ if (!interceptionDone) {
2087
+ if (prop === "write") {
2088
+ return patchedWrite;
2089
+ }
2090
+ if (prop === "visit") {
2091
+ return patchedVisit;
2092
+ }
2093
+ if (prop === "append") {
2094
+ return patchedAppend;
2095
+ }
2096
+ }
2097
+ const value = Reflect.get(target, prop);
2098
+ if (typeof value === "function") {
2099
+ return value.bind(target);
2100
+ }
2101
+ return value;
2102
+ }
2103
+ });
2104
+ return prevCallNewExpression(node, proxiedContext);
2105
+ };
2106
+ printer.CallExpression = newCallNewExpression;
2107
+ printer.NewExpression = newCallNewExpression;
2108
+ var prevWildcard = printer._;
2109
+ printer._ = (node, context, visit) => {
2110
+ const contextProto = Object.getPrototypeOf(context);
2111
+ const prevContextWrite = contextProto.write;
2112
+ if ("diagnosticsOnTop" in node && node.diagnosticsOnTop) {
2113
+ contextProto.write = function(text, node2) {
2114
+ node2 ??= {};
2115
+ node2.loc ??= {
2116
+ start: { line: 1, column: 0 },
2117
+ end: { line: 1, column: 0 }
2118
+ };
2119
+ return prevContextWrite.call(this, text, node2);
2120
+ };
2121
+ }
2122
+ prevWildcard(node, context, visit);
2123
+ contextProto.write = prevContextWrite;
2124
+ };
2125
+ var patchedPrinter = printer;
2126
+
1935
2127
  // packages/transpiler/src/transform/volar/index.ts
1936
2128
  function gtsToTypings(ast, option) {
1937
2129
  const state = {
@@ -1939,34 +2131,20 @@ function gtsToTypings(ast, option) {
1939
2131
  leafTokens: option.leafTokens,
1940
2132
  idCounter: 0,
1941
2133
  typingPendingStatements: [],
1942
- prefaceInserted: false,
1943
- rootVmId: { type: "Identifier", name: "__root_vm" },
2134
+ rootVmId: { type: "Identifier", name: "__gts_root_vm" },
2135
+ utilNsId: { type: "Identifier", name: "__gts_util" },
1944
2136
  replacementTag: { type: "Identifier", name: "__gts_replacement_tag" },
1945
- symbolsId: {
1946
- Meta: { type: "Identifier", name: "__gts_symbols_meta" },
1947
- NamedDefinition: { type: "Identifier", name: "__gts_symbols_namedDef" }
1948
- },
2137
+ MetaLit: { type: "Literal", value: "~meta" },
2138
+ NamedDefinitionLit: { type: "Literal", value: "~namedDefinition" },
1949
2139
  defineLeadingComments: [],
1950
2140
  vmDefTypeIdStack: [],
1951
2141
  metaTypeIdStack: [],
1952
2142
  finalMetaTypeIdStack: [],
1953
2143
  attrsOfCurrentVm: [],
1954
- additionalMappings: option.additionalMappings
2144
+ extraMappings: option.extraMappings
1955
2145
  };
1956
2146
  const newAst = walk5(ast, state, gtsToTypingsWalker);
1957
- const printer = tsPrinter({
1958
- getLeadingComments: (node) => node.leadingComments,
1959
- getTrailingComments: (node) => node.trailingComments
1960
- });
1961
- const prevIdentifier = printer.Identifier;
1962
- printer.Identifier = function(node, context) {
1963
- if (node.isDummy) {
1964
- context.write("", node);
1965
- } else {
1966
- prevIdentifier(node, context);
1967
- }
1968
- };
1969
- const { code, map } = print(newAst, printer, {
2147
+ const { code, map } = print(newAst, patchedPrinter, {
1970
2148
  indent: " "
1971
2149
  });
1972
2150
  return {
@@ -1976,13 +2154,13 @@ function gtsToTypings(ast, option) {
1976
2154
  }
1977
2155
  function transformForVolar(ast, option, sourceInfo) {
1978
2156
  const tokens = collectLeafTokens(ast);
1979
- const additionalMappings = new Map;
2157
+ const extraMappings = new Map;
1980
2158
  const { code, sourceMap } = gtsToTypings(ast, {
1981
2159
  ...option,
1982
2160
  leafTokens: tokens,
1983
- additionalMappings
2161
+ extraMappings
1984
2162
  });
1985
- const volarMappings = convertToVolarMappings(code, sourceInfo.content, sourceMap, tokens, additionalMappings);
2163
+ const volarMappings = convertToVolarMappings(code, sourceInfo.content, sourceMap, tokens, extraMappings);
1986
2164
  return {
1987
2165
  code,
1988
2166
  mappings: volarMappings
@@ -2004,7 +2182,7 @@ function transform(ast, option = {}, sourceInfo = {}) {
2004
2182
  };
2005
2183
  }
2006
2184
  // packages/transpiler/src/config.ts
2007
- import path from "node:path";
2185
+ import path from "path-browserify-esm";
2008
2186
  var DEFAULT_GTS_CONFIG = {
2009
2187
  runtimeImportSource: "@gi-tcg/gts-runtime",
2010
2188
  providerImportSource: "@gi-tcg/core/gts",
@@ -2060,7 +2238,7 @@ function normalizeStartDir(sourceFile, cwd) {
2060
2238
  function* findNearestPackageConfig(readFileFn, startDir, stopDir) {
2061
2239
  let currentDir = startDir;
2062
2240
  while (true) {
2063
- const pkgPath = path.join(currentDir, "package.json");
2241
+ const pkgPath = path.resolve(currentDir, "package.json");
2064
2242
  const config = yield* readPackageConfig(readFileFn, pkgPath);
2065
2243
  if (config) {
2066
2244
  return config;
@@ -2095,7 +2273,9 @@ function transpile(source, filename, option) {
2095
2273
  });
2096
2274
  }
2097
2275
  function transpileForVolar(source, filename, option) {
2098
- const ast = parseLoose(source);
2276
+ const ast = parseLoose(source, {
2277
+ recordCallLParens: true
2278
+ });
2099
2279
  return transformForVolar(ast, option, {
2100
2280
  content: source,
2101
2281
  filename