@typespec/compiler 0.48.0-dev.1 → 0.48.0-dev.12

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 (61) hide show
  1. package/dist/manifest.js +2 -2
  2. package/dist/src/config/config-loader.d.ts +2 -2
  3. package/dist/src/config/config-loader.d.ts.map +1 -1
  4. package/dist/src/config/config-loader.js +27 -15
  5. package/dist/src/config/config-loader.js.map +1 -1
  6. package/dist/src/config/config-to-options.d.ts.map +1 -1
  7. package/dist/src/config/config-to-options.js +2 -2
  8. package/dist/src/config/config-to-options.js.map +1 -1
  9. package/dist/src/core/binder.d.ts.map +1 -1
  10. package/dist/src/core/binder.js +37 -11
  11. package/dist/src/core/binder.js.map +1 -1
  12. package/dist/src/core/checker.d.ts.map +1 -1
  13. package/dist/src/core/checker.js +96 -61
  14. package/dist/src/core/checker.js.map +1 -1
  15. package/dist/src/core/cli/actions/info.js +1 -1
  16. package/dist/src/core/cli/actions/info.js.map +1 -1
  17. package/dist/src/core/cli/cli.js +1 -1
  18. package/dist/src/core/cli/cli.js.map +1 -1
  19. package/dist/src/core/cli/utils.d.ts.map +1 -1
  20. package/dist/src/core/cli/utils.js +6 -2
  21. package/dist/src/core/cli/utils.js.map +1 -1
  22. package/dist/src/core/diagnostics.d.ts +10 -3
  23. package/dist/src/core/diagnostics.d.ts.map +1 -1
  24. package/dist/src/core/diagnostics.js +10 -7
  25. package/dist/src/core/diagnostics.js.map +1 -1
  26. package/dist/src/core/external-error.d.ts +14 -0
  27. package/dist/src/core/external-error.d.ts.map +1 -0
  28. package/dist/src/core/external-error.js +55 -0
  29. package/dist/src/core/external-error.js.map +1 -0
  30. package/dist/src/core/formatter-fs.js +2 -2
  31. package/dist/src/core/logger/logger.js +1 -1
  32. package/dist/src/core/logger/logger.js.map +1 -1
  33. package/dist/src/core/options.d.ts +0 -1
  34. package/dist/src/core/options.d.ts.map +1 -1
  35. package/dist/src/core/parser.d.ts.map +1 -1
  36. package/dist/src/core/parser.js +2 -0
  37. package/dist/src/core/parser.js.map +1 -1
  38. package/dist/src/core/program.d.ts +1 -1
  39. package/dist/src/core/program.d.ts.map +1 -1
  40. package/dist/src/core/program.js +28 -36
  41. package/dist/src/core/program.js.map +1 -1
  42. package/dist/src/core/types.d.ts +9 -3
  43. package/dist/src/core/types.d.ts.map +1 -1
  44. package/dist/src/core/types.js +1 -0
  45. package/dist/src/core/types.js.map +1 -1
  46. package/dist/src/core/util.d.ts +0 -2
  47. package/dist/src/core/util.d.ts.map +1 -1
  48. package/dist/src/core/util.js +0 -2
  49. package/dist/src/core/util.js.map +1 -1
  50. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  51. package/dist/src/formatter/print/printer.js +1 -0
  52. package/dist/src/formatter/print/printer.js.map +1 -1
  53. package/dist/src/lib/decorators.d.ts +14 -0
  54. package/dist/src/lib/decorators.d.ts.map +1 -1
  55. package/dist/src/lib/decorators.js +26 -0
  56. package/dist/src/lib/decorators.js.map +1 -1
  57. package/dist/src/server/serverlib.js +2 -2
  58. package/dist/src/server/serverlib.js.map +1 -1
  59. package/lib/decorators.tsp +13 -0
  60. package/lib/lib.tsp +1 -1
  61. package/package.json +1 -1
@@ -342,6 +342,7 @@ export function createChecker(program) {
342
342
  case SyntaxKind.UnionVariant:
343
343
  return checkUnionVariant(node, mapper);
344
344
  case SyntaxKind.NamespaceStatement:
345
+ case SyntaxKind.JsNamespaceDeclaration:
345
346
  return checkNamespace(node);
346
347
  case SyntaxKind.OperationStatement:
347
348
  return checkOperation(node, mapper);
@@ -987,12 +988,14 @@ export function createChecker(program) {
987
988
  if (!type) {
988
989
  type = initializeTypeForNamespace(node);
989
990
  }
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);
991
+ if (node.kind === SyntaxKind.NamespaceStatement) {
992
+ if (isArray(node.statements)) {
993
+ node.statements.forEach((x) => getTypeForNode(x));
994
+ }
995
+ else if (node.statements) {
996
+ const subNs = checkNamespace(node.statements);
997
+ type.namespaces.set(subNs.name, subNs);
998
+ }
996
999
  }
997
1000
  return type;
998
1001
  }
