@typespec/compiler 1.17.0-dev.0 → 1.17.0-dev.11

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.
Files changed (195) hide show
  1. package/dist/manifest.js +2 -2
  2. package/dist/src/config/config-interpolation.js.map +1 -1
  3. package/dist/src/config/config-loader.js.map +1 -1
  4. package/dist/src/core/auto-decorator.js.map +1 -1
  5. package/dist/src/core/binder.d.ts +5 -5
  6. package/dist/src/core/binder.d.ts.map +1 -1
  7. package/dist/src/core/binder.js +33 -0
  8. package/dist/src/core/binder.js.map +1 -1
  9. package/dist/src/core/checker.d.ts.map +1 -1
  10. package/dist/src/core/checker.js +168 -53
  11. package/dist/src/core/checker.js.map +1 -1
  12. package/dist/src/core/cli/actions/compile/compile.js.map +1 -1
  13. package/dist/src/core/cli/actions/info.js.map +1 -1
  14. package/dist/src/core/cli/cli.js.map +1 -1
  15. package/dist/src/core/cli/utils.js.map +1 -1
  16. package/dist/src/core/compiler-code-fixes/suppress.codefix.js.map +1 -1
  17. package/dist/src/core/decorator-utils.js.map +1 -1
  18. package/dist/src/core/diagnostic-error.d.ts.map +1 -1
  19. package/dist/src/core/diagnostics.js.map +1 -1
  20. package/dist/src/core/external-error.d.ts.map +1 -1
  21. package/dist/src/core/external-error.js.map +1 -1
  22. package/dist/src/core/features.d.ts +3 -0
  23. package/dist/src/core/features.d.ts.map +1 -1
  24. package/dist/src/core/features.js +3 -0
  25. package/dist/src/core/features.js.map +1 -1
  26. package/dist/src/core/file-ref.d.ts.map +1 -1
  27. package/dist/src/core/formatter-fs.js.map +1 -1
  28. package/dist/src/core/helpers/operation-utils.js.map +1 -1
  29. package/dist/src/core/helpers/syntax-utils.js.map +1 -1
  30. package/dist/src/core/helpers/type-name-utils.js +19 -3
  31. package/dist/src/core/helpers/type-name-utils.js.map +1 -1
  32. package/dist/src/core/helpers/usage-resolver.js.map +1 -1
  33. package/dist/src/core/inspector/node.js +6 -1
  34. package/dist/src/core/inspector/node.js.map +1 -1
  35. package/dist/src/core/inspector/symbol.js.map +1 -1
  36. package/dist/src/core/linter-ruleset-file.js.map +1 -1
  37. package/dist/src/core/logger/console-sink.js.map +1 -1
  38. package/dist/src/core/logger/dynamic-task.d.ts.map +1 -1
  39. package/dist/src/core/logger/tracer.js.map +1 -1
  40. package/dist/src/core/messages.d.ts +88 -52
  41. package/dist/src/core/messages.d.ts.map +1 -1
  42. package/dist/src/core/messages.js +12 -0
  43. package/dist/src/core/messages.js.map +1 -1
  44. package/dist/src/core/modifiers.d.ts +9 -2
  45. package/dist/src/core/modifiers.d.ts.map +1 -1
  46. package/dist/src/core/modifiers.js +8 -0
  47. package/dist/src/core/modifiers.js.map +1 -1
  48. package/dist/src/core/name-resolver.d.ts.map +1 -1
  49. package/dist/src/core/name-resolver.js +30 -4
  50. package/dist/src/core/name-resolver.js.map +1 -1
  51. package/dist/src/core/node-host.js.map +1 -1
  52. package/dist/src/core/node-system-host.d.ts.map +1 -1
  53. package/dist/src/core/numeric.js.map +1 -1
  54. package/dist/src/core/parser.d.ts.map +1 -1
  55. package/dist/src/core/parser.js +257 -23
  56. package/dist/src/core/parser.js.map +1 -1
  57. package/dist/src/core/program.js.map +1 -1
  58. package/dist/src/core/scanner.d.ts +5 -0
  59. package/dist/src/core/scanner.d.ts.map +1 -1
  60. package/dist/src/core/scanner.js +10 -0
  61. package/dist/src/core/scanner.js.map +1 -1
  62. package/dist/src/core/schema-validator.js.map +1 -1
  63. package/dist/src/core/semantic-walker.d.ts.map +1 -1
  64. package/dist/src/core/semantic-walker.js.map +1 -1
  65. package/dist/src/core/source-loader.js.map +1 -1
  66. package/dist/src/core/state-accessors.d.ts.map +1 -1
  67. package/dist/src/core/state-accessors.js.map +1 -1
  68. package/dist/src/core/type-relation-checker.d.ts.map +1 -1
  69. package/dist/src/core/type-utils.d.ts.map +1 -1
  70. package/dist/src/core/type-utils.js +3 -0
  71. package/dist/src/core/type-utils.js.map +1 -1
  72. package/dist/src/core/types.d.ts +111 -14
  73. package/dist/src/core/types.d.ts.map +1 -1
  74. package/dist/src/core/types.js +4 -0
  75. package/dist/src/core/types.js.map +1 -1
  76. package/dist/src/core/visibility/core.d.ts.map +1 -1
  77. package/dist/src/experimental/mutators.js.map +1 -1
  78. package/dist/src/experimental/realm.d.ts.map +1 -1
  79. package/dist/src/experimental/realm.js.map +1 -1
  80. package/dist/src/formatter/index.d.ts.map +1 -1
  81. package/dist/src/formatter/parser.d.ts.map +1 -1
  82. package/dist/src/formatter/parser.js.map +1 -1
  83. package/dist/src/formatter/print/comment-handler.js +11 -1
  84. package/dist/src/formatter/print/comment-handler.js.map +1 -1
  85. package/dist/src/formatter/print/printer.d.ts +4 -4
  86. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  87. package/dist/src/formatter/print/printer.js +106 -15
  88. package/dist/src/formatter/print/printer.js.map +1 -1
  89. package/dist/src/init/init.d.ts.map +1 -1
  90. package/dist/src/init/init.js +3 -1
  91. package/dist/src/init/init.js.map +1 -1
  92. package/dist/src/init/prompts.d.ts +1 -1
  93. package/dist/src/init/prompts.d.ts.map +1 -1
  94. package/dist/src/init/prompts.js +1 -1
  95. package/dist/src/init/prompts.js.map +1 -1
  96. package/dist/src/init/scaffold.d.ts.map +1 -1
  97. package/dist/src/init/scaffold.js +31 -3
  98. package/dist/src/init/scaffold.js.map +1 -1
  99. package/dist/src/init/template-source/in-memory-template-source.d.ts +1 -1
  100. package/dist/src/init/template-source/in-memory-template-source.d.ts.map +1 -1
  101. package/dist/src/init/template-source/in-memory-template-source.js +2 -1
  102. package/dist/src/init/template-source/in-memory-template-source.js.map +1 -1
  103. package/dist/src/init/template-source/types.d.ts +1 -0
  104. package/dist/src/init/template-source/types.d.ts.map +1 -1
  105. package/dist/src/init/template-source/types.js +10 -1
  106. package/dist/src/init/template-source/types.js.map +1 -1
  107. package/dist/src/init/template-source/uri-template-source.d.ts +1 -1
  108. package/dist/src/init/template-source/uri-template-source.d.ts.map +1 -1
  109. package/dist/src/init/template-source/uri-template-source.js +23 -2
  110. package/dist/src/init/template-source/uri-template-source.js.map +1 -1
  111. package/dist/src/install/install.d.ts.map +1 -1
  112. package/dist/src/install/spec.d.ts.map +1 -1
  113. package/dist/src/internals/prettier-formatter.d.ts.map +1 -1
  114. package/dist/src/lib/decorators.js.map +1 -1
  115. package/dist/src/lib/examples.d.ts.map +1 -1
  116. package/dist/src/lib/examples.js.map +1 -1
  117. package/dist/src/lib/intrinsic/decorators.d.ts.map +1 -1
  118. package/dist/src/lib/intrinsic/tsp-index.d.ts +3 -2
  119. package/dist/src/lib/intrinsic/tsp-index.d.ts.map +1 -1
  120. package/dist/src/lib/paging.js.map +1 -1
  121. package/dist/src/lib/service.js.map +1 -1
  122. package/dist/src/lib/visibility.js.map +1 -1
  123. package/dist/src/module-resolver/esm/utils.d.ts.map +1 -1
  124. package/dist/src/module-resolver/module-resolver.d.ts.map +1 -1
  125. package/dist/src/module-resolver/module-resolver.js.map +1 -1
  126. package/dist/src/module-resolver/node-package-resolver.d.ts.map +1 -1
  127. package/dist/src/module-resolver/utils.d.ts.map +1 -1
  128. package/dist/src/module-resolver/utils.js +6 -2
  129. package/dist/src/module-resolver/utils.js.map +1 -1
  130. package/dist/src/package-manger/npm-package-download.js.map +1 -1
  131. package/dist/src/runner.js.map +1 -1
  132. package/dist/src/server/classify.d.ts.map +1 -1
  133. package/dist/src/server/classify.js +12 -4
  134. package/dist/src/server/classify.js.map +1 -1
  135. package/dist/src/server/completion.js +14 -1
  136. package/dist/src/server/completion.js.map +1 -1
  137. package/dist/src/server/debug.d.ts.map +1 -1
  138. package/dist/src/server/language-config.d.ts +4 -4
  139. package/dist/src/server/language-config.d.ts.map +1 -1
  140. package/dist/src/server/lib-provider.d.ts.map +1 -1
  141. package/dist/src/server/lib-provider.js.map +1 -1
  142. package/dist/src/server/npm-package-provider.d.ts.map +1 -1
  143. package/dist/src/server/npm-package-provider.js.map +1 -1
  144. package/dist/src/server/server-compile-manager.d.ts.map +1 -1
  145. package/dist/src/server/server-compile-manager.js.map +1 -1
  146. package/dist/src/server/server-track-action-task.d.ts.map +1 -1
  147. package/dist/src/server/server.js.map +1 -1
  148. package/dist/src/server/serverlib.js.map +1 -1
  149. package/dist/src/server/tmlanguage.d.ts.map +1 -1
  150. package/dist/src/server/tmlanguage.js +69 -1
  151. package/dist/src/server/tmlanguage.js.map +1 -1
  152. package/dist/src/server/tspconfig/completion.js.map +1 -1
  153. package/dist/src/server/type-details.js.map +1 -1
  154. package/dist/src/server/type-signature.js +4 -1
  155. package/dist/src/server/type-signature.js.map +1 -1
  156. package/dist/src/server/update-manager.d.ts.map +1 -1
  157. package/dist/src/server/update-manager.js.map +1 -1
  158. package/dist/src/testing/expect.d.ts.map +1 -1
  159. package/dist/src/testing/fs.d.ts.map +1 -1
  160. package/dist/src/testing/marked-template.d.ts.map +1 -1
  161. package/dist/src/testing/test-host.js.map +1 -1
  162. package/dist/src/testing/test-utils.js.map +1 -1
  163. package/dist/src/testing/tester.d.ts +11 -0
  164. package/dist/src/testing/tester.d.ts.map +1 -1
  165. package/dist/src/testing/tester.js +28 -3
  166. package/dist/src/testing/tester.js.map +1 -1
  167. package/dist/src/testing/types.d.ts.map +1 -1
  168. package/dist/src/testing/types.js.map +1 -1
  169. package/dist/src/typekit/kits/enum.d.ts +14 -1
  170. package/dist/src/typekit/kits/enum.d.ts.map +1 -1
  171. package/dist/src/typekit/kits/enum.js +2 -1
  172. package/dist/src/typekit/kits/enum.js.map +1 -1
  173. package/dist/src/typekit/kits/model.d.ts +12 -1
  174. package/dist/src/typekit/kits/model.d.ts.map +1 -1
  175. package/dist/src/typekit/kits/model.js +3 -2
  176. package/dist/src/typekit/kits/model.js.map +1 -1
  177. package/dist/src/typekit/kits/tuple.js.map +1 -1
  178. package/dist/src/typekit/kits/type.d.ts +2 -2
  179. package/dist/src/typekit/kits/type.d.ts.map +1 -1
  180. package/dist/src/typekit/kits/union.d.ts +12 -1
  181. package/dist/src/typekit/kits/union.d.ts.map +1 -1
  182. package/dist/src/typekit/kits/union.js +3 -3
  183. package/dist/src/typekit/kits/union.js.map +1 -1
  184. package/dist/src/typekit/kits/value.d.ts +2 -2
  185. package/dist/src/typekit/kits/value.d.ts.map +1 -1
  186. package/dist/src/typekit/utils.d.ts.map +1 -1
  187. package/dist/src/typekit/utils.js +17 -0
  188. package/dist/src/typekit/utils.js.map +1 -1
  189. package/dist/src/utils/custom-key-map.d.ts.map +1 -1
  190. package/dist/src/utils/duplicate-tracker.d.ts.map +1 -1
  191. package/dist/src/utils/misc.d.ts.map +1 -1
  192. package/dist/src/utils/misc.js.map +1 -1
  193. package/dist/src/yaml/diagnostics.js.map +1 -1
  194. package/dist/typespec.tmLanguage +209 -37
  195. package/package.json +10 -7
