@typespec/prettier-plugin-typespec 0.52.0-dev.1 → 0.52.0-dev.3

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
@@ -97,15 +97,17 @@ var SyntaxKind;
97
97
  SyntaxKind[SyntaxKind["ProjectionDecoratorReferenceExpression"] = 87] = "ProjectionDecoratorReferenceExpression";
98
98
  SyntaxKind[SyntaxKind["Return"] = 88] = "Return";
99
99
  SyntaxKind[SyntaxKind["JsNamespaceDeclaration"] = 89] = "JsNamespaceDeclaration";
100
+ SyntaxKind[SyntaxKind["TemplateArgument"] = 90] = "TemplateArgument";
100
101
  })(SyntaxKind || (SyntaxKind = {}));
101
102
  var IdentifierKind;
102
103
  (function (IdentifierKind) {
103
104
  IdentifierKind[IdentifierKind["TypeReference"] = 0] = "TypeReference";
104
- IdentifierKind[IdentifierKind["Decorator"] = 1] = "Decorator";
105
- IdentifierKind[IdentifierKind["Function"] = 2] = "Function";
106
- IdentifierKind[IdentifierKind["Using"] = 3] = "Using";
107
- IdentifierKind[IdentifierKind["Declaration"] = 4] = "Declaration";
108
- IdentifierKind[IdentifierKind["Other"] = 5] = "Other";
105
+ IdentifierKind[IdentifierKind["TemplateArgument"] = 1] = "TemplateArgument";
106
+ IdentifierKind[IdentifierKind["Decorator"] = 2] = "Decorator";
107
+ IdentifierKind[IdentifierKind["Function"] = 3] = "Function";
108
+ IdentifierKind[IdentifierKind["Using"] = 4] = "Using";
109
+ IdentifierKind[IdentifierKind["Declaration"] = 5] = "Declaration";
110
+ IdentifierKind[IdentifierKind["Other"] = 6] = "Other";
109
111
  })(IdentifierKind || (IdentifierKind = {}));
110
112
  /** Used to explicitly specify that a diagnostic has no target. */
111
113
  const NoTarget = Symbol.for("NoTarget");
@@ -117,53 +119,6 @@ var ListenerFlow;
117
119
  ListenerFlow[ListenerFlow["NoRecursion"] = 1] = "NoRecursion";
118
120
  })(ListenerFlow || (ListenerFlow = {}));
119
121
 