@@ -1008,7 +1011,7 @@ export function createChecker(program) {
1008
1011
  kind: "Namespace",
1009
1012
  name,
1010
1013
  namespace,
1011
- node,
1014
+ node: node,
1012
1015
  models: new Map(),
1013
1016
  scalars: new Map(),
1014
1017
  operations: new Map(),
@@ -1074,7 +1077,7 @@ export function createChecker(program) {
1074
1077
  // However, one case where this is not true is when a decorator on a namespace
1075
1078
  // refers to a model in another namespace. In this case, we need to evaluate
1076
1079
  // the namespace here.
1077
- const namespaceNode = mergedSymbol.declarations.find((x) => x.kind === SyntaxKind.NamespaceStatement);
1080
+ const namespaceNode = mergedSymbol.declarations.find((x) => x.kind === SyntaxKind.NamespaceStatement || x.kind === SyntaxKind.JsNamespaceDeclaration);
1078
1081
  compilerAssert(namespaceNode, "Can't find namespace declaration node.", node);
1079
1082
  symbolLinks.type = initializeTypeForNamespace(namespaceNode);
1080
1083
  }
@@ -1645,7 +1648,7 @@ export function createChecker(program) {
1645
1648
  default:
1646
1649
  // get the symbol from the node aliased type's node, or just return the base
1647
1650
  // 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;
1651
+ return (_a = getMergedSymbol(aliasType.node.symbol)) !== null && _a !== void 0 ? _a : aliasSymbol;
1649
1652
  }
1650
1653
  }