@@ -299,13 +299,17 @@ export function createChecker(program, resolver) {
299
299
  */
300
300
  function checkMemberSym(ctx, sym) {
301
301
  const symbolLinks = getSymbolLinks(sym);
302
- const memberContainer = getTypeForNode(getSymNode(sym.parent), ctx);
302
+ const parentNode = getSymNode(sym.parent);
303
+ compilerAssert(parentNode, "Expected member container parent symbol to have a node");
304
+ const memberContainer = getTypeForNode(parentNode, ctx);
303
305
  const type = symbolLinks.declaredType ?? symbolLinks.type;
304
306
  if (type) {
305
307
  return type;
306
308
  }
307
309
  else {
308
- return checkMember(ctx, getSymNode(sym), memberContainer);
310
+ const memberNode = getSymNode(sym);
311
+ compilerAssert(memberNode, "Expected member symbol to have a node");
312
+ return checkMember(ctx, memberNode, memberContainer);
309
313
  }
310
314
  }
311
315
  /**
@@ -558,20 +562,28 @@ export function createChecker(program, resolver) {
558
562
  return checkModel(ctx, node);
559
563
  case SyntaxKind.ModelStatement:
560
564
  return checkModel(ctx, node);
565
+ case SyntaxKind.ModelDeclarationExpression:
566
+ return checkModel(ctx, node);
561
567
  case SyntaxKind.ModelProperty:
562
568
  return checkModelProperty(ctx, node);
563
569
  case SyntaxKind.ScalarStatement:
564
570
  return checkScalar(ctx, node);
571
+ case SyntaxKind.ScalarDeclarationExpression:
572
+ return checkScalar(ctx, node);
565
573
  case SyntaxKind.AliasStatement:
566
574
  return checkAlias(ctx, node);
567
575
  case SyntaxKind.EnumStatement:
568
576
  return checkEnum(ctx, node);
577
+ case SyntaxKind.EnumDeclarationExpression:
578
+ return checkEnum(ctx, node);
569
579
  case SyntaxKind.EnumMember:
570
580
  return checkEnumMember(ctx, node);
571
581
  case SyntaxKind.InterfaceStatement:
572
582
  return checkInterface(ctx, node);
573
583
  case SyntaxKind.UnionStatement:
574
584
  return checkUnion(ctx, node);
585
+ case SyntaxKind.UnionDeclarationExpression:
586
+ return checkUnion(ctx, node);
575
587
  case SyntaxKind.UnionVariant:
576
588
  return checkUnionVariant(ctx, node);
577
589
  case SyntaxKind.NamespaceStatement:
@@ -631,6 +643,21 @@ export function createChecker(program, resolver) {
631
643
  return errorType;
632
644
  }
633
645
  }
646
+ function reportDeclarationExpressionFeature(node) {
647
+ const isExpression = node.kind === SyntaxKind.ModelDeclarationExpression ||
648
+ node.kind === SyntaxKind.ScalarDeclarationExpression ||
649
+ node.kind === SyntaxKind.EnumDeclarationExpression ||
650
+ node.kind === SyntaxKind.UnionDeclarationExpression;
651
+ if (!isExpression) {
652
+ return;
653
+ }
654
+ if (!isCompilerFeatureEnabled(program, "declaration-expressions", node)) {
655
+ reportCheckerDiagnostic(createDiagnostic({
656
+ code: "declaration-expression-disabled",
657
+ target: node,
658
+ }));
659
+ }
660
+ }
634
661
  /**
635
662
  * Return a fully qualified id of node
636
663
  */
@@ -673,7 +700,7 @@ export function createChecker(program, resolver) {
673
700
  let type = links.declaredType;
674
701
  if (type === undefined) {
675
702
  if (grandParentNode) {
676
- if (grandParentNode.locals?.has(node.id.sv)) {
703
+ if ("locals" in grandParentNode && grandParentNode.locals?.has(node.id.sv)) {
677
704
  reportCheckerDiagnostic(createDiagnostic({
678
705
  code: "shadow",
679
706
  format: { name: node.id.sv },
@@ -1096,6 +1123,7 @@ export function createChecker(program, resolver) {
1096
1123
  return sym.type;
1097
1124
  }
1098
1125
  else if (sym.flags & SymbolFlags.TemplateParameter) {
1126
+ compilerAssert(symNode, "Expected template parameter symbol to have a node");
1099
1127
  const mapped = checkTemplateParameterDeclaration(ctx, symNode);
1100
1128
  baseType = mapped;
1101
1129
  }
@@ -1112,6 +1140,7 @@ export function createChecker(program, resolver) {
1112
1140
  }
1113
1141
  else {
1114
1142
  // don't have a cached type for this symbol, so go grab it and cache it
1143
+ compilerAssert(symNode, "Expected symbol to have a node to resolve type");
1115
1144
  baseType = getTypeForNode(symNode, ctx);
1116
1145
  symbolLinks.type = baseType;
1117
1146
  }
@@ -1295,7 +1324,12 @@ export function createChecker(program, resolver) {
1295
1324
  if (type === neverType) {
1296
1325
  continue;
1297
1326
  }
1298
- if (type.kind === "Union" && type.expression) {
1327
+ // Flatten nested union expressions (e.g. `(a | b) | c` or an alias to a union
1328
+ // expression). Only the `|`-operator form is flattened: its variants are
1329
+ // anonymous (symbol-keyed) and cannot collide. Keyword-form unions used in
1330
+ // expression position (`union { a, b }`) are also `expression: true` but can have
1331
+ // named variants, so flattening them would silently drop colliding members.
1332
+ if (type.kind === "Union" && type.node?.kind === SyntaxKind.UnionExpression) {
1299
1333
  for (const [name, variant] of type.variants) {
1300
1334
  unionType.variants.set(name, variant);
1301
1335
  }
@@ -1673,7 +1707,11 @@ export function createChecker(program, resolver) {
1673
1707
  return undefined;
1674
1708
  if (node.kind === SyntaxKind.ModelExpression ||
1675
1709
  node.kind === SyntaxKind.IntersectionExpression ||
1676
- node.kind === SyntaxKind.UnionExpression) {
1710
+ node.kind === SyntaxKind.UnionExpression ||
1711
+ node.kind === SyntaxKind.ModelDeclarationExpression ||
1712
+ node.kind === SyntaxKind.EnumDeclarationExpression ||
1713
+ node.kind === SyntaxKind.UnionDeclarationExpression ||
1714
+ node.kind === SyntaxKind.ScalarDeclarationExpression) {
1677
1715
  let parent = node.parent;
1678
1716
  while (parent !== undefined) {
1679
1717
  if (parent.kind === SyntaxKind.AliasStatement ||
@@ -3221,17 +3259,20 @@ export function createChecker(program, resolver) {
3221
3259
  return getCanonicalResolvedMemberSymbol(type, node.id.sv);
3222
3260
  }
3223
3261
  function getMemberKindName(node) {
3224
- switch (node.kind) {
3262
+ switch (node?.kind) {
3225
3263
  case SyntaxKind.ModelStatement:
3264
+ case SyntaxKind.ModelDeclarationExpression:
3226
3265
  case SyntaxKind.ModelExpression:
3227
3266
  return "Model";
3228
3267
  case SyntaxKind.ModelProperty:
3229
3268
  return "ModelProperty";
3230
3269
  case SyntaxKind.EnumStatement:
3270
+ case SyntaxKind.EnumDeclarationExpression:
3231
3271
  return "Enum";
3232
3272
  case SyntaxKind.InterfaceStatement:
3233
3273
  return "Interface";
3234
3274
  case SyntaxKind.UnionStatement:
3275
+ case SyntaxKind.UnionDeclarationExpression:
3235
3276
  return "Union";
3236
3277
  default:
3237
3278
  return "Type";
@@ -3339,6 +3380,7 @@ export function createChecker(program, resolver) {
3339
3380
  */
3340
3381
  function getAliasedSymbol(ctx, aliasSymbol) {
3341
3382
  const node = getSymNode(aliasSymbol);
3383
+ compilerAssert(node, "Expected alias symbol to have a node");
3342
3384
  const links = resolver.getSymbolLinks(aliasSymbol);
3343
3385
  if (!links.aliasResolutionIsTemplate) {
3344
3386
  const aliased = links.aliasedSymbol ?? resolver.getNodeLinks(node).resolvedSymbol;
@@ -3670,11 +3712,26 @@ export function createChecker(program, resolver) {
3670
3712
  }
3671
3713
  }
3672
3714
  function checkModel(ctx, node) {
3673
- if (node.kind === SyntaxKind.ModelStatement) {
3674
- return checkModelStatement(ctx, node);
3715
+ if (node.kind === SyntaxKind.ModelExpression) {
3716
+ return checkModelExpression(ctx, node);
3675
3717
  }
3676
3718
  else {
3677
- return checkModelExpression(ctx, node);
3719
+ return checkModelStatement(ctx, node);
3720
+ }
3721
+ }
3722
+ /**
3723
+ * A declaration used in expression position is anonymous and cannot be referenced or
3724
+ * instantiated, so template parameters on it are meaningless. Report a diagnostic when present.
3725
+ */
3726
+ function checkExpressionDeclarationConstraints(node) {
3727
+ const isExpression = node.kind === SyntaxKind.ModelDeclarationExpression ||
3728
+ node.kind === SyntaxKind.UnionDeclarationExpression ||
3729
+ node.kind === SyntaxKind.ScalarDeclarationExpression;
3730
+ if (isExpression && node.templateParameters.length > 0) {
3731
+ reportCheckerDiagnostic(createDiagnostic({
3732
+ code: "templated-declaration-in-expression",
3733
+ target: node.templateParameters[0],
3734
+ }));
3678
3735
  }
3679
3736
  }
3680
3737
  function checkModelStatement(ctx, node) {
@@ -3690,16 +3747,21 @@ export function createChecker(program, resolver) {
3690
3747
  checkModifiers(program, node);
3691
3748
  }
3692
3749
  checkTemplateDeclaration(ctx, node);
3750
+ checkExpressionDeclarationConstraints(node);
3751
+ if (ctx.mapper === undefined) {
3752
+ reportDeclarationExpressionFeature(node);
3753
+ }
3693
3754
  const decorators = [];
3694
3755
  const type = createType({
3695
3756
  kind: "Model",
3696
- name: node.id.sv,
3757
+ name: node.id?.sv ?? "",
3697
3758
  node: node,
3698
3759
  properties: createRekeyableMap(),
3699
3760
  namespace: getParentNamespaceType(node),
3700
3761
  decorators,
3701
3762
  sourceModels: [],
3702
3763
  derivedModels: [],
3764
+ expression: node.kind === SyntaxKind.ModelDeclarationExpression,
3703
3765
  });
3704
3766
  linkType(ctx, links, type);
3705
3767
  if (node.symbol.members) {
@@ -3750,7 +3812,7 @@ export function createChecker(program, resolver) {
3750
3812
  }
3751
3813
  // Hold on to the model type that's being defined so that it
3752
3814
  // can be referenced
3753
- if (ctx.mapper === undefined) {
3815
+ if (ctx.mapper === undefined && !type.expression) {
3754
3816
  type.namespace?.models.set(type.name, type);
3755
3817
  }
3756
3818
  // Evaluate the properties after
@@ -3841,6 +3903,14 @@ export function createChecker(program, resolver) {
3841
3903
  else {
3842
3904
  // spread property
3843
3905
  const [newProperties, additionalIndexer] = checkSpreadProperty(ctx, node.symbol, prop.target, parentModel);
3906
+ if (findIndexer(parentModel)?.key.name === "integer" &&
3907
+ (newProperties.length > 0 || additionalIndexer !== undefined)) {
3908
+ reportCheckerDiagnostic(createDiagnostic({
3909
+ code: "no-array-properties",
3910
+ target: prop,
3911
+ }));
3912
+ continue;
3913
+ }
3844
3914
  if (additionalIndexer) {
3845
3915
  if (spreadIndexers) {
3846
3916
  spreadIndexers.push(additionalIndexer);
@@ -3892,6 +3962,7 @@ export function createChecker(program, resolver) {
3892
3962
  decorators: [],
3893
3963
  derivedModels: [],
3894
3964
  sourceModels: [],
3965
+ expression: true,
3895
3966
  });
3896
3967
  for (const prop of properties.values()) {
3897
3968
  model.properties.set(prop.name, createModelPropertyForObjectPropertyDescriptor(prop, model));
@@ -5333,7 +5404,8 @@ export function createChecker(program, resolver) {
5333
5404
  }
5334
5405
  else if (links.finalSymbol?.flags &&
5335
5406
  ~links.finalSymbol.flags & SymbolFlags.Declaration &&
5336
- ~links.finalSymbol.flags & SymbolFlags.Member) {
5407
+ ~links.finalSymbol.flags & SymbolFlags.Member &&
5408
+ !isDeclarationExpressionSym(links.finalSymbol)) {
5337
5409
  program.reportDiagnostic(createDiagnostic({
5338
5410
  code: "augment-decorator-target",
5339
5411
  messageId: links.finalSymbol.flags & SymbolFlags.Model
@@ -5346,6 +5418,7 @@ export function createChecker(program, resolver) {
5346
5418
  }
5347
5419
  else if (links.finalSymbol?.flags && links.finalSymbol.flags & SymbolFlags.Alias) {
5348
5420
  const aliasNode = getSymNode(links.finalSymbol);
5421
+ compilerAssert(aliasNode, "Expected alias symbol to have a node");
5349
5422
  program.reportDiagnostic(createDiagnostic({
5350
5423
  code: "augment-decorator-target",
5351
5424
  messageId: aliasNode.value.kind === SyntaxKind.UnionExpression ? "noUnionExpression" : "default",
@@ -5355,6 +5428,23 @@ export function createChecker(program, resolver) {
5355
5428
  // If this was used to get a type this is invalid, only used for validation.
5356
5429
  return errorType;
5357
5430
  }
5431
+ /**
5432
+ * A declaration expression (e.g. the `enum { a, b }` in `model Foo { x: enum { a, b } }`)
5433
+ * is bound as a non-declaration symbol but is still a real, referenceable type
5434
+ * (e.g. via `Foo.x::type`) and therefore a valid augment target. Statement-position
5435
+ * declarations carry {@link SymbolFlags.Declaration} and never reach this check.
5436
+ */
5437
+ function isDeclarationExpressionSym(sym) {
5438
+ switch (getSymNode(sym)?.kind) {
5439
+ case SyntaxKind.ModelDeclarationExpression:
5440
+ case SyntaxKind.EnumDeclarationExpression:
5441
+ case SyntaxKind.UnionDeclarationExpression:
5442
+ case SyntaxKind.ScalarDeclarationExpression:
5443
+ return true;
5444
+ default:
5445
+ return false;
5446
+ }
5447
+ }
5358
5448
  /**
5359
5449
  * Check that using statements are targeting valid symbols.
5360
5450
  */
@@ -5427,15 +5517,20 @@ export function createChecker(program, resolver) {
5427
5517
  checkModifiers(program, node);
5428
5518
  }
5429
5519
  checkTemplateDeclaration(ctx, node);
5520
+ checkExpressionDeclarationConstraints(node);
5521
+ if (ctx.mapper === undefined) {
5522
+ reportDeclarationExpressionFeature(node);
5523
+ }
5430
5524
  const decorators = [];
5431
5525
  const type = createType({
5432
5526
  kind: "Scalar",
5433
- name: node.id.sv,
5527
+ name: node.id?.sv ?? "",
5434
5528
  node: node,
5435
5529
  constructors: new Map(),
5436
5530
  namespace: getParentNamespaceType(node),
5437
5531
  decorators,
5438
5532
  derivedScalars: [],
5533
+ expression: node.kind === SyntaxKind.ScalarDeclarationExpression,
5439
5534
  });
5440
5535
  linkType(ctx, links, type);
5441
5536
  if (node.extends) {
@@ -5447,7 +5542,7 @@ export function createChecker(program, resolver) {
5447
5542
  }
5448
5543
  checkScalarConstructors(ctx, type, node, type.constructors);
5449
5544
  decorators.push(...checkDecorators(ctx, type, node));
5450
- if (ctx.mapper === undefined) {
5545
+ if (ctx.mapper === undefined && !type.expression) {
5451
5546
  type.namespace?.scalars.set(type.name, type);
5452
5547
  }
5453
5548
  linkMapper(type, ctx.mapper);
@@ -5631,46 +5726,57 @@ export function createChecker(program, resolver) {
5631
5726
  }
5632
5727
  function checkEnum(ctx, node) {
5633
5728
  const links = getSymbolLinks(node.symbol);
5634
- if (!links.type) {
5729
+ if (links.declaredType && ctx.mapper === undefined) {
5730
+ // we're not instantiating this enum and we've already checked it
5731
+ return links.declaredType;
5732
+ }
5733
+ if (ctx.mapper === undefined) {
5635
5734
  checkModifiers(program, node);
5636
- const enumType = (links.type = createType({
5637
- kind: "Enum",
5638
- name: node.id.sv,
5639
- node,
5640
- members: createRekeyableMap(),
5641
- decorators: [],
5642
- }));
5643
- const memberNames = new Set();
5644
- for (const member of node.members) {
5645
- if (member.kind === SyntaxKind.EnumMember) {
5646
- const memberType = checkEnumMember(ctx, member, enumType);
5647
- if (memberNames.has(memberType.name)) {
5648
- reportCheckerDiagnostic(createDiagnostic({
5649
- code: "enum-member-duplicate",
5650
- format: { name: memberType.name },
5651
- target: node,
5652
- }));
5653
- continue;
5654
- }
5655
- memberNames.add(memberType.name);
5656
- enumType.members.set(memberType.name, memberType);
5735
+ reportDeclarationExpressionFeature(node);
5736
+ }
5737
+ const enumType = createType({
5738
+ kind: "Enum",
5739
+ name: node.id?.sv ?? "",
5740
+ node,
5741
+ members: createRekeyableMap(),
5742
+ decorators: [],
5743
+ expression: node.kind === SyntaxKind.EnumDeclarationExpression,
5744
+ });
5745
+ // Link the type before resolving the parent namespace: resolving the namespace may run
5746
+ // its decorators which can reference this enum, and we must not create a second instance.
5747
+ linkType(ctx, links, enumType);
5748
+ const memberNames = new Set();
5749
+ for (const member of node.members) {
5750
+ if (member.kind === SyntaxKind.EnumMember) {
5751
+ const memberType = checkEnumMember(ctx, member, enumType);
5752
+ if (memberNames.has(memberType.name)) {
5753
+ reportCheckerDiagnostic(createDiagnostic({
5754
+ code: "enum-member-duplicate",
5755
+ format: { name: memberType.name },
5756
+ target: node,
5757
+ }));
5758
+ continue;
5657
5759
  }
5658
- else {
5659
- const members = checkEnumSpreadMember(ctx, node.symbol, enumType, member.target, memberNames);
5660
- for (const memberType of members) {
5661
- linkIndirectMember(ctx, node, memberType);
5662
- enumType.members.set(memberType.name, memberType);
5663
- }
5760
+ memberNames.add(memberType.name);
5761
+ enumType.members.set(memberType.name, memberType);
5762
+ }
5763
+ else {
5764
+ const members = checkEnumSpreadMember(ctx, node.symbol, enumType, member.target, memberNames);
5765
+ for (const memberType of members) {
5766
+ linkIndirectMember(ctx, node, memberType);
5767
+ enumType.members.set(memberType.name, memberType);
5664
5768
  }
5665
5769
  }
5666
- const namespace = getParentNamespaceType(node);
5667
- enumType.namespace = namespace;
5770
+ }
5771
+ enumType.namespace = getParentNamespaceType(node);
5772
+ if (ctx.mapper === undefined && !enumType.expression) {
5668
5773
  enumType.namespace?.enums.set(enumType.name, enumType);
5669
- enumType.decorators = checkDecorators(ctx, enumType, node);
5670
- linkMapper(enumType, ctx.mapper);
5671
- finishType(enumType);
5672
5774
  }
5673
- return links.type;
5775
+ enumType.decorators = checkDecorators(ctx, enumType, node);
5776
+ linkMapper(enumType, ctx.mapper);
5777
+ return finishType(enumType, {
5778
+ skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
5779
+ });
5674
5780
  }
5675
5781
  function checkInterface(ctx, node) {
5676
5782
  const links = getSymbolLinks(node.symbol);
@@ -5781,18 +5887,22 @@ export function createChecker(program, resolver) {
5781
5887
  }
5782
5888
  }
5783
5889
  checkTemplateDeclaration(ctx, node);
5890
+ checkExpressionDeclarationConstraints(node);
5891
+ if (ctx.mapper === undefined) {
5892
+ reportDeclarationExpressionFeature(node);
5893
+ }
5784
5894
  const variants = createRekeyableMap();
5785
5895
  const unionType = createType({
5786
5896
  kind: "Union",
5787
5897
  decorators: [],
5788
5898
  node,
5789
5899
  namespace: getParentNamespaceType(node),
5790
- name: node.id.sv,
5900
+ name: node.id?.sv,
5791
5901
  variants,
5792
5902
  get options() {
5793
5903
  return Array.from(this.variants.values()).map((v) => v.type);
5794
5904
  },
5795
- expression: false,
5905
+ expression: node.kind === SyntaxKind.UnionDeclarationExpression,
5796
5906
  });
5797
5907
  linkType(ctx, links, unionType);
5798
5908
  if (node.extends) {
@@ -5801,11 +5911,13 @@ export function createChecker(program, resolver) {
5801
5911
  unionType.decorators = checkDecorators(ctx, unionType, node);
5802
5912
  checkUnionVariants(ctx, unionType, node, variants);
5803
5913
  linkMapper(unionType, ctx.mapper);
5804
- if (ctx.mapper === undefined) {
5914
+ if (ctx.mapper === undefined && !unionType.expression) {
5805
5915
  unionType.namespace?.unions.set(unionType.name, unionType);
5806
5916
  }
5807
5917
  lateBindMemberContainer(unionType);
5808
- lateBindMembers(unionType);
5918
+ if (unionType.symbol) {
5919
+ lateBindMembers(unionType);
5920
+ }
5809
5921
  return finishType(unionType, {
5810
5922
  skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
5811
5923
  });
@@ -5876,7 +5988,7 @@ export function createChecker(program, resolver) {
5876
5988
  if (ctx.mapper === undefined) {
5877
5989
  reportCheckerDiagnostic(createDiagnostic({
5878
5990
  code: "circular-base-type",
5879
- format: { typeName: union.id.sv },
5991
+ format: { typeName: union.id?.sv ?? "(anonymous union)" },
5880
5992
  target: extendsRef,
5881
5993
  }));
5882
5994
  }
@@ -6080,6 +6192,7 @@ export function createChecker(program, resolver) {
6080
6192
  decorators: [],
6081
6193
  derivedModels: [],
6082
6194
  sourceModels: [],
6195
+ expression: true,
6083
6196
  });
6084
6197
  }
6085
6198
  /**
@@ -6786,6 +6899,8 @@ function createFunctionContext(program, fnCall) {
6786
6899
  };
6787
6900
  }
6788
6901
  function isTemplatedNode(node) {
6902
+ if (node === undefined)
6903
+ return false;
6789
6904
  return "templateParameters" in node && node.templateParameters.length > 0;
6790
6905
  }
6791
6906
  var ResolutionKind;