@typespec/compiler 0.48.0-dev.8 → 0.48.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.
Files changed (72) hide show
  1. package/dist/manifest.js +2 -2
  2. package/dist/src/config/config-loader.d.ts.map +1 -1
  3. package/dist/src/config/config-loader.js +20 -14
  4. package/dist/src/config/config-loader.js.map +1 -1
  5. package/dist/src/config/config-schema.d.ts.map +1 -1
  6. package/dist/src/config/config-schema.js +1 -0
  7. package/dist/src/config/config-schema.js.map +1 -1
  8. package/dist/src/config/types.d.ts +3 -0
  9. package/dist/src/config/types.d.ts.map +1 -1
  10. package/dist/src/core/binder.d.ts.map +1 -1
  11. package/dist/src/core/binder.js +32 -11
  12. package/dist/src/core/binder.js.map +1 -1
  13. package/dist/src/core/checker.d.ts.map +1 -1
  14. package/dist/src/core/checker.js +155 -81
  15. package/dist/src/core/checker.js.map +1 -1
  16. package/dist/src/core/cli/actions/compile/compile.js +1 -1
  17. package/dist/src/core/cli/actions/compile/compile.js.map +1 -1
  18. package/dist/src/core/cli/actions/info.d.ts.map +1 -1
  19. package/dist/src/core/cli/actions/info.js +3 -4
  20. package/dist/src/core/cli/actions/info.js.map +1 -1
  21. package/dist/src/core/index.d.ts +1 -0
  22. package/dist/src/core/index.d.ts.map +1 -1
  23. package/dist/src/core/index.js +1 -0
  24. package/dist/src/core/index.js.map +1 -1
  25. package/dist/src/core/messages.d.ts +20 -2
  26. package/dist/src/core/messages.d.ts.map +1 -1
  27. package/dist/src/core/messages.js +6 -0
  28. package/dist/src/core/messages.js.map +1 -1
  29. package/dist/src/core/options.d.ts +0 -1
  30. package/dist/src/core/options.d.ts.map +1 -1
  31. package/dist/src/core/parser.d.ts.map +1 -1
  32. package/dist/src/core/parser.js +4 -1
  33. package/dist/src/core/parser.js.map +1 -1
  34. package/dist/src/core/schema-validator.d.ts +4 -0
  35. package/dist/src/core/schema-validator.d.ts.map +1 -1
  36. package/dist/src/core/schema-validator.js +37 -1
  37. package/dist/src/core/schema-validator.js.map +1 -1
  38. package/dist/src/core/types.d.ts +13 -5
  39. package/dist/src/core/types.d.ts.map +1 -1
  40. package/dist/src/core/types.js +2 -0
  41. package/dist/src/core/types.js.map +1 -1
  42. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  43. package/dist/src/formatter/print/printer.js +1 -0
  44. package/dist/src/formatter/print/printer.js.map +1 -1
  45. package/dist/src/init/init.js +2 -2
  46. package/dist/src/init/init.js.map +1 -1
  47. package/dist/src/server/serverlib.d.ts +2 -1
  48. package/dist/src/server/serverlib.d.ts.map +1 -1
  49. package/dist/src/server/serverlib.js +77 -12
  50. package/dist/src/server/serverlib.js.map +1 -1
  51. package/dist/src/server/tmlanguage.d.ts +1 -1
  52. package/dist/src/server/tmlanguage.d.ts.map +1 -1
  53. package/dist/src/server/tmlanguage.js +50 -2
  54. package/dist/src/server/tmlanguage.js.map +1 -1
  55. package/dist/src/yaml/diagnostics.d.ts +4 -0
  56. package/dist/src/yaml/diagnostics.d.ts.map +1 -0
  57. package/dist/src/yaml/diagnostics.js +45 -0
  58. package/dist/src/yaml/diagnostics.js.map +1 -0
  59. package/dist/src/yaml/index.d.ts +4 -0
  60. package/dist/src/yaml/index.d.ts.map +1 -0
  61. package/dist/src/yaml/index.js +4 -0
  62. package/dist/src/yaml/index.js.map +1 -0
  63. package/dist/src/yaml/parser.d.ts +4 -0
  64. package/dist/src/yaml/parser.d.ts.map +1 -0
  65. package/dist/src/yaml/parser.js +30 -0
  66. package/dist/src/yaml/parser.js.map +1 -0
  67. package/dist/src/yaml/types.d.ts +9 -0
  68. package/dist/src/yaml/types.d.ts.map +1 -0
  69. package/dist/src/yaml/types.js +2 -0
  70. package/dist/src/yaml/types.js.map +1 -0
  71. package/dist/typespec.tmLanguage +131 -2
  72. package/package.json +5 -7
