@gi-tcg/gts-transpiler 0.6.8 → 0.7.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
@@ -185,8 +185,10 @@ function gtsPlugin(options = {}) {
185
185
  if (this.type === tokTypes.braceL) break;
186
186
  if (this.type === tokTypes.semi || this.canInsertSemicolon()) break;
187
187
  if (this.isContextual("as")) break;
188
- if (!first) this.expect(tokTypes.comma);
189
- else first = false;
188
+ if (!first) {
189
+ this.expect(tokTypes.comma);
190
+ if (this.type === tokTypes.braceL) break;
191
+ } else first = false;
190
192
  node.attributes.push(this.gts_parseAttributeExpression());
191
193
  }
192
194
  return this.finishNode(node, "GTSPositionalAttributeList");
@@ -227,7 +229,7 @@ function gtsPlugin(options = {}) {
227
229
  this.next();
228
230
  return this.gts_parseShortcutFunction();
229
231
  }
230
- if (this.gtsOptions.allowEmptyPositionalAttribute && (this.type === tokTypes.comma || this.type === tokTypes.braceR || this.type === tokTypes.semi || this.canInsertSemicolon() || this.isContextual("as"))) {
232
+ if (this.gtsOptions.allowEmptyPositionalAttribute && (this.type === tokTypes.comma || this.type === tokTypes.braceR || this.type === tokTypes.semi || this.isContextual("as"))) {
231
233
  const dummy = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
232
234
  dummy.name = "✖";
233
235
  dummy.isDummy = true;
@@ -388,7 +390,11 @@ function getCommentHandlers(source, comments, index = 0) {
388
390
  if (node.innerComments && node.innerComments.length > 0) return;
389
391
  }
390
392
  const parent = path.at(-1);
391
- if (parent === void 0 || node.end !== parent.end) {
393
+ if (parent === void 0) {
394
+ while (comments.length) (node.leadingComments ||= []).push(comments.shift());
395
+ return;
396
+ }
397
+ if (node.end !== parent.end) {
392
398
  const slice = source.slice(node.end, comments[0].start);
393
399
  let is_last_in_array = false;
394
400
  /** @type {(AST.Node | null)[] | null} */
@@ -1253,8 +1259,8 @@ function applyReplacements(state, code, mappings) {
1253
1259
  type ${rewrittenMeta} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType};
1254
1260
  let ${mergeFn}!: ${payload.defType} extends {
1255
1261
  [${payload.attrName}]: { mergeMeta: infer M }
1256
- } ? M : null;
1257
- let ${mergeFnRet} = ${mergeFn}?.(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
1262
+ } ? M : <const T>(x: T, y: unknown) => T;
1263
+ let ${mergeFnRet} = ${mergeFn}(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
1258
1264
  type ${payload.newMetaType} = [typeof ${mergeFn}] extends [null] ? ${rewrittenMeta} : typeof ${mergeFnRet};
1259
1265
  `;
1260
1266
  } else replacement = "";
@@ -1399,7 +1405,6 @@ const insertHintStatement = (state, whiteSpaceStart, whiteSpaceEnd) => {
1399
1405
  whiteSpaceStart,
1400
1406
  whiteSpaceEnd
1401
1407
  });
1402
- `${state.idCounter++}`;
1403
1408
  };
1404
1409
  const gtsToTypingsWalker = {
1405
1410
  Program(node, { state, visit }) {
@@ -1795,7 +1800,7 @@ function getPrintOptions(source, state) {
1795
1800
  context.writeNode(node.object);
1796
1801
  context.write(".");
1797
1802
  context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
1798
- context.write(";");
1803
+ context.write("// @ts-ignore\nωAttrNameHint;");
1799
1804
  },
1800
1805
  ErrorStatement(node, context) {
1801
1806
  if (node.range) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gi-tcg/gts-transpiler",
3
- "version": "0.6.8",
3
+ "version": "0.7.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/piovium/gts.git"
@@ -184,9 +184,21 @@ export function getCommentHandlers(source, comments, index = 0) {
184
184
  }
185
185
  }
186
186
 
187
- const parent = /** @type {AST.Node & AST.NodeWithLocation} */ (path.at(-1));
187
+ const parent = /** @type {AST.Node & AST.NodeWithLocation | undefined} */ (path.at(-1));
188
+
189
+ // A comment-only file leaves Program as the sole visited node. There is
190
+ // no parent to use for sibling-based attachment, so retain the remaining
191
+ // comments on Program itself.
192
+ if (parent === undefined) {
193
+ while (comments.length) {
194
+ (node.leadingComments ||= []).push(
195
+ /** @type {AST.CommentWithLocation} */ (comments.shift()),
196
+ );
197
+ }
198
+ return;
199
+ }
188
200
 
189
- if (parent === undefined || node.end !== parent.end) {
201
+ if (node.end !== parent.end) {
190
202
  const slice = source.slice(node.end, comments[0].start);
191
203
 
192
204
  // Check if this node is the last item in an array-like structure
@@ -408,4 +420,4 @@ export function getCommentHandlers(source, comments, index = 0) {
408
420
  });
409
421
  },
410
422
  };
411
- }
423
+ }
@@ -20,6 +20,7 @@ AttributeName:
20
20
 
21
21
  AttributeBody:
22
22
  PositionalAttributeList? NamedAttributeBlock?
23
+ PositionalAttributeList "," NamedAttributeBlock
23
24
 
24
25
  AttributeBindingClause:
25
26
  "as" BindingAccessModifier? Identifier
@@ -44,7 +45,7 @@ AttributeExpression:
44
45
  ":" ShortcutFunction
45
46
  # Intentionally disable object literal, for distinction to named attribute block
46
47
  # foo bar { baz = 1 };
47
- # foo bar, { baz: 1 }; // If allowed, hard to distinguish
48
+ # foo bar, { baz: 1 }; // Named attribute block
48
49
  # foo bar, ({ baz: 1 }); // OK
49
50
  [lookahead != "{"] CallExpression OptionalChain?
50
51
  [lookahead != "{"] MemberExpression OptionalChain?
@@ -181,6 +182,10 @@ export function gtsPlugin(options: GtsPluginOption = {}) {
181
182
  }
182
183
  if (!first) {
183
184
  this.expect(tokTypes.comma);
185
+ // A trailing comma is only valid before a named attribute block.
186
+ if (this.type === tokTypes.braceL) {
187
+ break;
188
+ }
184
189
  } else {
185
190
  first = false;
186
191
  }
@@ -247,7 +252,6 @@ export function gtsPlugin(options: GtsPluginOption = {}) {
247
252
  (this.type === tokTypes.comma ||
248
253
  this.type === tokTypes.braceR ||
249
254
  this.type === tokTypes.semi ||
250
- this.canInsertSemicolon() ||
251
255
  this.isContextual("as"))
252
256
  ) {
253
257
  // Allow omitting the attribute expression for language tooling
@@ -236,7 +236,7 @@ export function getPrintOptions(
236
236
  context.writeNode(node.object as EspolarAST.Node);
237
237
  context.write(".");
238
238
  context.writeSource(node.whiteSpaceStart, node.whiteSpaceEnd);
239
- context.write(";");
239
+ context.write("// @ts-ignore\nωAttrNameHint;");
240
240
  },
241
241
  ErrorStatement(node: any, context: PrinterContext<CodeInformation>) {
242
242
  if (node.range) {
@@ -204,8 +204,8 @@ export function applyReplacements(
204
204
  type ${rewrittenMeta} = ${payload.returnType} extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : ${payload.oldMetaType};
205
205
  let ${mergeFn}!: ${payload.defType} extends {
206
206
  [${payload.attrName}]: { mergeMeta: infer M }
207
- } ? M : null;
208
- let ${mergeFnRet} = ${mergeFn}?.(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
207
+ } ? M : <const T>(x: T, y: unknown) => T;
208
+ let ${mergeFnRet} = ${mergeFn}(null! as ${rewrittenMeta}, null! as ${payload.innerMetaType});
209
209
  type ${payload.newMetaType} = [typeof ${mergeFn}] extends [null] ? ${rewrittenMeta} : typeof ${mergeFnRet};
210
210
  `;
211
211
  } else {
@@ -290,10 +290,6 @@ const insertHintStatement = (
290
290
  whiteSpaceStart,
291
291
  whiteSpaceEnd,
292
292
  } satisfies GTSAttributeNameHintStatement as any);
293
- const returnValue: Identifier = {
294
- type: "Identifier",
295
- name: `__gts_attrRet_hint_${state.idCounter++}`,
296
- };
297
293
  // do NOT exitAttr (rewrite meta) since hint is a incomplete structure
298
294
  };
299
295