@gi-tcg/gts-transpiler 0.2.0 → 0.3.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.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();
@@ -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
  {
@@ -908,14 +964,10 @@ var gtsVisitor = {
908
964
  const body = [];
909
965
  for (const stmt of node.body) {
910
966
  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
- }
967
+ body.push(visited);
918
968
  }
969
+ body.unshift(...state.bindingStatements);
970
+ state.bindingStatements = [];
919
971
  if (state.hasQueryExpressions) {
920
972
  body.unshift({
921
973
  type: "ImportDeclaration",
@@ -944,16 +996,6 @@ var gtsVisitor = {
944
996
  type: "ImportSpecifier",
945
997
  imported: { type: "Identifier", name: "createBinding" },
946
998
  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
999
  }
958
1000
  ],
959
1001
  source: { type: "Literal", value: state.runtimeImportSource },
@@ -990,8 +1032,7 @@ var gtsVisitor = {
990
1032
  };
991
1033
  const newBindings = state.externalizedBindings;
992
1034
  state.externalizedBindings = [];
993
- const statements = [];
994
- statements.push({
1035
+ state.bindingStatements.push({
995
1036
  type: "VariableDeclaration",
996
1037
  kind: "const",
997
1038
  declarations: [
@@ -1003,7 +1044,7 @@ var gtsVisitor = {
1003
1044
  ],
1004
1045
  loc: node.loc
1005
1046
  });
1006
- statements.push({
1047
+ state.bindingStatements.push({
1007
1048
  type: "VariableDeclaration",
1008
1049
  kind: "const",
1009
1050
  declarations: [
@@ -1040,31 +1081,26 @@ var gtsVisitor = {
1040
1081
  ]
1041
1082
  };
1042
1083
  if (binding.export) {
1043
- statements.push({
1084
+ state.bindingStatements.push({
1044
1085
  type: "ExportNamedDeclaration",
1045
1086
  declaration: decl,
1046
1087
  specifiers: [],
1047
1088
  attributes: []
1048
1089
  });
1049
1090
  } else {
1050
- statements.push(decl);
1091
+ state.bindingStatements.push(decl);
1051
1092
  }
1052
1093
  }
1053
- statements.push({
1094
+ return {
1054
1095
  type: "ExpressionStatement",
1055
1096
  expression: {
1056
1097
  type: "CallExpression",
1057
1098
  optional: false,
1058
- callee: {
1059
- ...state.createDefineFnId,
1060
- loc: node.loc
1061
- },
1099
+ callee: state.createDefineFnId,
1062
1100
  arguments: [state.rootVmId, nodeVarId]
1063
1101
  },
1064
1102
  loc: node.loc
1065
- });
1066
- state.pendingStatements.push(...statements);
1067
- return { type: "EmptyStatement" };
1103
+ };
1068
1104
  },
1069
1105
  GTSNamedAttributeDefinition(node, { visit, state }) {
1070
1106
  const namedBody = visit(node.body);
@@ -1196,9 +1232,9 @@ var initialTranspileState = (option = {}) => {
1196
1232
  const shortcutFunctionPreludes = option.shortcutFunctionPreludes ?? DEFAULT_SHORTCUT_FUNCTION_PRELUDES;
1197
1233
  const queryBindings = option.queryBindings ?? DEFAULT_QUERY_BINDINGS;
1198
1234
  const fnArgId = { type: "Identifier", name: "__gts_fnArg" };
1199
- const preludeSymbolId = {
1200
- type: "Identifier",
1201
- name: "__gts_Prelude"
1235
+ const PreludeLit = {
1236
+ type: "Literal",
1237
+ value: "~prelude"
1202
1238
  };
1203
1239
  const shortcutFunctionParameters = [
1204
1240
  fnArgId,
@@ -1219,7 +1255,7 @@ var initialTranspileState = (option = {}) => {
1219
1255
  right: {
1220
1256
  type: "MemberExpression",
1221
1257
  object: fnArgId,
1222
- property: preludeSymbolId,
1258
+ property: PreludeLit,
1223
1259
  computed: true,
1224
1260
  optional: false
1225
1261
  }
@@ -1242,8 +1278,8 @@ var initialTranspileState = (option = {}) => {
1242
1278
  return {
1243
1279
  createDefineFnId: { type: "Identifier", name: "__gts_createDefine" },
1244
1280
  createBindingFnId: { type: "Identifier", name: "__gts_createBinding" },
1245
- ActionId: { type: "Identifier", name: "__gts_Action" },
1246
- preludeSymbolId,
1281
+ ActionLit: { type: "Literal", value: "~action" },
1282
+ PreludeLit,
1247
1283
  fnArgId,
1248
1284
  shortcutFunctionParameters,
1249
1285
  rootVmId: { type: "Identifier", name: "__gts_rootVm" },
@@ -1266,7 +1302,7 @@ var initialTranspileState = (option = {}) => {
1266
1302
  externalizedBindings: [],
1267
1303
  hasQueryExpressions: false,
1268
1304
  defineIdCounter: 0,
1269
- pendingStatements: []
1305
+ bindingStatements: []
1270
1306
  };
1271
1307
  };
1272
1308
  var gtsToTs = (ast, option = {}) => {
@@ -1277,7 +1313,6 @@ var gtsToTs = (ast, option = {}) => {
1277
1313
  // packages/transpiler/src/transform/volar/index.ts
1278
1314
  import { walk as walk5 } from "zimmerframe";
1279
1315
  import { print } from "esrap";
1280
- import tsPrinter from "esrap/languages/ts";
1281
1316
 
1282
1317
  // packages/transpiler/src/transform/volar/replacements.ts
1283
1318
  var createReplacementHolder = (state, value) => {
@@ -1303,31 +1338,94 @@ var createReplacementHolder = (state, value) => {
1303
1338
  };
1304
1339
  function applyReplacements(state, code) {
1305
1340
  const replacementRegex = new RegExp("\\b" + state.replacementTag.name + "`(.*?)`", "gm");
1306
- const {
1307
- symbolsId: { NamedDefinition, Meta }
1308
- } = state;
1341
+ const { NamedDefinitionLit, MetaLit } = state;
1342
+ const NamedDefinition = JSON.stringify(NamedDefinitionLit.value);
1343
+ const Meta = JSON.stringify(MetaLit.value);
1344
+ const oneLine = (strings, ...values) => strings.reduce((result, chunk, index) => result + chunk + (index < values.length ? values[index] : ""), "").replace(/\n[ \t]*/g, " ").trim();
1309
1345
  return code.replace(replacementRegex, (_, rawPayload) => {
1310
1346
  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}];`;
1347
+ if (payload.type === "preface") {
1348
+ return oneLine`
1349
+ namespace ${state.utilNsId.name} {
1350
+ export type UniqueKeyProbSegment = "__gts_unique_prob_seg__";
1351
+ export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
1352
+ }
1353
+ `;
1354
+ } else if (payload.type === "enterVMFromRoot") {
1355
+ return oneLine`
1356
+ type ${payload.defType} = (typeof ${payload.vm})[${NamedDefinition}];
1357
+ type ${payload.metaType} = ${payload.defType}[${Meta}];
1358
+ `;
1313
1359
  } 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}];`;
1360
+ return oneLine`
1361
+ type ${payload.defType} = ${payload.returnType} extends { namedDefinition: infer Def } ? Def : { ${Meta}: unknown };
1362
+ type ${payload.metaType} = ${payload.defType}[${Meta}];
1363
+ `;
1315
1364
  } else if (payload.type === "exitVM") {
1316
1365
  const lhs = `${payload.finalMetaType}_lhs`;
1317
1366
  const requiredAttrsNs = `${payload.finalMetaType}_rans`;
1318
1367
  const collectedAttrsExpr = `${payload.collectedAttrs.join(" | ")}`;
1319
1368
  const needleString = `"${requiredAttrsNs}_NeedleString" as any as "required attributes are missing"`;
1320
1369
  if (payload.errorLoc) {
1321
- state.additionalMappings.set(payload.errorLoc, needleString);
1370
+ state.extraMappings.set(payload.errorLoc, needleString);
1322
1371
  }
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});`;
1372
+ return oneLine`
1373
+ type ${payload.finalMetaType} = ${payload.metaType};
1374
+ let ${lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${Meta}>;
1375
+ type ${lhs} = typeof ${lhs};
1376
+ namespace ${requiredAttrsNs} {
1377
+ export type Collected = ${collectedAttrsExpr};
1378
+ export type Expected = { [K in keyof ${payload.defType}]: ${lhs}[K] extends { required(this: ${lhs}): true } ? K : never }[keyof ${payload.defType}];
1379
+ };
1380
+ ((_: ${requiredAttrsNs}.Expected extends ${requiredAttrsNs}.Collected ? string : ${requiredAttrsNs}.Expected) => 0)(${needleString});
1381
+ `;
1324
1382
  } else if (payload.type === "enterAttr") {
1325
- return `const ${payload.lhs}: { [${Meta.name}]: ${payload.metaType} } & Omit<${payload.defType}, ${Meta.name}> = 0 as any;`;
1383
+ const uniqueKeyLhs = `${payload.lhs}_uniqueKey_lhs`;
1384
+ const uniqueKey = `${payload.lhs}_uniqueKey`;
1385
+ const uniqueKeyForThis = `${payload.lhs}_uniqueKeyFor_${payload.lhs}`;
1386
+ const uniqueKeyHelperIntf = `${payload.defType}_uniqueKeyProbeHelper`;
1387
+ const omittedKeys = `${payload.lhs}_omittedKeys`;
1388
+ return oneLine`
1389
+ type ${uniqueKeyLhs} = {
1390
+ ${Meta}: ${payload.metaType};
1391
+ uniqueKey: ${payload.defType} extends { [${payload.attrName}]: { uniqueKey: infer UniqueKey } } ? UniqueKey : () => 0;
1392
+
1393
+ let ${uniqueKeyLhs}!: ${uniqueKeyLhs};
1394
+ let ${uniqueKey} = ${uniqueKeyLhs}.uniqueKey();
1395
+ type ${uniqueKey} = typeof ${uniqueKey};
1396
+ let ${uniqueKeyForThis}!: \`\${${uniqueKey}}\${${state.utilNsId.name}.UniqueKeyProbSegment}${payload.lhs}\`;
1397
+ interface ${uniqueKeyHelperIntf} {
1398
+ [${uniqueKeyForThis}]: 1;
1399
+ }
1400
+ type ${omittedKeys} = ${Meta} | (
1401
+ ${uniqueKey} extends 0
1402
+ ? never /* no unique requirement */
1403
+ : string extends keyof ${uniqueKeyHelperIntf}
1404
+ ? keyof ${payload.defType} /* too loose, disable all */
1405
+ : ${state.utilNsId.name}.UnionToIntersection<
1406
+ keyof ${uniqueKeyHelperIntf} & \`\${${uniqueKey}}\${${state.utilNsId.name}.UniqueKeyProbSegment}\${string}\`
1407
+ > extends never
1408
+ ? ${payload.attrName} /* have duplicate, disable this */
1409
+ : never
1410
+ );
1411
+ let ${payload.lhs}!: { ${Meta}: ${payload.metaType} } & Omit<${payload.defType}, ${omittedKeys}>;
1412
+ `;
1326
1413
  } else if (payload.type === "createBindingTyping") {
1327
1414
  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};`;
1415
+ return oneLine`
1416
+ type ${typingIdLhs} = {
1417
+ ${Meta}: ${payload.finalMetaType};
1418
+ as: ${payload.defType} extends { [${payload.attrName}]: { as: infer As } } ? As : unknown;
1419
+ };
1420
+ let ${typingIdLhs}!: ${typingIdLhs};
1421
+ let ${payload.typingId} = ${typingIdLhs}.as();
1422
+ type ${payload.typingId} = typeof ${payload.typingId};
1423
+ `;
1329
1424
  } 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}`;
1425
+ return oneLine`
1426
+ type ${payload.returnType} = typeof ${payload.returnType};
1427
+ type ${payload.newMetaType} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType}
1428
+ `;
1331
1429
  } else {
1332
1430
  return "";
1333
1431
  }
@@ -1344,59 +1442,7 @@ var ANY_INIT = {
1344
1442
  expression: { type: "Literal", value: 0 },
1345
1443
  typeAnnotation: ANY
1346
1444
  };
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
1445
  var enterVMFromRoot = (state) => {
1399
- emitPreface(state);
1400
1446
  let defTypeId = {
1401
1447
  type: "Identifier",
1402
1448
  name: `__gts_rootVmDefType_${state.idCounter++}`
@@ -1473,7 +1519,8 @@ var enterAttr = (state, attrName) => {
1473
1519
  type: "enterAttr",
1474
1520
  defType: defTypeId.name,
1475
1521
  metaType: metaTypeId.name,
1476
- lhs: lhsId.name
1522
+ lhs: lhsId.name,
1523
+ attrName
1477
1524
  }));
1478
1525
  return { lhsId };
1479
1526
  };
@@ -1539,8 +1586,7 @@ var gtsToTypingsWalker = {
1539
1586
  }
1540
1587
  }
1541
1588
  }
1542
- ],
1543
- leadingComments: extBinding.leadingComments
1589
+ ]
1544
1590
  };
1545
1591
  if (extBinding.export) {
1546
1592
  body.unshift({
@@ -1548,31 +1594,18 @@ var gtsToTypingsWalker = {
1548
1594
  declaration: varDecl,
1549
1595
  specifiers: [],
1550
1596
  source: null,
1551
- attributes: []
1597
+ attributes: [],
1598
+ leadingComments: extBinding.leadingComments
1552
1599
  });
1553
1600
  } else {
1601
+ varDecl.leadingComments = extBinding.leadingComments;
1554
1602
  body.unshift(varDecl);
1555
1603
  }
1556
1604
  }
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
1605
  if (state.hasQueryExpressions) {
1574
1606
  body.unshift({
1575
1607
  type: "ImportDeclaration",
1608
+ diagnosticsOnTop: true,
1576
1609
  specifiers: [
1577
1610
  {
1578
1611
  type: "ImportDefaultSpecifier",
@@ -1586,6 +1619,23 @@ var gtsToTypingsWalker = {
1586
1619
  attributes: []
1587
1620
  });
1588
1621
  }
1622
+ body.unshift({
1623
+ type: "ImportDeclaration",
1624
+ diagnosticsOnTop: true,
1625
+ specifiers: [
1626
+ {
1627
+ type: "ImportDefaultSpecifier",
1628
+ local: state.rootVmId
1629
+ }
1630
+ ],
1631
+ source: {
1632
+ type: "Literal",
1633
+ value: `${state.providerImportSource}/vm`
1634
+ },
1635
+ attributes: []
1636
+ }, createReplacementHolder(state, {
1637
+ type: "preface"
1638
+ }));
1589
1639
  return {
1590
1640
  ...node,
1591
1641
  body
@@ -1600,15 +1650,18 @@ var gtsToTypingsWalker = {
1600
1650
  GTSNamedAttributeDefinition(node, { visit, state }) {
1601
1651
  const { name, body, bindingName } = node;
1602
1652
  const attrName = JSON.stringify(name.type === "Literal" ? String(name.value) : name.name);
1653
+ const attributeNameToken = state.leafTokens.find((t) => t.loc === name.loc);
1654
+ if (attributeNameToken) {
1655
+ attributeNameToken.sourceLengthOffset = 1;
1656
+ }
1603
1657
  const { lhsId } = enterAttr(state, attrName);
1658
+ state.extraMappings.set(`${name.loc?.start.line}:${name.loc?.start.column}`, `${lhsId.name}${name.type === "Literal" ? `[` : `.`}`);
1604
1659
  const positionals = body.positionalAttributes.attributes.map((attr) => {
1605
1660
  if (attr.type === "Identifier" && /^[a-z_]/.test(attr.name)) {
1606
1661
  const token = state.leafTokens.find((t) => t.loc === attr.loc);
1607
1662
  if (token) {
1608
- token.locationAdjustment = {
1609
- startOffset: 1,
1610
- generatedLength: attr.name.length + 2
1611
- };
1663
+ token.generatedStartOffset = 1;
1664
+ token.generatedLength = attr.name.length + 2;
1612
1665
  }
1613
1666
  return {
1614
1667
  type: "Literal",
@@ -1684,7 +1737,11 @@ var gtsToTypingsWalker = {
1684
1737
  visit(attr);
1685
1738
  }
1686
1739
  if (node.directAction) {
1687
- const { lhsId } = enterAttr(state, state.ActionId.name);
1740
+ const attrName = JSON.stringify(state.ActionLit.value);
1741
+ const { lhsId } = enterAttr(state, attrName);
1742
+ const actionNotExistsReplacementStr = `${lhsId.name}[${attrName}]`;
1743
+ const actionNotExistsErrorLoc = `${node.directAction.loc?.start.line}:${node.directAction.loc?.start.column}`;
1744
+ state.extraMappings.set(actionNotExistsErrorLoc, actionNotExistsReplacementStr);
1688
1745
  const fn = {
1689
1746
  type: "ArrowFunctionExpression",
1690
1747
  params: state.shortcutFunctionParameters,
@@ -1711,7 +1768,7 @@ var gtsToTypingsWalker = {
1711
1768
  callee: {
1712
1769
  type: "MemberExpression",
1713
1770
  object: lhsId,
1714
- property: state.ActionId,
1771
+ property: state.ActionLit,
1715
1772
  computed: true,
1716
1773
  optional: false
1717
1774
  },
@@ -1810,8 +1867,7 @@ function buildSrcToGenMap(source_map, line_offsets, generated_code) {
1810
1867
  function getGeneratedPosition(src_line, src_column, srcToGenMap) {
1811
1868
  const key = `${src_line}:${src_column}`;
1812
1869
  const positions = srcToGenMap.get(key);
1813
- if (!positions || positions.length === 0) {}
1814
- return positions?.[0];
1870
+ return positions || [];
1815
1871
  }
1816
1872
  function createLineOffsets(content) {
1817
1873
  const lines = content.split(`
@@ -1828,39 +1884,41 @@ function locToOffset(line, column, line_offsets) {
1828
1884
  if (line < 1 || line > line_offsets.length) {}
1829
1885
  return line_offsets[line - 1] + column;
1830
1886
  }
1831
- function convertToVolarMappings(generated, source, sourceMap, tokens, additionalMappings) {
1887
+ function convertToVolarMappings(generated, source, sourceMap, tokens, extraMappings) {
1832
1888
  const sourceLineOffsets = createLineOffsets(source);
1833
1889
  const generatedLineOffsets = createLineOffsets(generated);
1834
1890
  const srcToGenMap = buildSrcToGenMap(sourceMap, generatedLineOffsets, generated);
1835
1891
  const mappings = [];
1836
1892
  for (const token of tokens) {
1837
1893
  let sourceStart = locToOffset(token.loc.start.line, token.loc.start.column, sourceLineOffsets);
1894
+ sourceStart += token.sourceStartOffset ?? 0;
1838
1895
  const sourceEnd = locToOffset(token.loc.end.line, token.loc.end.column, sourceLineOffsets);
1839
1896
  let sourceLength = token.sourceLength ?? sourceEnd - sourceStart;
1840
- const genLineCol = getGeneratedPosition(token.loc.start.line, token.loc.start.column, srcToGenMap);
1897
+ sourceLength += token.sourceLengthOffset ?? 0;
1898
+ const [genLineCol] = getGeneratedPosition(token.loc.start.line, token.loc.start.column, srcToGenMap);
1841
1899
  if (!genLineCol) {
1842
1900
  continue;
1843
1901
  }
1844
1902
  let genStart = locToOffset(genLineCol.line, genLineCol.column, generatedLineOffsets);
1845
- if (token.locationAdjustment) {
1903
+ if (token.isDummy) {
1904
+ while (sourceStart > 0 && /\s/.test(source[sourceStart - 1])) {
1905
+ sourceStart--;
1906
+ sourceLength++;
1907
+ }
1908
+ }
1909
+ const generatedLength = token.generatedLength ?? sourceLength;
1910
+ if (typeof token.generatedStartOffset === "number" && token.generatedStartOffset > 0) {
1846
1911
  mappings.push({
1847
1912
  sourceOffsets: [sourceStart],
1848
1913
  generatedOffsets: [genStart],
1849
1914
  lengths: [0],
1850
- generatedLengths: [token.locationAdjustment.generatedLength],
1915
+ generatedLengths: [generatedLength],
1851
1916
  data: {
1852
1917
  verification: true
1853
1918
  }
1854
1919
  });
1855
- genStart += token.locationAdjustment.startOffset;
1920
+ genStart += token.generatedStartOffset;
1856
1921
  }
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
1922
  mappings.push({
1865
1923
  sourceOffsets: [sourceStart],
1866
1924
  generatedOffsets: [genStart],
@@ -1869,7 +1927,20 @@ function convertToVolarMappings(generated, source, sourceMap, tokens, additional
1869
1927
  data: DEFAULT_VOLAR_MAPPING_DATA
1870
1928
  });
1871
1929
  }
1872
- for (const [loc, codeSnippet] of additionalMappings) {
1930
+ const locMapsToTop = getGeneratedPosition(1, 0, srcToGenMap);
1931
+ for (const loc of locMapsToTop) {
1932
+ const offset = locToOffset(loc.line, loc.column, generatedLineOffsets);
1933
+ mappings.push({
1934
+ sourceOffsets: [0],
1935
+ generatedOffsets: [offset],
1936
+ lengths: [0],
1937
+ generatedLengths: [0],
1938
+ data: {
1939
+ verification: true
1940
+ }
1941
+ });
1942
+ }
1943
+ for (const [loc, codeSnippet] of extraMappings) {
1873
1944
  const generatedStart = generated.indexOf(codeSnippet);
1874
1945
  if (generatedStart === -1) {
1875
1946
  continue;
@@ -1912,26 +1983,138 @@ function isLeafNode(node) {
1912
1983
  return true;
1913
1984
  }
1914
1985
  function collectLeafTokens(ast) {
1915
- const tokens = [];
1916
- walk4(ast, tokens, {
1917
- _(node, { state, next }) {
1986
+ const state = {
1987
+ tokens: []
1988
+ };
1989
+ walk4(ast, state, {
1990
+ _(node, { state: state2, next }) {
1918
1991
  if (isLeafNode(node) && node.loc) {
1919
1992
  const token = {
1920
1993
  loc: node.loc
1921
1994
  };
1922
- if (node.isDummy) {
1995
+ if ("isDummy" in node && node.isDummy) {
1923
1996
  token.isDummy = true;
1924
1997
  token.sourceLength = 0;
1925
1998
  token.generatedLength = 1;
1926
1999
  }
1927
- state.push(token);
2000
+ state2.tokens.push(token);
2001
+ }
2002
+ next();
2003
+ },
2004
+ NewExpression(node, { state: state2, next }) {
2005
+ const lParenLoc = node.lParenLoc;
2006
+ if (lParenLoc) {
2007
+ state2.tokens.push({
2008
+ loc: lParenLoc
2009
+ });
2010
+ }
2011
+ next();
2012
+ },
2013
+ CallExpression(node, { state: state2, next }) {
2014
+ const lParenLoc = node.lParenLoc;
2015
+ if (lParenLoc) {
2016
+ state2.tokens.push({
2017
+ loc: lParenLoc
2018
+ });
1928
2019
  }
1929
2020
  next();
1930
2021
  }
1931
2022
  });
1932
- return tokens;
2023
+ return state.tokens;
1933
2024
  }
1934
2025
 
2026
+ // packages/transpiler/src/transform/volar/printer.ts
2027
+ import tsPrinter from "esrap/languages/ts";
2028
+ var printer = tsPrinter({
2029
+ getLeadingComments: (node) => node.leadingComments,
2030
+ getTrailingComments: (node) => node.trailingComments
2031
+ });
2032
+ var prevIdentifier = printer.Identifier;
2033
+ printer.Identifier = function(node, context) {
2034
+ if (node.isDummy) {
2035
+ const text = Reflect.get(node, "lastArg") ? "," : "";
2036
+ context.write(text, node);
2037
+ } else {
2038
+ prevIdentifier(node, context);
2039
+ }
2040
+ };
2041
+ var prevCallNewExpression = printer.CallExpression;
2042
+ var newCallNewExpression = function(node, context) {
2043
+ const lastArg = node.arguments.at(-1);
2044
+ if (lastArg) {
2045
+ Reflect.set(lastArg, "lastArg", true);
2046
+ }
2047
+ if (!node.lParenLoc) {
2048
+ return prevCallNewExpression(node, context);
2049
+ }
2050
+ let hasDeferredWrite = false;
2051
+ let interceptionDone = false;
2052
+ const lParenFakeNode = {
2053
+ loc: node.lParenLoc
2054
+ };
2055
+ const patchedWrite = (text, node2) => {
2056
+ if (text === "(") {
2057
+ hasDeferredWrite = true;
2058
+ } else {
2059
+ context.write(text, node2);
2060
+ }
2061
+ };
2062
+ const patchedVisit = (node2) => {
2063
+ if (hasDeferredWrite) {
2064
+ context.write("(");
2065
+ }
2066
+ return context.visit(node2);
2067
+ };
2068
+ const patchedAppend = (subcontext) => {
2069
+ if (hasDeferredWrite) {
2070
+ context.write("(", lParenFakeNode);
2071
+ interceptionDone = true;
2072
+ }
2073
+ return context.append(subcontext);
2074
+ };
2075
+ const proxiedContext = new Proxy(context, {
2076
+ get(target, prop) {
2077
+ if (!interceptionDone) {
2078
+ if (prop === "write") {
2079
+ return patchedWrite;
2080
+ }
2081
+ if (prop === "visit") {
2082
+ return patchedVisit;
2083
+ }
2084
+ if (prop === "append") {
2085
+ return patchedAppend;
2086
+ }
2087
+ }
2088
+ const value = Reflect.get(target, prop);
2089
+ if (typeof value === "function") {
2090
+ return value.bind(target);
2091
+ }
2092
+ return value;
2093
+ }
2094
+ });
2095
+ return prevCallNewExpression(node, proxiedContext);
2096
+ };
2097
+ printer.CallExpression = newCallNewExpression;
2098
+ printer.NewExpression = newCallNewExpression;
2099
+ var prevWildcard = printer._;
2100
+ printer._ = (node, context, visit) => {
2101
+ const contextProto = Object.getPrototypeOf(context);
2102
+ const prevContextWrite = contextProto.write;
2103
+ if ("diagnosticsOnTop" in node && node.diagnosticsOnTop) {
2104
+ contextProto.write = function(text, node2) {
2105
+ node2 ??= {};
2106
+ node2.loc ??= {
2107
+ start: { line: 1, column: 0 },
2108
+ end: { line: 1, column: 0 }
2109
+ };
2110
+ return prevContextWrite.call(this, text, node2);
2111
+ };
2112
+ }
2113
+ prevWildcard(node, context, visit);
2114
+ contextProto.write = prevContextWrite;
2115
+ };
2116
+ var patchedPrinter = printer;
2117
+
1935
2118
  // packages/transpiler/src/transform/volar/index.ts
1936
2119
  function gtsToTypings(ast, option) {
1937
2120
  const state = {
@@ -1939,34 +2122,20 @@ function gtsToTypings(ast, option) {
1939
2122
  leafTokens: option.leafTokens,
1940
2123
  idCounter: 0,
1941
2124
  typingPendingStatements: [],
1942
- prefaceInserted: false,
1943
- rootVmId: { type: "Identifier", name: "__root_vm" },
2125
+ rootVmId: { type: "Identifier", name: "__gts_root_vm" },
2126
+ utilNsId: { type: "Identifier", name: "__gts_util" },
1944
2127
  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
- },
2128
+ MetaLit: { type: "Literal", value: "~meta" },
2129
+ NamedDefinitionLit: { type: "Literal", value: "~namedDefinition" },
1949
2130
  defineLeadingComments: [],
1950
2131
  vmDefTypeIdStack: [],
1951
2132
  metaTypeIdStack: [],
1952
2133
  finalMetaTypeIdStack: [],
1953
2134
  attrsOfCurrentVm: [],
1954
- additionalMappings: option.additionalMappings
2135
+ extraMappings: option.extraMappings
1955
2136
  };
1956
2137
  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, {
2138
+ const { code, map } = print(newAst, patchedPrinter, {
1970
2139
  indent: " "
1971
2140
  });
1972
2141
  return {
@@ -1976,13 +2145,13 @@ function gtsToTypings(ast, option) {
1976
2145
  }
1977
2146
  function transformForVolar(ast, option, sourceInfo) {
1978
2147
  const tokens = collectLeafTokens(ast);
1979
- const additionalMappings = new Map;
2148
+ const extraMappings = new Map;
1980
2149
  const { code, sourceMap } = gtsToTypings(ast, {
1981
2150
  ...option,
1982
2151
  leafTokens: tokens,
1983
- additionalMappings
2152
+ extraMappings
1984
2153
  });
1985
- const volarMappings = convertToVolarMappings(code, sourceInfo.content, sourceMap, tokens, additionalMappings);
2154
+ const volarMappings = convertToVolarMappings(code, sourceInfo.content, sourceMap, tokens, extraMappings);
1986
2155
  return {
1987
2156
  code,
1988
2157
  mappings: volarMappings
@@ -2004,7 +2173,77 @@ function transform(ast, option = {}, sourceInfo = {}) {
2004
2173
  };
2005
2174
  }
2006
2175
  // packages/transpiler/src/config.ts
2007
- import path from "node:path";
2176
+ var path = globalThis.require ? globalThis.require("node:path") : {
2177
+ isAbsolute(filePath) {
2178
+ return filePath.startsWith("/");
2179
+ },
2180
+ dirname(filePath) {
2181
+ if (!filePath) {
2182
+ return ".";
2183
+ }
2184
+ const normalized = normalizeSlashes(filePath);
2185
+ if (normalized === "/") {
2186
+ return "/";
2187
+ }
2188
+ const trimmed = normalized.length > 1 && normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
2189
+ const idx = trimmed.lastIndexOf("/");
2190
+ if (idx < 0) {
2191
+ return ".";
2192
+ }
2193
+ if (idx === 0) {
2194
+ return "/";
2195
+ }
2196
+ return trimmed.slice(0, idx);
2197
+ },
2198
+ resolve(...segments) {
2199
+ if (segments.length === 0) {
2200
+ return ".";
2201
+ }
2202
+ let resolved = "";
2203
+ for (let i = segments.length - 1;i >= 0; i--) {
2204
+ const segment = segments[i];
2205
+ if (!segment) {
2206
+ continue;
2207
+ }
2208
+ if (resolved) {
2209
+ resolved = `${segment}/${resolved}`;
2210
+ } else {
2211
+ resolved = segment;
2212
+ }
2213
+ if (path.isAbsolute(segment)) {
2214
+ break;
2215
+ }
2216
+ }
2217
+ return normalizeResolvedPath(resolved || ".");
2218
+ }
2219
+ };
2220
+ function normalizeSlashes(filePath) {
2221
+ return filePath.replace(/\\+/g, "/");
2222
+ }
2223
+ function normalizeResolvedPath(filePath) {
2224
+ const normalized = normalizeSlashes(filePath);
2225
+ const isAbsolute = normalized.startsWith("/");
2226
+ const parts = normalized.split("/");
2227
+ const stack = [];
2228
+ for (const part of parts) {
2229
+ if (!part || part === ".") {
2230
+ continue;
2231
+ }
2232
+ if (part === "..") {
2233
+ if (stack.length > 0 && stack[stack.length - 1] !== "..") {
2234
+ stack.pop();
2235
+ } else if (!isAbsolute) {
2236
+ stack.push("..");
2237
+ }
2238
+ continue;
2239
+ }
2240
+ stack.push(part);
2241
+ }
2242
+ if (isAbsolute) {
2243
+ return `/${stack.join("/")}` || "/";
2244
+ }
2245
+ return stack.join("/") || ".";
2246
+ }
2008
2247
  var DEFAULT_GTS_CONFIG = {
2009
2248
  runtimeImportSource: "@gi-tcg/gts-runtime",
2010
2249
  providerImportSource: "@gi-tcg/core/gts",
@@ -2060,7 +2299,7 @@ function normalizeStartDir(sourceFile, cwd) {
2060
2299
  function* findNearestPackageConfig(readFileFn, startDir, stopDir) {
2061
2300
  let currentDir = startDir;
2062
2301
  while (true) {
2063
- const pkgPath = path.join(currentDir, "package.json");
2302
+ const pkgPath = path.resolve(currentDir, "package.json");
2064
2303
  const config = yield* readPackageConfig(readFileFn, pkgPath);
2065
2304
  if (config) {
2066
2305
  return config;
@@ -2095,7 +2334,9 @@ function transpile(source, filename, option) {
2095
2334
  });
2096
2335
  }
2097
2336
  function transpileForVolar(source, filename, option) {
2098
- const ast = parseLoose(source);
2337
+ const ast = parseLoose(source, {
2338
+ recordCallLParens: true
2339
+ });
2099
2340
  return transformForVolar(ast, option, {
2100
2341
  content: source,
2101
2342
  filename
@@ -2106,5 +2347,6 @@ export {
2106
2347
  transpile,
2107
2348
  resolveGtsConfigSync,
2108
2349
  resolveGtsConfig,
2350
+ path,
2109
2351
  GtsTranspilerError
2110
2352
  };