@@ -1,3 +1,9 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _PendingResolutions_data;
1
7
  import { $docFromComment, getIndexer } from "../lib/decorators.js";
2
8
  import { createSymbol, createSymbolTable } from "./binder.js";
3
9
  import { getDeprecationDetails, markDeprecated } from "./deprecation.js";
@@ -63,7 +69,7 @@ export function createChecker(program) {
63
69
  * Set keeping track of node pending type resolution.
64
70
  * Key is the SymId of a node. It can be retrieved with getNodeSymId(node)
65
71
  */
66
- const pendingResolutions = new Set();
72
+ const pendingResolutions = new PendingResolutions();
67
73
  for (const file of program.jsSourceFiles.values()) {
68
74
  mergeSourceFile(file);
69
75
  }
@@ -342,6 +348,7 @@ export function createChecker(program) {
342
348
  case SyntaxKind.UnionVariant:
343
349
  return checkUnionVariant(node, mapper);
344
350
  case SyntaxKind.NamespaceStatement:
351
+ case SyntaxKind.JsNamespaceDeclaration:
345
352
  return checkNamespace(node);
346
353
  case SyntaxKind.OperationStatement:
347
354
  return checkOperation(node, mapper);
@@ -987,12 +994,14 @@ export function createChecker(program) {
987
994
  if (!type) {
988
995
  type = initializeTypeForNamespace(node);
989
996
  }
990
- if (isArray(node.statements)) {
991
- node.statements.forEach((x) => getTypeForNode(x));
992
- }
993
- else if (node.statements) {
994
- const subNs = checkNamespace(node.statements);
995
- type.namespaces.set(subNs.name, subNs);
997
+ if (node.kind === SyntaxKind.NamespaceStatement) {
998
+ if (isArray(node.statements)) {
999
+ node.statements.forEach((x) => getTypeForNode(x));
1000
+ }
1001
+ else if (node.statements) {
1002
+ const subNs = checkNamespace(node.statements);
1003
+ type.namespaces.set(subNs.name, subNs);
1004
+ }
996
1005
  }
997
1006
  return type;
998
1007
  }
@@ -1008,7 +1017,7 @@ export function createChecker(program) {
1008
1017
  kind: "Namespace",
1009
1018
  name,
1010
1019
  namespace,
1011
- node,
1020
+ node: node,
1012
1021
  models: new Map(),
1013
1022
  scalars: new Map(),
1014
1023
  operations: new Map(),
@@ -1074,7 +1083,7 @@ export function createChecker(program) {
1074
1083
  // However, one case where this is not true is when a decorator on a namespace
1075
1084
  // refers to a model in another namespace. In this case, we need to evaluate
1076
1085
  // the namespace here.
1077
- const namespaceNode = mergedSymbol.declarations.find((x) => x.kind === SyntaxKind.NamespaceStatement);
1086
+ const namespaceNode = mergedSymbol.declarations.find((x) => x.kind === SyntaxKind.NamespaceStatement || x.kind === SyntaxKind.JsNamespaceDeclaration);
1078
1087
  compilerAssert(namespaceNode, "Can't find namespace declaration node.", node);
1079
1088
  symbolLinks.type = initializeTypeForNamespace(namespaceNode);
1080
1089
  }
@@ -1172,14 +1181,14 @@ export function createChecker(program) {
1172
1181
  // Ensure that we don't end up with a circular reference to the same operation
1173
1182
  const opSymId = getNodeSymId(operation);
1174
1183
  if (opSymId) {
1175
- pendingResolutions.add(opSymId);
1184
+ pendingResolutions.start(opSymId, ResolutionKind.BaseType);
1176
1185
  }
1177
1186
  const target = resolveTypeReferenceSym(opReference, mapper);
1178
1187
  if (target === undefined) {
1179
1188
  return undefined;
1180
1189
  }
1181
1190
  // Did we encounter a circular operation reference?
1182
- if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
1191
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
1183
1192
  if (mapper === undefined) {
1184
1193
  reportCheckerDiagnostic(createDiagnostic({
1185
1194
  code: "circular-op-signature",
@@ -1192,7 +1201,7 @@ export function createChecker(program) {
1192
1201
  // Resolve the base operation type
1193
1202
  const baseOperation = checkTypeReferenceSymbol(target, opReference, mapper);
1194
1203
  if (opSymId) {
1195
- pendingResolutions.delete(opSymId);
1204
+ pendingResolutions.finish(opSymId, ResolutionKind.BaseType);
1196
1205
  }
1197
1206
  if (isErrorType(baseOperation)) {
1198
1207
  return undefined;
@@ -1645,7 +1654,7 @@ export function createChecker(program) {
1645
1654
  default:
1646
1655
  // get the symbol from the node aliased type's node, or just return the base
1647
1656
  // if it doesn't have a symbol (which will likely result in an error later on)
1648
- return (_a = aliasType.node.symbol) !== null && _a !== void 0 ? _a : aliasSymbol;
1657
+ return (_a = getMergedSymbol(aliasType.node.symbol)) !== null && _a !== void 0 ? _a : aliasSymbol;
1649
1658
  }
1650
1659
  }
1651
1660
  function checkStringLiteral(str) {
@@ -2150,12 +2159,12 @@ export function createChecker(program) {
2150
2159
  return undefined;
2151
2160
  }
2152
2161
  const modelSymId = getNodeSymId(model);
2153
- pendingResolutions.add(modelSymId);
2162
+ pendingResolutions.start(modelSymId, ResolutionKind.BaseType);
2154
2163
  const target = resolveTypeReferenceSym(heritageRef, mapper);
2155
2164
  if (target === undefined) {
2156
2165
  return undefined;
2157
2166
  }
2158
- if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
2167
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
2159
2168
  if (mapper === undefined) {
2160
2169
  reportCheckerDiagnostic(createDiagnostic({
2161
2170
  code: "circular-base-type",
@@ -2166,7 +2175,7 @@ export function createChecker(program) {
2166
2175
  return undefined;
2167
2176
  }
2168
2177
  const heritageType = checkTypeReferenceSymbol(target, heritageRef, mapper);
2169
- pendingResolutions.delete(modelSymId);
2178
+ pendingResolutions.finish(modelSymId, ResolutionKind.BaseType);
2170
2179
  if (isErrorType(heritageType)) {
2171
2180
  compilerAssert(program.hasError(), "Should already have reported an error.", heritageRef);
2172
2181
  return undefined;
@@ -2188,7 +2197,7 @@ export function createChecker(program) {
2188
2197
  if (!isExpr)
2189
2198
  return undefined;
2190
2199
  const modelSymId = getNodeSymId(model);
2191
- pendingResolutions.add(modelSymId);
2200
+ pendingResolutions.start(modelSymId, ResolutionKind.BaseType);
2192
2201
  let isType;
2193
2202
  if (isExpr.kind === SyntaxKind.ModelExpression) {
2194
2203
  reportCheckerDiagnostic(createDiagnostic({
@@ -2206,7 +2215,7 @@ export function createChecker(program) {
2206
2215
  if (target === undefined) {
2207
2216
  return undefined;
2208
2217
  }
2209
- if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
2218
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
2210
2219
  if (mapper === undefined) {
2211
2220
  reportCheckerDiagnostic(createDiagnostic({
2212
2221
  code: "circular-base-type",
@@ -2222,7 +2231,7 @@ export function createChecker(program) {
2222
2231
  reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
2223
2232
  return undefined;
2224
2233
  }
2225
- pendingResolutions.delete(modelSymId);
2234
+ pendingResolutions.finish(modelSymId, ResolutionKind.BaseType);
2226
2235
  if (isType.kind !== "Model") {
2227
2236
  reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
2228
2237
  return;
@@ -2276,24 +2285,35 @@ export function createChecker(program) {
2276
2285
  }
2277
2286
  function checkModelProperty(prop, mapper) {
2278
2287
  var _a, _b, _c;
2288
+ const symId = getSymbolId(getSymbolForMember(prop));
2279
2289
  const links = getSymbolLinksForMember(prop);
2280
2290
  if (links && links.declaredType && mapper === undefined) {
2281
2291
  return links.declaredType;
2282
2292
  }
2283
2293
  const name = prop.id.sv;
2284
- const valueType = getTypeForNode(prop.value, mapper);
2285
- const defaultValue = prop.default && checkDefault(prop.default, valueType);
2286
2294
  const type = createType({
2287
2295
  kind: "ModelProperty",
2288
2296
  name,
2289
2297
  node: prop,
2290
2298
  optional: prop.optional,
2291
- type: valueType,
2299
+ type: undefined,
2292
2300
  decorators: [],
2293
- default: defaultValue,
2294
2301
  });
2295
- if (links) {
2296
- linkType(links, type, mapper);
2302
+ if (pendingResolutions.has(symId, ResolutionKind.Type) && mapper === undefined) {
2303
+ reportCheckerDiagnostic(createDiagnostic({
2304
+ code: "circular-prop",
2305
+ format: { propName: name },
2306
+ target: prop,
2307
+ }));
2308
+ type.type = errorType;
2309
+ }
2310
+ else {
2311
+ pendingResolutions.start(symId, ResolutionKind.Type);
2312
+ type.type = getTypeForNode(prop.value, mapper);
2313
+ type.default = prop.default && checkDefault(prop.default, type.type);
2314
+ if (links) {
2315
+ linkType(links, type, mapper);
2316
+ }
2297
2317
  }
2298
2318
  type.decorators = checkDecorators(type, prop, mapper);
2299
2319
  const parentTemplate = getParentTemplateNode(prop);
@@ -2311,6 +2331,7 @@ export function createChecker(program) {
2311
2331
  }
2312
2332
  finishType(type);
2313
2333
  }
2334
+ pendingResolutions.finish(symId, ResolutionKind.Type);
2314
2335
  return type;
2315
2336
  }
2316
2337
  function isValueType(type) {
@@ -2566,12 +2587,12 @@ export function createChecker(program) {
2566
2587
  }
2567
2588
  function checkScalarExtends(scalar, extendsRef, mapper) {
2568
2589
  const symId = getNodeSymId(scalar);
2569
- pendingResolutions.add(symId);
2590
+ pendingResolutions.start(symId, ResolutionKind.BaseType);
2570
2591
  const target = resolveTypeReferenceSym(extendsRef, mapper);
2571
2592
  if (target === undefined) {
2572
2593
  return undefined;
2573
2594
  }
2574
- if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
2595
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
2575
2596
  if (mapper === undefined) {
2576
2597
  reportCheckerDiagnostic(createDiagnostic({
2577
2598
  code: "circular-base-type",
@@ -2582,7 +2603,7 @@ export function createChecker(program) {
2582
2603
  return undefined;
2583
2604
  }
2584
2605
  const extendsType = checkTypeReferenceSymbol(target, extendsRef, mapper);
2585
- pendingResolutions.delete(symId);
2606
+ pendingResolutions.finish(symId, ResolutionKind.BaseType);
2586
2607
  if (isErrorType(extendsType)) {
2587
2608
  compilerAssert(program.hasError(), "Should already have reported an error.", extendsRef);
2588
2609
  return undefined;
@@ -2600,7 +2621,7 @@ export function createChecker(program) {
2600
2621
  }
2601
2622
  checkTemplateDeclaration(node, mapper);
2602
2623
  const aliasSymId = getNodeSymId(node);
2603
- if (pendingResolutions.has(aliasSymId)) {
2624
+ if (pendingResolutions.has(aliasSymId, ResolutionKind.Type)) {
2604
2625
  if (mapper === undefined) {
2605
2626
  reportCheckerDiagnostic(createDiagnostic({
2606
2627
  code: "circular-alias-type",
@@ -2611,10 +2632,10 @@ export function createChecker(program) {
2611
2632
  links.declaredType = errorType;
2612
2633
  return errorType;
2613
2634
  }
2614
- pendingResolutions.add(aliasSymId);
2635
+ pendingResolutions.start(aliasSymId, ResolutionKind.Type);
2615
2636
  const type = getTypeForNode(node.value, mapper);
2616
2637
  linkType(links, type, mapper);
2617
- pendingResolutions.delete(aliasSymId);
2638
+ pendingResolutions.finish(aliasSymId, ResolutionKind.Type);
2618
2639
  return type;
2619
2640
  }
2620
2641
  function checkEnum(node, mapper) {
@@ -3794,42 +3815,55 @@ export function createChecker(program) {
3794
3815
  * @param diagnosticTarget Target for the diagnostic, unless something better can be inferred.
3795
3816
  */
3796
3817
  function isTypeAssignableTo(source, target, diagnosticTarget) {
3818
+ const [related, diagnostics] = isTypeAssignableToInternal(source, target, diagnosticTarget, new MultiKeyMap());
3819
+ return [related === Related.true, diagnostics];
3820
+ }
3821
+ function isTypeAssignableToInternal(source, target, diagnosticTarget, relationCache) {
3822
+ const cached = relationCache.get([source, target]);
3823
+ if (cached !== undefined) {
3824
+ return [cached, []];
3825
+ }
3826
+ const [result, diagnostics] = isTypeAssignableToWorker(source, target, diagnosticTarget, new MultiKeyMap());
3827
+ relationCache.set([source, target], result);
3828
+ return [result, diagnostics];
3829
+ }
3830
+ function isTypeAssignableToWorker(source, target, diagnosticTarget, relationCache) {
3797
3831
  var _a;
3798
3832
  // BACKCOMPAT: Added May 2023 sprint, to be removed by June 2023 sprint
3799
3833
  if (source.kind === "TemplateParameter" && source.constraint && target.kind === "Value") {
3800
- const [assignable] = isTypeAssignableTo(source.constraint, target.target, diagnosticTarget);
3834
+ const [assignable] = isTypeAssignableToInternal(source.constraint, target.target, diagnosticTarget, relationCache);
3801
3835
  if (assignable) {
3802
3836
  const constraint = getTypeName(source.constraint);
3803
3837
  reportDeprecated(program, `Template constrainted to '${constraint}' will not be assignable to '${getTypeName(target)}' in the future. Update the constraint to be 'valueof ${constraint}'`, diagnosticTarget);
3804
- return [true, []];
3838
+ return [Related.true, []];
3805
3839
  }
3806
3840
  }
3807
3841
  if (source.kind === "TemplateParameter") {
3808
3842
  source = (_a = source.constraint) !== null && _a !== void 0 ? _a : unknownType;
3809
3843
  }
3810
3844
  if (source === target)
3811
- return [true, []];
3845
+ return [Related.true, []];
3812
3846
  if (target.kind === "Value") {
3813
- return isAssignableToValueType(source, target, diagnosticTarget);
3847
+ return isAssignableToValueType(source, target, diagnosticTarget, relationCache);
3814
3848
  }
3815
3849
  if (source.kind === "Value") {
3816
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3850
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3817
3851
  }
3818
3852
  const isSimpleTypeRelated = isSimpleTypeAssignableTo(source, target);
3819
3853
  if (isSimpleTypeRelated === true) {
3820
- return [true, []];
3854
+ return [Related.true, []];
3821
3855
  }
3822
3856
  else if (isSimpleTypeRelated === false) {
3823
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3857
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3824
3858
  }
3825
3859
  if (source.kind === "Union") {
3826
3860
  for (const variant of source.variants.values()) {
3827
- const [variantAssignable] = isTypeAssignableTo(variant.type, target, diagnosticTarget);
3861
+ const [variantAssignable] = isTypeAssignableToInternal(variant.type, target, diagnosticTarget, relationCache);
3828
3862
  if (!variantAssignable) {
3829
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3863
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3830
3864
  }
3831
3865
  }
3832
- return [true, []];
3866
+ return [Related.true, []];
3833
3867
  }
3834
3868
  if (target.kind === "Model" &&
3835
3869
  source.kind === "Model" &&
@@ -3838,7 +3872,7 @@ export function createChecker(program) {
3838
3872
  source.indexer &&
3839
3873
  source.indexer.key.name === "integer") {
3840
3874
  return [
3841
- false,
3875
+ Related.false,
3842
3876
  [
3843
3877
  createDiagnostic({
3844
3878
  code: "missing-index",
@@ -3852,43 +3886,43 @@ export function createChecker(program) {
3852
3886
  ];
3853
3887
  }
3854
3888
  else if (target.kind === "Model" && target.indexer !== undefined && source.kind === "Model") {
3855
- return isIndexerValid(source, target, diagnosticTarget);
3889
+ return isIndexerValid(source, target, diagnosticTarget, relationCache);
3856
3890
  }
3857
3891
  else if (target.kind === "Model" && source.kind === "Model") {
3858
- return isModelRelatedTo(source, target, diagnosticTarget);
3892
+ return isModelRelatedTo(source, target, diagnosticTarget, relationCache);
3859
3893
  }
3860
3894
  else if (target.kind === "Model" && target.indexer && source.kind === "Tuple") {
3861
3895
  for (const item of source.values) {
3862
- const [related, diagnostics] = isTypeAssignableTo(item, target.indexer.value, diagnosticTarget);
3896
+ const [related, diagnostics] = isTypeAssignableToInternal(item, target.indexer.value, diagnosticTarget, relationCache);
3863
3897
  if (!related) {
3864
- return [false, diagnostics];
3898
+ return [Related.false, diagnostics];
3865
3899
  }
3866
3900
  }
3867
- return [true, []];
3901
+ return [Related.true, []];
3868
3902
  }
3869
3903
  else if (target.kind === "Tuple" && source.kind === "Tuple") {
3870
- return isTupleAssignableToTuple(source, target, diagnosticTarget);
3904
+ return isTupleAssignableToTuple(source, target, diagnosticTarget, relationCache);
3871
3905
  }
3872
3906
  else if (target.kind === "Union") {
3873
- return isAssignableToUnion(source, target, diagnosticTarget);
3907
+ return isAssignableToUnion(source, target, diagnosticTarget, relationCache);
3874
3908
  }
3875
3909
  else if (target.kind === "Enum") {
3876
3910
  return isAssignableToEnum(source, target, diagnosticTarget);
3877
3911
  }
3878
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3912
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3879
3913
  }
3880
- function isAssignableToValueType(source, target, diagnosticTarget) {
3914
+ function isAssignableToValueType(source, target, diagnosticTarget, relationCache) {
3881
3915
  if (source.kind === "Value") {
3882
- return isTypeAssignableTo(source.target, target.target, diagnosticTarget);
3916
+ return isTypeAssignableToInternal(source.target, target.target, diagnosticTarget, relationCache);
3883
3917
  }
3884
- const [assignable, diagnostics] = isTypeAssignableTo(source, target.target, diagnosticTarget);
3918
+ const [assignable, diagnostics] = isTypeAssignableToInternal(source, target.target, diagnosticTarget, relationCache);
3885
3919
  if (!assignable) {
3886
3920
  return [assignable, diagnostics];
3887
3921
  }
3888
3922
  if (!isValueType(source)) {
3889
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3923
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3890
3924
  }
3891
- return [true, []];
3925
+ return [Related.true, []];
3892
3926
  }
3893
3927
  function isReflectionType(type) {
3894
3928
  var _a, _b, _c;
@@ -3971,7 +4005,8 @@ export function createChecker(program) {
3971
4005
  const [low, high, options] = numericRanges[target.name];
3972
4006
  return source.value >= low && source.value <= high && (!options.int || isInt);
3973
4007
  }
3974
- function isModelRelatedTo(source, target, diagnosticTarget) {
4008
+ function isModelRelatedTo(source, target, diagnosticTarget, relationCache) {
4009
+ relationCache.set([source, target], Related.maybe);
3975
4010
  const diagnostics = [];
3976
4011
  for (const prop of walkPropertiesInherited(target)) {
3977
4012
  const sourceProperty = getProperty(source, prop.name);
@@ -3989,27 +4024,27 @@ export function createChecker(program) {
3989
4024
  }
3990
4025
  }
3991
4026
  else {
3992
- const [related, propDiagnostics] = isTypeAssignableTo(sourceProperty.type, prop.type, diagnosticTarget);
4027
+ const [related, propDiagnostics] = isTypeAssignableToInternal(sourceProperty.type, prop.type, diagnosticTarget, relationCache);
3993
4028
  if (!related) {
3994
4029
  diagnostics.push(...propDiagnostics);
3995
4030
  }
3996
4031
  }
3997
4032
  }
3998
- return [diagnostics.length === 0, diagnostics];
4033
+ return [diagnostics.length === 0 ? Related.true : Related.false, diagnostics];
3999
4034
  }
4000
4035
  function getProperty(model, name) {
4001
4036
  var _a;
4002
4037
  return ((_a = model.properties.get(name)) !== null && _a !== void 0 ? _a : (model.baseModel !== undefined ? getProperty(model.baseModel, name) : undefined));
4003
4038
  }
4004
- function isIndexerValid(source, target, diagnosticTarget) {
4039
+ function isIndexerValid(source, target, diagnosticTarget, relationCache) {
4005
4040
  // Model expressions should be able to be assigned.
4006
4041
  if (source.name === "" && target.indexer.key.name !== "integer") {
4007
- return isIndexConstraintValid(target.indexer.value, source, diagnosticTarget);
4042
+ return isIndexConstraintValid(target.indexer.value, source, diagnosticTarget, relationCache);
4008
4043
  }
4009
4044
  else {
4010
4045
  if (source.indexer === undefined || source.indexer.key !== target.indexer.key) {
4011
4046
  return [
4012
- false,
4047
+ Related.false,
4013
4048
  [
4014
4049
  createDiagnostic({
4015
4050
  code: "missing-index",
@@ -4022,7 +4057,7 @@ export function createChecker(program) {
4022
4057
  ],
4023
4058
  ];
4024
4059
  }
4025
- return isTypeAssignableTo(source.indexer.value, target.indexer.value, diagnosticTarget);
4060
+ return isTypeAssignableToInternal(source.indexer.value, target.indexer.value, diagnosticTarget, relationCache);
4026
4061
  }
4027
4062
  }
4028
4063
  /**
@@ -4030,25 +4065,25 @@ export function createChecker(program) {
4030
4065
  * @param type Type of the model that should be respecting the constraint.
4031
4066
  * @param diagnosticTarget Diagnostic target unless something better can be inferred.
4032
4067
  */
4033
- function isIndexConstraintValid(constraintType, type, diagnosticTarget) {
4068
+ function isIndexConstraintValid(constraintType, type, diagnosticTarget, relationCache) {
4034
4069
  for (const prop of type.properties.values()) {
4035
4070
  const [related, diagnostics] = isTypeAssignableTo(prop.type, constraintType, diagnosticTarget);
4036
4071
  if (!related) {
4037
- return [false, diagnostics];
4072
+ return [Related.false, diagnostics];
4038
4073
  }
4039
4074
  }
4040
4075
  if (type.baseModel) {
4041
- const [related, diagnostics] = isIndexConstraintValid(constraintType, type.baseModel, diagnosticTarget);
4076
+ const [related, diagnostics] = isIndexConstraintValid(constraintType, type.baseModel, diagnosticTarget, relationCache);
4042
4077
  if (!related) {
4043
- return [false, diagnostics];
4078
+ return [Related.false, diagnostics];
4044
4079
  }
4045
4080
  }
4046
- return [true, []];
4081
+ return [Related.true, []];
4047
4082
  }
4048
- function isTupleAssignableToTuple(source, target, diagnosticTarget) {
4083
+ function isTupleAssignableToTuple(source, target, diagnosticTarget, relationCache) {
4049
4084
  if (source.values.length !== target.values.length) {
4050
4085
  return [
4051
- false,
4086
+ Related.false,
4052
4087
  [
4053
4088
  createDiagnostic({
4054
4089
  code: "unassignable",
@@ -4065,40 +4100,40 @@ export function createChecker(program) {
4065
4100
  }
4066
4101
  for (const [index, sourceItem] of source.values.entries()) {
4067
4102
  const targetItem = target.values[index];
4068
- const [related, diagnostics] = isTypeAssignableTo(sourceItem, targetItem, diagnosticTarget);
4103
+ const [related, diagnostics] = isTypeAssignableToInternal(sourceItem, targetItem, diagnosticTarget, relationCache);
4069
4104
  if (!related) {
4070
- return [false, diagnostics];
4105
+ return [Related.false, diagnostics];
4071
4106
  }
4072
4107
  }
4073
- return [true, []];
4108
+ return [Related.true, []];
4074
4109
  }
4075
- function isAssignableToUnion(source, target, diagnosticTarget) {
4110
+ function isAssignableToUnion(source, target, diagnosticTarget, relationCache) {
4076
4111
  for (const option of target.variants.values()) {
4077
- const [related] = isTypeAssignableTo(source, option.type, diagnosticTarget);
4112
+ const [related] = isTypeAssignableToInternal(source, option.type, diagnosticTarget, relationCache);
4078
4113
  if (related) {
4079
- return [true, []];
4114
+ return [Related.true, []];
4080
4115
  }
4081
4116
  }
4082
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4117
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4083
4118
  }
4084
4119
  function isAssignableToEnum(source, target, diagnosticTarget) {
4085
4120
  switch (source.kind) {
4086
4121
  case "Enum":
4087
4122
  if (source === target) {
4088
- return [true, []];
4123
+ return [Related.true, []];
4089
4124
  }
4090
4125
  else {
4091
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4126
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4092
4127
  }
4093
4128
  case "EnumMember":
4094
4129
  if (source.enum === target) {
4095
- return [true, []];
4130
+ return [Related.true, []];
4096
4131
  }
4097
4132
  else {
4098
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4133
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4099
4134
  }
4100
4135
  default:
4101
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4136
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4102
4137
  }
4103
4138
  }
4104
4139
  function createUnassignableDiagnostic(source, target, diagnosticTarget) {
@@ -4519,4 +4554,43 @@ const ReflectionNameToKind = {
4519
4554
  UnionVariant: "UnionVariant",
4520
4555
  };
4521
4556
  const _assertReflectionNameToKind = ReflectionNameToKind;
4557
+ var ResolutionKind;
4558
+ (function (ResolutionKind) {
4559
+ ResolutionKind[ResolutionKind["Type"] = 0] = "Type";
4560
+ ResolutionKind[ResolutionKind["BaseType"] = 1] = "BaseType";
4561
+ })(ResolutionKind || (ResolutionKind = {}));
4562
+ class PendingResolutions {
4563
+ constructor() {
4564
+ _PendingResolutions_data.set(this, new Map());
4565
+ }
4566
+ start(symId, kind) {
4567
+ let existing = __classPrivateFieldGet(this, _PendingResolutions_data, "f").get(symId);
4568
+ if (existing === undefined) {
4569
+ existing = new Set();
4570
+ __classPrivateFieldGet(this, _PendingResolutions_data, "f").set(symId, existing);
4571
+ }
4572
+ existing.add(kind);
4573
+ }
4574
+ has(symId, kind) {
4575
+ var _a, _b;
4576
+ return (_b = (_a = __classPrivateFieldGet(this, _PendingResolutions_data, "f").get(symId)) === null || _a === void 0 ? void 0 : _a.has(kind)) !== null && _b !== void 0 ? _b : false;
4577
+ }
4578
+ finish(symId, kind) {
4579
+ const existing = __classPrivateFieldGet(this, _PendingResolutions_data, "f").get(symId);
4580
+ if (existing === undefined) {
4581
+ return;
4582
+ }
4583
+ existing === null || existing === void 0 ? void 0 : existing.delete(kind);
4584
+ if (existing.size === 0) {
4585
+ __classPrivateFieldGet(this, _PendingResolutions_data, "f").delete(symId);
4586
+ }
4587
+ }
4588
+ }
4589
+ _PendingResolutions_data = new WeakMap();
4590
+ var Related;
4591
+ (function (Related) {
4592
+ Related[Related["false"] = 0] = "false";
4593
+ Related[Related["true"] = 1] = "true";
4594
+ Related[Related["maybe"] = 2] = "maybe";
4595
+ })(Related || (Related = {}));
4522
4596
  //# sourceMappingURL=checker.js.map