1651
1654
  function checkStringLiteral(str) {
@@ -1830,11 +1833,23 @@ export function createChecker(program) {
1830
1833
  checkModelProperties(node, properties, type, mapper);
1831
1834
  return finishType(type);
1832
1835
  }
1836
+ /** Find the indexer that applies to this model. Either defined on itself or from a base model */
1837
+ function findIndexer(model) {
1838
+ let current = model;
1839
+ while (current) {
1840
+ if (current.indexer) {
1841
+ return current.indexer;
1842
+ }
1843
+ current = current.baseModel;
1844
+ }
1845
+ return undefined;
1846
+ }
1833
1847
  function checkPropertyCompatibleWithIndexer(parentModel, property, diagnosticTarget) {
1834
- if (parentModel.indexer === undefined) {
1848
+ const indexer = findIndexer(parentModel);
1849
+ if (indexer === undefined) {
1835
1850
  return;
1836
1851
  }
1837
- const [valid, diagnostics] = isTypeAssignableTo(property.type, parentModel.indexer.value, diagnosticTarget.kind === SyntaxKind.ModelSpreadProperty
1852
+ const [valid, diagnostics] = isTypeAssignableTo(property.type, indexer.value, diagnosticTarget.kind === SyntaxKind.ModelSpreadProperty
1838
1853
  ? diagnosticTarget
1839
1854
  : diagnosticTarget.value);
1840
1855
  if (!valid)
@@ -3782,42 +3797,55 @@ export function createChecker(program) {
3782
3797
  * @param diagnosticTarget Target for the diagnostic, unless something better can be inferred.
3783
3798
  */
3784
3799
  function isTypeAssignableTo(source, target, diagnosticTarget) {
3800
+ const [related, diagnostics] = isTypeAssignableToInternal(source, target, diagnosticTarget, new MultiKeyMap());
3801
+ return [related === Related.true, diagnostics];
3802
+ }
3803
+ function isTypeAssignableToInternal(source, target, diagnosticTarget, relationCache) {
3804
+ const cached = relationCache.get([source, target]);
3805
+ if (cached !== undefined) {
3806
+ return [cached, []];
3807
+ }
3808
+ const [result, diagnostics] = isTypeAssignableToWorker(source, target, diagnosticTarget, new MultiKeyMap());
3809
+ relationCache.set([source, target], result);
3810
+ return [result, diagnostics];
3811
+ }
3812
+ function isTypeAssignableToWorker(source, target, diagnosticTarget, relationCache) {
3785
3813
  var _a;
3786
3814
  // BACKCOMPAT: Added May 2023 sprint, to be removed by June 2023 sprint
3787
3815
  if (source.kind === "TemplateParameter" && source.constraint && target.kind === "Value") {
3788
- const [assignable] = isTypeAssignableTo(source.constraint, target.target, diagnosticTarget);
3816
+ const [assignable] = isTypeAssignableToInternal(source.constraint, target.target, diagnosticTarget, relationCache);
3789
3817
  if (assignable) {
3790
3818
  const constraint = getTypeName(source.constraint);
3791
3819
  reportDeprecated(program, `Template constrainted to '${constraint}' will not be assignable to '${getTypeName(target)}' in the future. Update the constraint to be 'valueof ${constraint}'`, diagnosticTarget);
3792
- return [true, []];
3820
+ return [Related.true, []];
3793
3821
  }
3794
3822
  }
3795
3823
  if (source.kind === "TemplateParameter") {
3796
3824
  source = (_a = source.constraint) !== null && _a !== void 0 ? _a : unknownType;
3797
3825
  }
3798
3826
  if (source === target)
3799
- return [true, []];
3827
+ return [Related.true, []];
3800
3828
  if (target.kind === "Value") {
3801
- return isAssignableToValueType(source, target, diagnosticTarget);
3829
+ return isAssignableToValueType(source, target, diagnosticTarget, relationCache);
3802
3830
  }
3803
3831
  if (source.kind === "Value") {
3804
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3832
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3805
3833
  }
3806
3834
  const isSimpleTypeRelated = isSimpleTypeAssignableTo(source, target);
3807
3835
  if (isSimpleTypeRelated === true) {
3808
- return [true, []];
3836
+ return [Related.true, []];
3809
3837
  }
3810
3838
  else if (isSimpleTypeRelated === false) {
3811
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3839
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3812
3840
  }
3813
3841
  if (source.kind === "Union") {
3814
3842
  for (const variant of source.variants.values()) {
3815
- const [variantAssignable] = isTypeAssignableTo(variant.type, target, diagnosticTarget);
3843
+ const [variantAssignable] = isTypeAssignableToInternal(variant.type, target, diagnosticTarget, relationCache);
3816
3844
  if (!variantAssignable) {
3817
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3845
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3818
3846
  }
3819
3847
  }
3820
- return [true, []];
3848
+ return [Related.true, []];
3821
3849
  }
3822
3850
  if (target.kind === "Model" &&
3823
3851
  source.kind === "Model" &&
@@ -3826,7 +3854,7 @@ export function createChecker(program) {
3826
3854
  source.indexer &&
3827
3855
  source.indexer.key.name === "integer") {
3828
3856
  return [
3829
- false,
3857
+ Related.false,
3830
3858
  [
3831
3859
  createDiagnostic({
3832
3860
  code: "missing-index",
@@ -3840,43 +3868,43 @@ export function createChecker(program) {
3840
3868
  ];
3841
3869
  }
3842
3870
  else if (target.kind === "Model" && target.indexer !== undefined && source.kind === "Model") {
3843
- return isIndexerValid(source, target, diagnosticTarget);
3871
+ return isIndexerValid(source, target, diagnosticTarget, relationCache);
3844
3872
  }
3845
3873
  else if (target.kind === "Model" && source.kind === "Model") {
3846
- return isModelRelatedTo(source, target, diagnosticTarget);
3874
+ return isModelRelatedTo(source, target, diagnosticTarget, relationCache);
3847
3875
  }
3848
3876
  else if (target.kind === "Model" && target.indexer && source.kind === "Tuple") {
3849
3877
  for (const item of source.values) {
3850
- const [related, diagnostics] = isTypeAssignableTo(item, target.indexer.value, diagnosticTarget);
3878
+ const [related, diagnostics] = isTypeAssignableToInternal(item, target.indexer.value, diagnosticTarget, relationCache);
3851
3879
  if (!related) {
3852
- return [false, diagnostics];
3880
+ return [Related.false, diagnostics];
3853
3881
  }
3854
3882
  }
3855
- return [true, []];
3883
+ return [Related.true, []];
3856
3884
  }
3857
3885
  else if (target.kind === "Tuple" && source.kind === "Tuple") {
3858
- return isTupleAssignableToTuple(source, target, diagnosticTarget);
3886
+ return isTupleAssignableToTuple(source, target, diagnosticTarget, relationCache);
3859
3887
  }
3860
3888
  else if (target.kind === "Union") {
3861
- return isAssignableToUnion(source, target, diagnosticTarget);
3889
+ return isAssignableToUnion(source, target, diagnosticTarget, relationCache);
3862
3890
  }
3863
3891
  else if (target.kind === "Enum") {
3864
3892
  return isAssignableToEnum(source, target, diagnosticTarget);
3865
3893
  }
3866
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3894
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3867
3895
  }
3868
- function isAssignableToValueType(source, target, diagnosticTarget) {
3896
+ function isAssignableToValueType(source, target, diagnosticTarget, relationCache) {
3869
3897
  if (source.kind === "Value") {
3870
- return isTypeAssignableTo(source.target, target.target, diagnosticTarget);
3898
+ return isTypeAssignableToInternal(source.target, target.target, diagnosticTarget, relationCache);
3871
3899
  }
3872
- const [assignable, diagnostics] = isTypeAssignableTo(source, target.target, diagnosticTarget);
3900
+ const [assignable, diagnostics] = isTypeAssignableToInternal(source, target.target, diagnosticTarget, relationCache);
3873
3901
  if (!assignable) {
3874
3902
  return [assignable, diagnostics];
3875
3903
  }
3876
3904
  if (!isValueType(source)) {
3877
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3905
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3878
3906
  }
3879
- return [true, []];
3907
+ return [Related.true, []];
3880
3908
  }
3881
3909
  function isReflectionType(type) {
3882
3910
  var _a, _b, _c;
@@ -3959,7 +3987,8 @@ export function createChecker(program) {
3959
3987
  const [low, high, options] = numericRanges[target.name];
3960
3988
  return source.value >= low && source.value <= high && (!options.int || isInt);
3961
3989
  }
3962
- function isModelRelatedTo(source, target, diagnosticTarget) {
3990
+ function isModelRelatedTo(source, target, diagnosticTarget, relationCache) {
3991
+ relationCache.set([source, target], Related.maybe);
3963
3992
  const diagnostics = [];
3964
3993
  for (const prop of walkPropertiesInherited(target)) {
3965
3994
  const sourceProperty = getProperty(source, prop.name);
@@ -3977,27 +4006,27 @@ export function createChecker(program) {
3977
4006
  }
3978
4007
  }
3979
4008
  else {
3980
- const [related, propDiagnostics] = isTypeAssignableTo(sourceProperty.type, prop.type, diagnosticTarget);
4009
+ const [related, propDiagnostics] = isTypeAssignableToInternal(sourceProperty.type, prop.type, diagnosticTarget, relationCache);
3981
4010
  if (!related) {
3982
4011
  diagnostics.push(...propDiagnostics);
3983
4012
  }
3984
4013
  }
3985
4014
  }
3986
- return [diagnostics.length === 0, diagnostics];
4015
+ return [diagnostics.length === 0 ? Related.true : Related.false, diagnostics];
3987
4016
  }
3988
4017
  function getProperty(model, name) {
3989
4018
  var _a;
3990
4019
  return ((_a = model.properties.get(name)) !== null && _a !== void 0 ? _a : (model.baseModel !== undefined ? getProperty(model.baseModel, name) : undefined));
3991
4020
  }
3992
- function isIndexerValid(source, target, diagnosticTarget) {
4021
+ function isIndexerValid(source, target, diagnosticTarget, relationCache) {
3993
4022
  // Model expressions should be able to be assigned.
3994
4023
  if (source.name === "" && target.indexer.key.name !== "integer") {
3995
- return isIndexConstraintValid(target.indexer.value, source, diagnosticTarget);
4024
+ return isIndexConstraintValid(target.indexer.value, source, diagnosticTarget, relationCache);
3996
4025
  }
3997
4026
  else {
3998
4027
  if (source.indexer === undefined || source.indexer.key !== target.indexer.key) {
3999
4028
  return [
4000
- false,
4029
+ Related.false,
4001
4030
  [
4002
4031
  createDiagnostic({
4003
4032
  code: "missing-index",
@@ -4010,7 +4039,7 @@ export function createChecker(program) {
4010
4039
  ],
4011
4040
  ];
4012
4041
  }
4013
- return isTypeAssignableTo(source.indexer.value, target.indexer.value, diagnosticTarget);
4042
+ return isTypeAssignableToInternal(source.indexer.value, target.indexer.value, diagnosticTarget, relationCache);
4014
4043
  }
4015
4044
  }
4016
4045
  /**
@@ -4018,25 +4047,25 @@ export function createChecker(program) {
4018
4047
  * @param type Type of the model that should be respecting the constraint.
4019
4048
  * @param diagnosticTarget Diagnostic target unless something better can be inferred.
4020
4049
  */
4021
- function isIndexConstraintValid(constraintType, type, diagnosticTarget) {
4050
+ function isIndexConstraintValid(constraintType, type, diagnosticTarget, relationCache) {
4022
4051
  for (const prop of type.properties.values()) {
4023
4052
  const [related, diagnostics] = isTypeAssignableTo(prop.type, constraintType, diagnosticTarget);
4024
4053
  if (!related) {
4025
- return [false, diagnostics];
4054
+ return [Related.false, diagnostics];
4026
4055
  }
4027
4056
  }
4028
4057
  if (type.baseModel) {
4029
- const [related, diagnostics] = isIndexConstraintValid(constraintType, type.baseModel, diagnosticTarget);
4058
+ const [related, diagnostics] = isIndexConstraintValid(constraintType, type.baseModel, diagnosticTarget, relationCache);
4030
4059
  if (!related) {
4031
- return [false, diagnostics];
4060
+ return [Related.false, diagnostics];
4032
4061
  }
4033
4062
  }
4034
- return [true, []];
4063
+ return [Related.true, []];
4035
4064
  }
4036
- function isTupleAssignableToTuple(source, target, diagnosticTarget) {
4065
+ function isTupleAssignableToTuple(source, target, diagnosticTarget, relationCache) {
4037
4066
  if (source.values.length !== target.values.length) {
4038
4067
  return [
4039
- false,
4068
+ Related.false,
4040
4069
  [
4041
4070
  createDiagnostic({
4042
4071
  code: "unassignable",
@@ -4053,40 +4082,40 @@ export function createChecker(program) {
4053
4082
  }
4054
4083
  for (const [index, sourceItem] of source.values.entries()) {
4055
4084
  const targetItem = target.values[index];
4056
- const [related, diagnostics] = isTypeAssignableTo(sourceItem, targetItem, diagnosticTarget);
4085
+ const [related, diagnostics] = isTypeAssignableToInternal(sourceItem, targetItem, diagnosticTarget, relationCache);
4057
4086
  if (!related) {
4058
- return [false, diagnostics];
4087
+ return [Related.false, diagnostics];
4059
4088
  }
4060
4089
  }
4061
- return [true, []];
4090
+ return [Related.true, []];
4062
4091
  }
4063
- function isAssignableToUnion(source, target, diagnosticTarget) {
4092
+ function isAssignableToUnion(source, target, diagnosticTarget, relationCache) {
4064
4093
  for (const option of target.variants.values()) {
4065
- const [related] = isTypeAssignableTo(source, option.type, diagnosticTarget);
4094
+ const [related] = isTypeAssignableToInternal(source, option.type, diagnosticTarget, relationCache);
4066
4095
  if (related) {
4067
- return [true, []];
4096
+ return [Related.true, []];
4068
4097
  }
4069
4098
  }
4070
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4099
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4071
4100
  }
4072
4101
  function isAssignableToEnum(source, target, diagnosticTarget) {
4073
4102
  switch (source.kind) {
4074
4103
  case "Enum":
4075
4104
  if (source === target) {
4076
- return [true, []];
4105
+ return [Related.true, []];
4077
4106
  }
4078
4107
  else {
4079
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4108
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4080
4109
  }
4081
4110
  case "EnumMember":
4082
4111
  if (source.enum === target) {
4083
- return [true, []];
4112
+ return [Related.true, []];
4084
4113
  }
4085
4114
  else {
4086
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4115
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4087
4116
  }
4088
4117
  default:
4089
- return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4118
+ return [Related.false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
4090
4119
  }
4091
4120
  }
4092
4121
  function createUnassignableDiagnostic(source, target, diagnosticTarget) {
@@ -4507,4 +4536,10 @@ const ReflectionNameToKind = {
4507
4536
  UnionVariant: "UnionVariant",
4508
4537
  };
4509
4538
  const _assertReflectionNameToKind = ReflectionNameToKind;
4539
+ var Related;
4540
+ (function (Related) {
4541
+ Related[Related["false"] = 0] = "false";
4542
+ Related[Related["true"] = 1] = "true";
4543
+ Related[Related["maybe"] = 2] = "maybe";
4544
+ })(Related || (Related = {}));
4510
4545
  //# sourceMappingURL=checker.js.map