120
- /**
121
- * Create a new diagnostics creator.
122
- * @param diagnostics Map of the potential diagnostics.
123
- * @param libraryName Optional name of the library if in the scope of a library.
124
- * @returns @see DiagnosticCreator
125
- */
126
- function createDiagnosticCreator(diagnostics, libraryName) {
127
- const errorMessage = libraryName
128
- ? `It must match one of the code defined in the library '${libraryName}'`
129
- : "It must match one of the code defined in the compiler.";
130
- function createDiagnostic(diagnostic) {
131
- var _a;
132
- const diagnosticDef = diagnostics[diagnostic.code];
133
- if (!diagnosticDef) {
134
- const codeStr = Object.keys(diagnostics)
135
- .map((x) => ` - ${x}`)
136
- .join("\n");
137
- const code = String(diagnostic.code);
138
- throw new Error(`Unexpected diagnostic code '${code}'. ${errorMessage}. Defined codes:\n${codeStr}`);
139
- }
140
- const message = diagnosticDef.messages[(_a = diagnostic.messageId) !== null && _a !== void 0 ? _a : "default"];
141
- if (!message) {
142
- const codeStr = Object.keys(diagnosticDef.messages)
143
- .map((x) => ` - ${x}`)
144
- .join("\n");
145
- const messageId = String(diagnostic.messageId);
146
- const code = String(diagnostic.code);
147
- throw new Error(`Unexpected message id '${messageId}'. ${errorMessage} for code '${code}'. Defined codes:\n${codeStr}`);
148
- }
149
- const messageStr = typeof message === "string" ? message : message(diagnostic.format);
150
- return {
151
- code: libraryName ? `${libraryName}/${String(diagnostic.code)}` : diagnostic.code.toString(),
152
- severity: diagnosticDef.severity,
153
- message: messageStr,
154
- target: diagnostic.target,
155
- };
156
- }
157
- function reportDiagnostic(program, diagnostic) {
158
- const diag = createDiagnostic(diagnostic);
159
- program.reportDiagnostic(diag);
160
- }
161
- return {
162
- diagnostics,
163
- createDiagnostic,
164
- reportDiagnostic,
165
- };
166
- }
167
122
  function createSourceFile(text, path) {
168
123
  let lineStarts = undefined;
169
124
  return {
@@ -328,10 +283,54 @@ function binarySearch(array, value) {
328
283
  return ~low;
329
284
  }
330
285
 
331
- const globalLibraryUrlsLoadedSym = Symbol.for("TYPESPEC_LIBRARY_URLS_LOADED");
332
- if (globalThis[globalLibraryUrlsLoadedSym] === undefined) {
333
- globalThis[globalLibraryUrlsLoadedSym] = new Set();
286
+ /**
287
+ * Create a new diagnostics creator.
288
+ * @param diagnostics Map of the potential diagnostics.
289
+ * @param libraryName Optional name of the library if in the scope of a library.
290
+ * @returns @see DiagnosticCreator
291
+ */
292
+ function createDiagnosticCreator(diagnostics, libraryName) {
293
+ const errorMessage = libraryName
294
+ ? `It must match one of the code defined in the library '${libraryName}'`
295
+ : "It must match one of the code defined in the compiler.";
296
+ function createDiagnostic(diagnostic) {
297
+ var _a;
298
+ const diagnosticDef = diagnostics[diagnostic.code];
299
+ if (!diagnosticDef) {
300
+ const codeStr = Object.keys(diagnostics)
301
+ .map((x) => ` - ${x}`)
302
+ .join("\n");
303
+ const code = String(diagnostic.code);
304
+ throw new Error(`Unexpected diagnostic code '${code}'. ${errorMessage}. Defined codes:\n${codeStr}`);
305
+ }
306
+ const message = diagnosticDef.messages[(_a = diagnostic.messageId) !== null && _a !== void 0 ? _a : "default"];
307
+ if (!message) {
308
+ const codeStr = Object.keys(diagnosticDef.messages)
309
+ .map((x) => ` - ${x}`)
310
+ .join("\n");
311
+ const messageId = String(diagnostic.messageId);
312
+ const code = String(diagnostic.code);
313
+ throw new Error(`Unexpected message id '${messageId}'. ${errorMessage} for code '${code}'. Defined codes:\n${codeStr}`);
314
+ }
315
+ const messageStr = typeof message === "string" ? message : message(diagnostic.format);
316
+ return {
317
+ code: libraryName ? `${libraryName}/${String(diagnostic.code)}` : diagnostic.code.toString(),
318
+ severity: diagnosticDef.severity,
319
+ message: messageStr,
320
+ target: diagnostic.target,
321
+ };
322
+ }
323
+ function reportDiagnostic(program, diagnostic) {
324
+ const diag = createDiagnostic(diagnostic);
325
+ program.reportDiagnostic(diag);
326
+ }
327
+ return {
328
+ diagnostics,
329
+ createDiagnostic,
330
+ reportDiagnostic,
331
+ };
334
332
  }
333
+
335
334
  function paramMessage(strings, ...keys) {
336
335
  const template = (dict) => {
337
336
  const result = [strings[0]];
@@ -544,6 +543,12 @@ const diagnostics = {
544
543
  default: "Required template parameters must not follow optional template parameters",
545
544
  },
546
545
  },
546
+ "invalid-template-argument-name": {
547
+ severity: "error",
548
+ messages: {
549
+ default: "Template parameter argument names must be valid, bare identifiers.",
550
+ },
551
+ },
547
552
  "invalid-template-default": {
548
553
  severity: "error",
549
554
  messages: {
@@ -603,8 +608,11 @@ const diagnostics = {
603
608
  messages: {
604
609
  default: "Invalid template arguments.",
605
610
  notTemplate: "Can't pass template arguments to non-templated type",
606
- tooFew: "Too few template arguments provided.",
607
611
  tooMany: "Too many template arguments provided.",
612
+ unknownName: paramMessage `No parameter named '${"name"}' exists in the target template.`,
613
+ positionalAfterNamed: "Positional template arguments cannot follow named arguments in the same argument list.",
614
+ missing: paramMessage `Template argument '${"name"}' is required and not specified.`,
615
+ specifiedAgain: paramMessage `Cannot specify template argument '${"name"}' again.`,
608
616
  },
609
617
  },
610
618
  "intersect-non-model": {
@@ -1080,6 +1088,25 @@ const diagnostics = {
1080
1088
  wrongNumericEncodingType: paramMessage `Encoding '${"encoding"}' on type '${"type"}' is expected to be serialized as '${"expected"}' but got '${"actual"}'. Set '@encode' 2nd parameter to be of type ${"expected"}. e.g. '@encode("${"encoding"}", int32)'`,
1081
1089
  },
1082
1090
  },
1091
+ "invalid-mime-type": {
1092
+ severity: "error",
1093
+ messages: {
1094
+ default: paramMessage `Invalid mime type '${"mimeType"}'`,
1095
+ },
1096
+ },
1097
+ "no-mime-type-suffix": {
1098
+ severity: "error",
1099
+ messages: {
1100
+ default: paramMessage `Cannot use mime type '${"mimeType"}' with suffix '${"suffix"}'. Use a simple mime \`type/subtype\` instead.`,
1101
+ },
1102
+ },
1103
+ "encoded-name-conflict": {
1104
+ severity: "error",
1105
+ messages: {
1106
+ default: paramMessage `Encoded name '${"name"}' conflicts with existing member name for mime type '${"mimeType"}'`,
1107
+ duplicate: paramMessage `Same encoded name '${"name"}' is used for 2 members '${"mimeType"}'`,
1108
+ },
1109
+ },
1083
1110
  /**
1084
1111
  * Service
1085
1112
  */
@@ -4659,6 +4686,8 @@ path, options, print) {
4659
4686
  return printUnionVariant(path, options, print);
4660
4687
  case SyntaxKind.TypeReference:
4661
4688
  return printTypeReference(path, options, print);
4689
+ case SyntaxKind.TemplateArgument:
4690
+ return printTemplateArgument(path, options, print);
4662
4691
  case SyntaxKind.ValueOfExpression:
4663
4692
  return printValueOfExpression(path, options, print);
4664
4693
  case SyntaxKind.TemplateParameterDeclaration:
@@ -5407,6 +5436,16 @@ function printTypeReference(path, options, print) {
5407
5436
  const template = printTemplateParameters(path, options, print, "arguments");
5408
5437
  return [type, template];
5409
5438
  }
5439
+ function printTemplateArgument(path, _options, print) {
5440
+ if (path.getValue().name !== undefined) {
5441
+ const name = path.call(print, "name");
5442
+ const argument = path.call(print, "argument");
5443
+ return group([name, " = ", argument]);
5444
+ }
5445
+ else {
5446
+ return path.call(print, "argument");
5447
+ }
5448
+ }
5410
5449
  function printValueOfExpression(path, options, print) {
5411
5450
  const type = path.call(print, "target");
5412
5451
  return ["valueof ", type];
@@ -6493,7 +6532,7 @@ function createParser(code, options = {}) {
6493
6532
  function parseReferenceExpression(message) {
6494
6533
  const pos = tokenPos();
6495
6534
  const target = parseIdentifierOrMemberExpression(message);
6496
- const args = parseOptionalList(ListKind.TemplateArguments, parseExpression);
6535
+ const args = parseOptionalList(ListKind.TemplateArguments, parseTemplateArgument);
6497
6536
  return {
6498
6537
  kind: SyntaxKind.TypeReference,
6499
6538
  target,
@@ -6501,6 +6540,41 @@ function createParser(code, options = {}) {
6501
6540
  ...finishNode(pos),
6502
6541
  };
6503
6542
  }
6543
+ function parseTemplateArgument() {
6544
+ const pos = tokenPos();
6545
+ // Early error recovery for missing identifier followed by eq
6546
+ if (token() === Token.Equals) {
6547
+ error({ code: "token-expected", messageId: "identifier" });
6548
+ nextToken();
6549
+ return {
6550
+ kind: SyntaxKind.TemplateArgument,
6551
+ name: createMissingIdentifier(),
6552
+ argument: parseExpression(),
6553
+ ...finishNode(pos),
6554
+ };
6555
+ }
6556
+ const expr = parseExpression();
6557
+ const eq = parseOptional(Token.Equals);
6558
+ if (eq) {
6559
+ const isBareIdentifier = exprIsBareIdentifier(expr);
6560
+ if (!isBareIdentifier) {
6561
+ error({ code: "invalid-template-argument-name", target: expr });
6562
+ }
6563
+ return {
6564
+ kind: SyntaxKind.TemplateArgument,
6565
+ name: isBareIdentifier ? expr.target : createMissingIdentifier(),
6566
+ argument: parseExpression(),
6567
+ ...finishNode(pos),
6568
+ };
6569
+ }
6570
+ else {
6571
+ return {
6572
+ kind: SyntaxKind.TemplateArgument,
6573
+ argument: expr,
6574
+ ...finishNode(pos),
6575
+ };
6576
+ }
6577
+ }
6504
6578
  function parseAugmentDecorator() {
6505
6579
  const pos = tokenPos();
6506
6580
  parseExpected(Token.AtAt);
@@ -6932,7 +7006,7 @@ function createParser(code, options = {}) {
6932
7006
  target = {
6933
7007
  kind: SyntaxKind.FunctionParameter,
6934
7008
  id: createMissingIdentifier(),
6935
- type: createMissingIdentifier(),
7009
+ type: createMissingTypeReference(),
6936
7010
  optional: false,
6937
7011
  rest: false,
6938
7012
  ...finishNode(pos),
@@ -7842,6 +7916,15 @@ function createParser(code, options = {}) {
7842
7916
  ...finishNode(pos),
7843
7917
  };
7844
7918
  }
7919
+ function createMissingTypeReference() {
7920
+ const pos = tokenPos();
7921
+ return {
7922
+ kind: SyntaxKind.TypeReference,
7923
+ target: createMissingIdentifier(),
7924
+ arguments: [],
7925
+ ...finishNode(pos),
7926
+ };
7927
+ }
7845
7928
  function finishNode(pos) {
7846
7929
  const flags = parseErrorInNextFinishedNode ? 2 /* NodeFlags.ThisNodeHasError */ : 0 /* NodeFlags.None */;
7847
7930
  parseErrorInNextFinishedNode = false;
@@ -8141,6 +8224,11 @@ function createParser(code, options = {}) {
8141
8224
  : undefined;
8142
8225
  }
8143
8226
  }
8227
+ function exprIsBareIdentifier(expr) {
8228
+ return (expr.kind === SyntaxKind.TypeReference &&
8229
+ expr.target.kind === SyntaxKind.Identifier &&
8230
+ expr.arguments.length === 0);
8231
+ }
8144
8232
  function visitChildren(node, cb) {
8145
8233
  if (node.directives) {
8146
8234
  const result = visitEach(cb, node.directives);
@@ -8296,6 +8384,8 @@ function visitChildren(node, cb) {
8296
8384
  return visitEach(cb, node.decorators);
8297
8385
  case SyntaxKind.TemplateParameterDeclaration:
8298
8386
  return (visitNode(cb, node.id) || visitNode(cb, node.constraint) || visitNode(cb, node.default));
8387
+ case SyntaxKind.TemplateArgument:
8388
+ return (node.name && visitNode(cb, node.name)) || visitNode(cb, node.argument);
8299
8389
  case SyntaxKind.ProjectionLambdaParameterDeclaration:
8300
8390
  return visitNode(cb, node.id);
8301
8391
  case SyntaxKind.ProjectionParameterDeclaration: