@typespec/compiler 0.47.0-dev.8 → 0.48.0-dev.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 (119) hide show
  1. package/dist/manifest.js +2 -2
  2. package/dist/src/config/config-to-options.d.ts +31 -0
  3. package/dist/src/config/config-to-options.d.ts.map +1 -0
  4. package/dist/src/config/config-to-options.js +55 -0
  5. package/dist/src/config/config-to-options.js.map +1 -0
  6. package/dist/src/config/index.d.ts +1 -0
  7. package/dist/src/config/index.d.ts.map +1 -1
  8. package/dist/src/config/index.js +1 -0
  9. package/dist/src/config/index.js.map +1 -1
  10. package/dist/src/core/checker.d.ts.map +1 -1
  11. package/dist/src/core/checker.js +254 -85
  12. package/dist/src/core/checker.js.map +1 -1
  13. package/dist/src/core/cli/actions/compile/args.d.ts +1 -0
  14. package/dist/src/core/cli/actions/compile/args.d.ts.map +1 -1
  15. package/dist/src/core/cli/actions/compile/args.js +27 -64
  16. package/dist/src/core/cli/actions/compile/args.js.map +1 -1
  17. package/dist/src/core/cli/actions/compile/compile.d.ts.map +1 -1
  18. package/dist/src/core/cli/actions/compile/compile.js +59 -51
  19. package/dist/src/core/cli/actions/compile/compile.js.map +1 -1
  20. package/dist/src/core/cli/actions/compile/watch.d.ts +15 -0
  21. package/dist/src/core/cli/actions/compile/watch.d.ts.map +1 -0
  22. package/dist/src/core/cli/actions/compile/watch.js +59 -0
  23. package/dist/src/core/cli/actions/compile/watch.js.map +1 -0
  24. package/dist/src/core/cli/cli.js +5 -0
  25. package/dist/src/core/cli/cli.js.map +1 -1
  26. package/dist/src/core/deprecation.d.ts +31 -0
  27. package/dist/src/core/deprecation.d.ts.map +1 -0
  28. package/dist/src/core/deprecation.js +48 -0
  29. package/dist/src/core/deprecation.js.map +1 -0
  30. package/dist/src/core/formatter-fs.js +4 -4
  31. package/dist/src/core/formatter-fs.js.map +1 -1
  32. package/dist/src/core/formatter.d.ts +3 -3
  33. package/dist/src/core/formatter.d.ts.map +1 -1
  34. package/dist/src/core/formatter.js +4 -4
  35. package/dist/src/core/formatter.js.map +1 -1
  36. package/dist/src/core/index.d.ts +1 -0
  37. package/dist/src/core/index.d.ts.map +1 -1
  38. package/dist/src/core/index.js +1 -0
  39. package/dist/src/core/index.js.map +1 -1
  40. package/dist/src/core/messages.d.ts +43 -17
  41. package/dist/src/core/messages.d.ts.map +1 -1
  42. package/dist/src/core/messages.js +13 -3
  43. package/dist/src/core/messages.js.map +1 -1
  44. package/dist/src/core/module-resolver.d.ts.map +1 -1
  45. package/dist/src/core/module-resolver.js.map +1 -1
  46. package/dist/src/core/options.d.ts +4 -0
  47. package/dist/src/core/options.d.ts.map +1 -1
  48. package/dist/src/core/parser.d.ts.map +1 -1
  49. package/dist/src/core/parser.js +36 -9
  50. package/dist/src/core/parser.js.map +1 -1
  51. package/dist/src/core/program.d.ts.map +1 -1
  52. package/dist/src/core/program.js +2 -0
  53. package/dist/src/core/program.js.map +1 -1
  54. package/dist/src/core/types.d.ts +6 -2
  55. package/dist/src/core/types.d.ts.map +1 -1
  56. package/dist/src/core/types.js.map +1 -1
  57. package/dist/src/emitter-framework/builders/object-builder.d.ts.map +1 -1
  58. package/dist/src/emitter-framework/builders/object-builder.js +1 -0
  59. package/dist/src/emitter-framework/builders/object-builder.js.map +1 -1
  60. package/dist/src/emitter-framework/type-emitter.d.ts +4 -4
  61. package/dist/src/emitter-framework/type-emitter.d.ts.map +1 -1
  62. package/dist/src/emitter-framework/type-emitter.js +12 -12
  63. package/dist/src/emitter-framework/type-emitter.js.map +1 -1
  64. package/dist/src/emitter-framework/types.d.ts.map +1 -1
  65. package/dist/src/emitter-framework/types.js.map +1 -1
  66. package/dist/src/formatter/index.d.ts +1 -1
  67. package/dist/src/formatter/index.d.ts.map +1 -1
  68. package/dist/src/formatter/parser.d.ts +2 -6
  69. package/dist/src/formatter/parser.d.ts.map +1 -1
  70. package/dist/src/formatter/parser.js +1 -1
  71. package/dist/src/formatter/parser.js.map +1 -1
  72. package/dist/src/formatter/print/comment-handler.d.ts +1 -1
  73. package/dist/src/formatter/print/comment-handler.d.ts.map +1 -1
  74. package/dist/src/formatter/print/comment-handler.js +1 -2
  75. package/dist/src/formatter/print/comment-handler.js.map +1 -1
  76. package/dist/src/formatter/print/needs-parens.d.ts +1 -1
  77. package/dist/src/formatter/print/needs-parens.d.ts.map +1 -1
  78. package/dist/src/formatter/print/needs-parens.js +1 -0
  79. package/dist/src/formatter/print/needs-parens.js.map +1 -1
  80. package/dist/src/formatter/print/printer.d.ts +41 -40
  81. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  82. package/dist/src/formatter/print/printer.js +6 -4
  83. package/dist/src/formatter/print/printer.js.map +1 -1
  84. package/dist/src/formatter/print/types.d.ts +3 -3
  85. package/dist/src/formatter/print/types.d.ts.map +1 -1
  86. package/dist/src/formatter/print/util.d.ts +3 -0
  87. package/dist/src/formatter/print/util.d.ts.map +1 -0
  88. package/dist/src/formatter/print/util.js +3 -0
  89. package/dist/src/formatter/print/util.js.map +1 -0
  90. package/dist/src/index.d.ts +1 -0
  91. package/dist/src/index.d.ts.map +1 -1
  92. package/dist/src/index.js +1 -0
  93. package/dist/src/index.js.map +1 -1
  94. package/dist/src/init/init-template.d.ts +19 -1
  95. package/dist/src/init/init-template.d.ts.map +1 -1
  96. package/dist/src/init/init-template.js +15 -1
  97. package/dist/src/init/init-template.js.map +1 -1
  98. package/dist/src/init/init.d.ts +4 -4
  99. package/dist/src/init/init.d.ts.map +1 -1
  100. package/dist/src/init/init.js +40 -11
  101. package/dist/src/init/init.js.map +1 -1
  102. package/dist/src/lib/decorators.d.ts +1 -7
  103. package/dist/src/lib/decorators.d.ts.map +1 -1
  104. package/dist/src/lib/decorators.js +4 -11
  105. package/dist/src/lib/decorators.js.map +1 -1
  106. package/dist/src/server/completion.d.ts.map +1 -1
  107. package/dist/src/server/completion.js +9 -5
  108. package/dist/src/server/completion.js.map +1 -1
  109. package/dist/src/server/serverlib.d.ts.map +1 -1
  110. package/dist/src/server/serverlib.js +4 -2
  111. package/dist/src/server/serverlib.js.map +1 -1
  112. package/dist/src/server/symbol-structure.d.ts.map +1 -1
  113. package/dist/src/server/symbol-structure.js +3 -1
  114. package/dist/src/server/symbol-structure.js.map +1 -1
  115. package/dist/src/testing/types.d.ts.map +1 -1
  116. package/dist/src/testing/types.js.map +1 -1
  117. package/lib/decorators.tsp +8 -2
  118. package/lib/lib.tsp +1 -1
  119. package/package.json +5 -7
@@ -1,5 +1,6 @@
1
- import { $docFromComment, getDeprecated, getIndexer } from "../lib/decorators.js";
1
+ import { $docFromComment, getIndexer } from "../lib/decorators.js";
2
2
  import { createSymbol, createSymbolTable } from "./binder.js";
3
+ import { getDeprecationDetails, markDeprecated } from "./deprecation.js";
3
4
  import { ProjectionError, compilerAssert, reportDeprecated } from "./diagnostics.js";
4
5
  import { validateInheritanceDiscriminatedUnions } from "./helpers/discriminator-utils.js";
5
6
  import { getNamespaceFullName, getTypeName } from "./helpers/index.js";
@@ -170,6 +171,7 @@ export function createChecker(program) {
170
171
  }
171
172
  if (!(sym.flags & 4096 /* SymbolFlags.Namespace */)) {
172
173
  reportCheckerDiagnostic(createDiagnostic({ code: "using-invalid-ref", target: using }));
174
+ continue;
173
175
  }
174
176
  const namespaceSym = getMergedSymbol(sym);
175
177
  if (usedUsing.has(namespaceSym)) {
@@ -487,7 +489,6 @@ export function createChecker(program) {
487
489
  return errorType;
488
490
  }
489
491
  const type = checkTypeReferenceSymbol(sym, node, mapper, instantiateTemplate);
490
- checkDeprecated(type, node);
491
492
  return type;
492
493
  }
493
494
  function resolveTypeReference(node) {
@@ -498,16 +499,23 @@ export function createChecker(program) {
498
499
  onCheckerDiagnostic = oldDiagnosticHook;
499
500
  return [type === errorType ? undefined : type, diagnostics];
500
501
  }
501
- function checkDeprecated(type, target) {
502
- const deprecated = getDeprecated(program, type);
503
- if (deprecated) {
504
- reportCheckerDiagnostic(createDiagnostic({
505
- code: "deprecated",
506
- format: {
507
- message: deprecated,
508
- },
509
- target,
510
- }));
502
+ function copyDeprecation(sourceType, destType) {
503
+ const deprecationDetails = getDeprecationDetails(program, sourceType);
504
+ if (deprecationDetails) {
505
+ markDeprecated(program, destType, deprecationDetails);
506
+ }
507
+ }
508
+ function checkDeprecated(type, node, target) {
509
+ if (node) {
510
+ const deprecationDetails = getDeprecationDetails(program, node);
511
+ if (deprecationDetails) {
512
+ reportDeprecation(program, target, deprecationDetails.message, reportCheckerDiagnostic);
513
+ return;
514
+ }
515
+ }
516
+ const deprecationDetails = getDeprecationDetails(program, type);
517
+ if (deprecationDetails) {
518
+ reportDeprecation(program, target, deprecationDetails.message, reportCheckerDiagnostic);
511
519
  }
512
520
  }
513
521
  function checkTypeReferenceArgs(node, mapper) {
@@ -665,6 +673,11 @@ export function createChecker(program) {
665
673
  }
666
674
  }
667
675
  }
676
+ // Check for deprecations here, first on symbol, then on type.
677
+ const declarationNode = sym === null || sym === void 0 ? void 0 : sym.declarations[0];
678
+ if (declarationNode && mapper === undefined) {
679
+ checkDeprecated(baseType, declarationNode, node);
680
+ }
668
681
  return baseType;
669
682
  }
670
683
  /**
@@ -1070,7 +1083,8 @@ export function createChecker(program) {
1070
1083
  function checkOperation(node, mapper, parentInterface) {
1071
1084
  var _a;
1072
1085
  const inInterface = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.kind) === SyntaxKind.InterfaceStatement;
1073
- const links = inInterface ? getSymbolLinksForMember(node) : getSymbolLinks(node.symbol);
1086
+ const symbol = inInterface ? getSymbolForMember(node) : node.symbol;
1087
+ const links = symbol && getSymbolLinks(symbol);
1074
1088
  if (links) {
1075
1089
  if (links.declaredType && mapper === undefined) {
1076
1090
  // we're not instantiating this operation and we've already checked it
@@ -1080,6 +1094,7 @@ export function createChecker(program) {
1080
1094
  if (mapper === undefined && inInterface) {
1081
1095
  compilerAssert(parentInterface, "Operation in interface should already have been checked.");
1082
1096
  }
1097
+ checkTemplateDeclaration(node, mapper);
1083
1098
  // If we are instantating operation inside of interface
1084
1099
  if (isTemplatedNode(node) && mapper !== undefined && parentInterface) {
1085
1100
  mapper = { ...mapper, partial: true };
@@ -1096,8 +1111,19 @@ export function createChecker(program) {
1096
1111
  return errorType;
1097
1112
  }
1098
1113
  sourceOperation = baseOperation;
1114
+ const parameterModelSym = getOrCreateAugmentedSymbolTable(symbol.metatypeMembers).get("parameters");
1099
1115
  // Reference the same return type and create the parameters type
1100
- parameters = cloneType(baseOperation.parameters);
1116
+ const clone = initializeClone(baseOperation.parameters, {
1117
+ properties: createRekeyableMap(),
1118
+ });
1119
+ clone.properties = createRekeyableMap(Array.from(baseOperation.parameters.properties.entries()).map(([key, prop]) => [
1120
+ key,
1121
+ cloneTypeForSymbol(getMemberSymbol(parameterModelSym, prop.name), prop, {
1122
+ model: clone,
1123
+ sourceProperty: prop,
1124
+ }),
1125
+ ]));
1126
+ parameters = finishType(clone);
1101
1127
  returnType = baseOperation.returnType;
1102
1128
  // Copy decorators from the base operation, inserting the base decorators first
1103
1129
  decorators = [...baseOperation.decorators];
@@ -1567,6 +1593,14 @@ export function createChecker(program) {
1567
1593
  }
1568
1594
  function resolveMetaProperty(node, base) {
1569
1595
  const resolved = resolveIdentifierInTable(node.id, base.metatypeMembers);
1596
+ if (!resolved) {
1597
+ reportCheckerDiagnostic(createDiagnostic({
1598
+ code: "invalid-ref",
1599
+ messageId: "metaProperty",
1600
+ format: { kind: getMemberKindName(base.declarations[0]), id: node.id.sv },
1601
+ target: node,
1602
+ }));
1603
+ }
1570
1604
  return resolved;
1571
1605
  }
1572
1606
  function getMemberKindName(node) {
@@ -1574,6 +1608,8 @@ export function createChecker(program) {
1574
1608
  case SyntaxKind.ModelStatement:
1575
1609
  case SyntaxKind.ModelExpression:
1576
1610
  return "Model";
1611
+ case SyntaxKind.ModelProperty:
1612
+ return "ModelProperty";
1577
1613
  case SyntaxKind.EnumStatement:
1578
1614
  return "Enum";
1579
1615
  case SyntaxKind.InterfaceStatement:
@@ -1672,6 +1708,19 @@ export function createChecker(program) {
1672
1708
  getTypeForNode(statement, undefined);
1673
1709
  }
1674
1710
  }
1711
+ /**
1712
+ * Check that the given node template parameters are valid if applicable.
1713
+ * @param node Node with template parameters
1714
+ * @param mapper Type mapper, set if instantiating the template, undefined otherwise.
1715
+ */
1716
+ function checkTemplateDeclaration(node, mapper) {
1717
+ // If mapper is undefined it means we are checking the declaration of the template.
1718
+ if (mapper === undefined) {
1719
+ for (const templateParameter of node.templateParameters) {
1720
+ checkTemplateParameterDeclaration(templateParameter, undefined);
1721
+ }
1722
+ }
1723
+ }
1675
1724
  function checkModel(node, mapper) {
1676
1725
  if (node.kind === SyntaxKind.ModelStatement) {
1677
1726
  return checkModelStatement(node, mapper);
@@ -1687,6 +1736,7 @@ export function createChecker(program) {
1687
1736
  // we're not instantiating this model and we've already checked it
1688
1737
  return links.declaredType;
1689
1738
  }
1739
+ checkTemplateDeclaration(node, mapper);
1690
1740
  const decorators = [];
1691
1741
  const type = createType({
1692
1742
  kind: "Model",
@@ -1701,7 +1751,6 @@ export function createChecker(program) {
1701
1751
  const isBase = checkModelIs(node, node.is, mapper);
1702
1752
  if (isBase) {
1703
1753
  type.sourceModel = isBase;
1704
- checkDeprecated(isBase, node.is);
1705
1754
  // copy decorators
1706
1755
  decorators.push(...isBase.decorators);
1707
1756
  if (isBase.indexer) {
@@ -1725,7 +1774,7 @@ export function createChecker(program) {
1725
1774
  else if (node.extends) {
1726
1775
  type.baseModel = checkClassHeritage(node, node.extends, mapper);
1727
1776
  if (type.baseModel) {
1728
- checkDeprecated(type.baseModel, node.extends);
1777
+ copyDeprecation(type.baseModel, type);
1729
1778
  }
1730
1779
  }
1731
1780
  if (type.baseModel) {
@@ -1738,13 +1787,6 @@ export function createChecker(program) {
1738
1787
  }
1739
1788
  // Evaluate the properties after
1740
1789
  checkModelProperties(node, type.properties, type, mapper);
1741
- for (const prop of walkPropertiesInherited(type)) {
1742
- const table = getOrCreateAugmentedSymbolTable(node.symbol.members);
1743
- const sym = table.get(prop.name);
1744
- if (sym) {
1745
- mutate(sym).type = prop;
1746
- }
1747
- }
1748
1790
  linkMapper(type, mapper);
1749
1791
  if (shouldCreateTypeForTemplate(node, mapper)) {
1750
1792
  finishType(type);
@@ -1808,7 +1850,7 @@ export function createChecker(program) {
1808
1850
  }
1809
1851
  else {
1810
1852
  // spread property
1811
- const newProperties = checkSpreadProperty(prop.target, parentModel, mapper);
1853
+ const newProperties = checkSpreadProperty(node.symbol, prop.target, parentModel, mapper);
1812
1854
  for (const newProp of newProperties) {
1813
1855
  linkIndirectMember(node, newProp, mapper);
1814
1856
  checkPropertyCompatibleWithIndexer(parentModel, newProp, prop);
@@ -1908,6 +1950,9 @@ export function createChecker(program) {
1908
1950
  break;
1909
1951
  case SyntaxKind.UnionStatement:
1910
1952
  for (const variant of node.options.values()) {
1953
+ if (!variant.id) {
1954
+ continue;
1955
+ }
1911
1956
  const name = variant.id.sv;
1912
1957
  bindMember(name, variant, 1024 /* SymbolFlags.UnionVariant */);
1913
1958
  }
@@ -1953,40 +1998,68 @@ export function createChecker(program) {
1953
1998
  }
1954
1999
  }
1955
2000
  }
1956
- function bindMetaTypes(node) {
2001
+ function copyMembersToContainer(targetContainerSym, table) {
1957
2002
  var _a;
1958
- switch (node.kind) {
1959
- case SyntaxKind.ModelProperty: {
1960
- const sym = getSymbolForMember(node);
1961
- if (sym) {
1962
- const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
1963
- table.set("type", node.value.kind === SyntaxKind.TypeReference
1964
- ? createSymbol(node.value, "", 2048 /* SymbolFlags.Alias */)
1965
- : node.value.symbol);
1966
- }
1967
- break;
2003
+ const members = (_a = augmentedSymbolTables.get(table)) !== null && _a !== void 0 ? _a : table;
2004
+ compilerAssert(targetContainerSym.members, "containerSym.members is undefined");
2005
+ const containerMembers = getOrCreateAugmentedSymbolTable(targetContainerSym.members);
2006
+ for (const member of members.values()) {
2007
+ bindMemberToContainer(targetContainerSym, containerMembers, member.name, member.declarations[0], member.flags);
2008
+ }
2009
+ }
2010
+ function bindMemberToContainer(containerSym, containerMembers, name, node, kind) {
2011
+ const sym = createSymbol(node, name, kind, containerSym);
2012
+ compilerAssert(containerSym.members, "containerSym.members is undefined");
2013
+ containerMembers.set(name, sym);
2014
+ }
2015
+ function bindMetaTypes(node) {
2016
+ const visited = new Set();
2017
+ function visit(node, symbol) {
2018
+ var _a;
2019
+ if (visited.has(node)) {
2020
+ return;
1968
2021
  }
1969
- case SyntaxKind.OperationStatement: {
1970
- const sym = (_a = node.symbol) !== null && _a !== void 0 ? _a : getSymbolForMember(node);
1971
- const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
1972
- if (node.signature.kind === SyntaxKind.OperationSignatureDeclaration) {
1973
- table.set("parameters", node.signature.parameters.symbol);
1974
- table.set("returnType", node.signature.returnType.symbol);
2022
+ visited.add(node);
2023
+ switch (node.kind) {
2024
+ case SyntaxKind.ModelProperty: {
2025
+ const sym = getSymbolForMember(node);
2026
+ if (sym) {
2027
+ const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
2028
+ table.set("type", node.value.kind === SyntaxKind.TypeReference
2029
+ ? createSymbol(node.value, "", 2048 /* SymbolFlags.Alias */)
2030
+ : node.value.symbol);
2031
+ }
2032
+ break;
1975
2033
  }
1976
- else {
1977
- const sig = resolveTypeReferenceSym(node.signature.baseOperation, undefined);
1978
- if (sig) {
1979
- const sigTable = getOrCreateAugmentedSymbolTable(sig.metatypeMembers);
1980
- table.set("parameters", sigTable.get("parameters"));
1981
- table.set("returnType", sigTable.get("returnType"));
2034
+ case SyntaxKind.OperationStatement: {
2035
+ const sym = (_a = symbol !== null && symbol !== void 0 ? symbol : node.symbol) !== null && _a !== void 0 ? _a : getSymbolForMember(node);
2036
+ const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
2037
+ if (node.signature.kind === SyntaxKind.OperationSignatureDeclaration) {
2038
+ table.set("parameters", node.signature.parameters.symbol);
2039
+ table.set("returnType", node.signature.returnType.symbol);
2040
+ }
2041
+ else {
2042
+ const sig = resolveTypeReferenceSym(node.signature.baseOperation, undefined);
2043
+ if (sig) {
2044
+ visit(sig.declarations[0], sig);
2045
+ const sigTable = getOrCreateAugmentedSymbolTable(sig.metatypeMembers);
2046
+ const sigParameterSym = sigTable.get("parameters");
2047
+ if (sigParameterSym !== undefined) {
2048
+ const parametersSym = createSymbol(sigParameterSym.declarations[0], "parameters", 2 /* SymbolFlags.Model */ & 674 /* SymbolFlags.MemberContainer */);
2049
+ copyMembersToContainer(parametersSym, sigParameterSym.members);
2050
+ table.set("parameters", parametersSym);
2051
+ table.set("returnType", sigTable.get("returnType"));
2052
+ }
2053
+ }
1982
2054
  }
2055
+ break;
1983
2056
  }
1984
- break;
1985
2057
  }
2058
+ visitChildren(node, (child) => {
2059
+ bindMetaTypes(child);
2060
+ });
1986
2061
  }
1987
- visitChildren(node, (child) => {
1988
- bindMetaTypes(child);
1989
- });
2062
+ visit(node);
1990
2063
  }
1991
2064
  /**
1992
2065
  * Initializes a late bound symbol for the type. This is generally necessary when attempting to
@@ -2148,7 +2221,7 @@ export function createChecker(program) {
2148
2221
  }
2149
2222
  return isType;
2150
2223
  }
2151
- function checkSpreadProperty(targetNode, parentModel, mapper) {
2224
+ function checkSpreadProperty(parentModelSym, targetNode, parentModel, mapper) {
2152
2225
  const targetType = getTypeForNode(targetNode, mapper);
2153
2226
  if (targetType.kind === "TemplateParameter" || isErrorType(targetType)) {
2154
2227
  return [];
@@ -2160,7 +2233,8 @@ export function createChecker(program) {
2160
2233
  const props = [];
2161
2234
  // copy each property
2162
2235
  for (const prop of walkPropertiesInherited(targetType)) {
2163
- props.push(cloneType(prop, {
2236
+ const memberSym = getMemberSymbol(parentModelSym, prop.name);
2237
+ props.push(cloneTypeForSymbol(memberSym, prop, {
2164
2238
  sourceProperty: prop,
2165
2239
  model: parentModel,
2166
2240
  }));
@@ -2393,6 +2467,18 @@ export function createChecker(program) {
2393
2467
  }
2394
2468
  return valid;
2395
2469
  }
2470
+ function checkAugmentDecorators(sym, targetType, mapper) {
2471
+ var _a;
2472
+ const augmentDecoratorNodes = (_a = augmentDecoratorsForSym.get(sym)) !== null && _a !== void 0 ? _a : [];
2473
+ const decorators = [];
2474
+ for (const decNode of augmentDecoratorNodes) {
2475
+ const decorator = checkDecorator(targetType, decNode, mapper);
2476
+ if (decorator) {
2477
+ decorators.unshift(decorator);
2478
+ }
2479
+ }
2480
+ return decorators;
2481
+ }
2396
2482
  function checkDecorators(targetType, node, mapper) {
2397
2483
  var _a, _b;
2398
2484
  const sym = isMemberNode(node) ? (_a = getSymbolForMember(node)) !== null && _a !== void 0 ? _a : node.symbol : node.symbol;
@@ -2413,7 +2499,7 @@ export function createChecker(program) {
2413
2499
  if (docComment) {
2414
2500
  decorators.unshift({
2415
2501
  decorator: $docFromComment,
2416
- args: [{ value: program.checker.createLiteralType(docComment), jsValue: docComment }],
2502
+ args: [{ value: createLiteralType(docComment), jsValue: docComment }],
2417
2503
  });
2418
2504
  }
2419
2505
  return decorators;
@@ -2435,6 +2521,7 @@ export function createChecker(program) {
2435
2521
  // we're not instantiating this model and we've already checked it
2436
2522
  return links.declaredType;
2437
2523
  }
2524
+ checkTemplateDeclaration(node, mapper);
2438
2525
  const decorators = [];
2439
2526
  const type = createType({
2440
2527
  kind: "Scalar",
@@ -2448,7 +2535,7 @@ export function createChecker(program) {
2448
2535
  if (node.extends) {
2449
2536
  type.baseScalar = checkScalarExtends(node, node.extends, mapper);
2450
2537
  if (type.baseScalar) {
2451
- checkDeprecated(type.baseScalar, node.extends);
2538
+ copyDeprecation(type.baseScalar, type);
2452
2539
  type.baseScalar.derivedScalars.push(type);
2453
2540
  }
2454
2541
  }
@@ -2499,6 +2586,7 @@ export function createChecker(program) {
2499
2586
  if (links.declaredType && mapper === undefined) {
2500
2587
  return links.declaredType;
2501
2588
  }
2589
+ checkTemplateDeclaration(node, mapper);
2502
2590
  const aliasSymId = getNodeSymId(node);
2503
2591
  if (pendingResolutions.has(aliasSymId)) {
2504
2592
  if (mapper === undefined) {
@@ -2544,7 +2632,7 @@ export function createChecker(program) {
2544
2632
  enumType.members.set(memberType.name, memberType);
2545
2633
  }
2546
2634
  else {
2547
- const members = checkEnumSpreadMember(enumType, member.target, mapper, memberNames);
2635
+ const members = checkEnumSpreadMember(node.symbol, enumType, member.target, mapper, memberNames);
2548
2636
  for (const memberType of members) {
2549
2637
  linkIndirectMember(node, memberType, mapper);
2550
2638
  enumType.members.set(memberType.name, memberType);
@@ -2567,6 +2655,7 @@ export function createChecker(program) {
2567
2655
  // we're not instantiating this interface and we've already checked it
2568
2656
  return links.declaredType;
2569
2657
  }
2658
+ checkTemplateDeclaration(node, mapper);
2570
2659
  const interfaceType = createType({
2571
2660
  kind: "Interface",
2572
2661
  decorators: [],
@@ -2593,11 +2682,15 @@ export function createChecker(program) {
2593
2682
  target: extendsNode,
2594
2683
  }));
2595
2684
  }
2596
- const newMember = cloneType(member, { interface: interfaceType });
2685
+ const newMember = cloneTypeForSymbol(getMemberSymbol(node.symbol, member.name), member, {
2686
+ interface: interfaceType,
2687
+ });
2597
2688
  // Don't link it it is overritten
2598
2689
  if (!ownMembers.has(member.name)) {
2599
2690
  linkIndirectMember(node, newMember, mapper);
2600
2691
  }
2692
+ // Clone deprecation information
2693
+ copyDeprecation(member, newMember);
2601
2694
  interfaceType.operations.set(newMember.name, newMember);
2602
2695
  }
2603
2696
  interfaceType.sourceInterfaces.push(extendsType);
@@ -2639,6 +2732,7 @@ export function createChecker(program) {
2639
2732
  // we're not instantiating this union and we've already checked it
2640
2733
  return links.declaredType;
2641
2734
  }
2735
+ checkTemplateDeclaration(node, mapper);
2642
2736
  const variants = createRekeyableMap();
2643
2737
  const unionType = createType({
2644
2738
  kind: "Union",
@@ -2685,7 +2779,7 @@ export function createChecker(program) {
2685
2779
  // we're not instantiating this union variant and we've already checked it
2686
2780
  return links.declaredType;
2687
2781
  }
2688
- const name = variantNode.id.sv;
2782
+ const name = variantNode.id ? variantNode.id.sv : Symbol("name");
2689
2783
  const type = getTypeForNode(variantNode.value, mapper);
2690
2784
  const variantType = createType({
2691
2785
  kind: "UnionVariant",
@@ -2711,8 +2805,14 @@ export function createChecker(program) {
2711
2805
  node.kind === SyntaxKind.OperationStatement ||
2712
2806
  node.kind === SyntaxKind.UnionVariant);
2713
2807
  }
2808
+ function getMemberSymbol(parentSym, name) {
2809
+ return parentSym ? getOrCreateAugmentedSymbolTable(parentSym.members).get(name) : undefined;
2810
+ }
2714
2811
  function getSymbolForMember(node) {
2715
2812
  var _a;
2813
+ if (!node.id) {
2814
+ return undefined;
2815
+ }
2716
2816
  const name = node.id.sv;
2717
2817
  const parentSym = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.symbol;
2718
2818
  return parentSym ? getOrCreateAugmentedSymbolTable(parentSym.members).get(name) : undefined;
@@ -2743,7 +2843,7 @@ export function createChecker(program) {
2743
2843
  member.decorators = checkDecorators(member, node, mapper);
2744
2844
  return finishType(member);
2745
2845
  }
2746
- function checkEnumSpreadMember(parentEnum, targetNode, mapper, existingMemberNames) {
2846
+ function checkEnumSpreadMember(parentEnumSym, parentEnum, targetNode, mapper, existingMemberNames) {
2747
2847
  const members = [];
2748
2848
  const targetType = getTypeForNode(targetNode, mapper);
2749
2849
  if (!isErrorType(targetType)) {
@@ -2761,7 +2861,8 @@ export function createChecker(program) {
2761
2861
  }
2762
2862
  else {
2763
2863
  existingMemberNames.add(member.name);
2764
- const clonedMember = cloneType(member, {
2864
+ const memberSym = getMemberSymbol(parentEnumSym, member.name);
2865
+ const clonedMember = cloneTypeForSymbol(memberSym, member, {
2765
2866
  enum: parentEnum,
2766
2867
  sourceMember: member,
2767
2868
  });
@@ -2773,6 +2874,29 @@ export function createChecker(program) {
2773
2874
  }
2774
2875
  return members;
2775
2876
  }
2877
+ function checkDirectives(node, type) {
2878
+ var _a;
2879
+ let hasDeprecation = false;
2880
+ ((_a = node.directives) !== null && _a !== void 0 ? _a : []).forEach((directive) => {
2881
+ if (directive.target.sv === "deprecated") {
2882
+ if (directive.arguments[0].kind !== SyntaxKind.StringLiteral) {
2883
+ reportCheckerDiagnostic(createDiagnostic({
2884
+ code: "invalid-deprecation-argument",
2885
+ target: directive.arguments[0],
2886
+ }));
2887
+ }
2888
+ if (hasDeprecation === true) {
2889
+ reportCheckerDiagnostic(createDiagnostic({ code: "duplicate-deprecation", target: node }));
2890
+ }
2891
+ else {
2892
+ hasDeprecation = true;
2893
+ markDeprecated(program, type, {
2894
+ message: directive.arguments[0].value,
2895
+ });
2896
+ }
2897
+ }
2898
+ });
2899
+ }
2776
2900
  // the types here aren't ideal and could probably be refactored.
2777
2901
  function createAndFinishType(typeDef) {
2778
2902
  createType(typeDef);
@@ -2786,7 +2910,13 @@ export function createChecker(program) {
2786
2910
  function createType(typeDef) {
2787
2911
  Object.setPrototypeOf(typeDef, typePrototype);
2788
2912
  typeDef.isFinished = false;
2789
- return typeDef;
2913
+ // If the type has an associated syntax node, check any directives that
2914
+ // might be attached.
2915
+ const createdType = typeDef;
2916
+ if (createdType.node) {
2917
+ checkDirectives(createdType.node, createdType);
2918
+ }
2919
+ return createdType;
2790
2920
  }
2791
2921
  function finishType(typeDef) {
2792
2922
  return finishTypeForProgramAndChecker(program, typePrototype, typeDef);
@@ -2921,23 +3051,7 @@ export function createChecker(program) {
2921
3051
  getSymbolLinks(globalNamespaceNode.symbol).type = type;
2922
3052
  return type;
2923
3053
  }
2924
- /**
2925
- * Clone a type, resulting in an identical type with all the same decorators
2926
- * applied. Decorators are re-run on the clone to achieve this.
2927
- *
2928
- * Care is taken to clone nested data structures that are part of the type.
2929
- * Any type with e.g. a map or an array property must recreate the map or array
2930
- * so that clones don't share the same object.
2931
- *
2932
- * For types which have sub-types that are part of it, e.g. enums with members,
2933
- * unions with variants, or models with properties, the sub-types are cloned
2934
- * as well.
2935
- *
2936
- * If the entire type graph needs to be cloned, then cloneType must be called
2937
- * recursively by the caller.
2938
- */
2939
- function cloneType(type, additionalProps = {}) {
2940
- // TODO: this needs to handle other types
3054
+ function initializeClone(type, additionalProps) {
2941
3055
  let clone;
2942
3056
  switch (type.kind) {
2943
3057
  case "Model":
@@ -2953,7 +3067,7 @@ export function createChecker(program) {
2953
3067
  cloneType(prop, { model: newModel }),
2954
3068
  ]));
2955
3069
  }
2956
- clone = finishType(newModel);
3070
+ clone = newModel;
2957
3071
  break;
2958
3072
  case "Union":
2959
3073
  const newUnion = createType({
@@ -2971,7 +3085,7 @@ export function createChecker(program) {
2971
3085
  cloneType(prop, { union: newUnion }),
2972
3086
  ]));
2973
3087
  }
2974
- clone = finishType(newUnion);
3088
+ clone = newUnion;
2975
3089
  break;
2976
3090
  case "Interface":
2977
3091
  const newInterface = createType({
@@ -2986,7 +3100,7 @@ export function createChecker(program) {
2986
3100
  cloneType(prop, { interface: newInterface }),
2987
3101
  ]));
2988
3102
  }
2989
- clone = finishType(newInterface);
3103
+ clone = newInterface;
2990
3104
  break;
2991
3105
  case "Enum":
2992
3106
  const newEnum = createType({
@@ -3001,16 +3115,35 @@ export function createChecker(program) {
3001
3115
  cloneType(prop, { enum: newEnum }),
3002
3116
  ]));
3003
3117
  }
3004
- clone = finishType(newEnum);
3118
+ clone = newEnum;
3005
3119
  break;
3006
3120
  default:
3007
- clone = createAndFinishType({
3121
+ clone = createType({
3008
3122
  ...type,
3009
3123
  ...("decorators" in type ? { decorators: [...type.decorators] } : {}),
3010
3124
  ...additionalProps,
3011
3125
  });
3012
3126
  break;
3013
3127
  }
3128
+ return clone;
3129
+ }
3130
+ /**
3131
+ * Clone a type, resulting in an identical type with all the same decorators
3132
+ * applied. Decorators are re-run on the clone to achieve this.
3133
+ *
3134
+ * Care is taken to clone nested data structures that are part of the type.
3135
+ * Any type with e.g. a map or an array property must recreate the map or array
3136
+ * so that clones don't share the same object.
3137
+ *
3138
+ * For types which have sub-types that are part of it, e.g. enums with members,
3139
+ * unions with variants, or models with properties, the sub-types are cloned
3140
+ * as well.
3141
+ *
3142
+ * If the entire type graph needs to be cloned, then cloneType must be called
3143
+ * recursively by the caller.
3144
+ */
3145
+ function cloneType(type, additionalProps = {}) {
3146
+ const clone = finishType(initializeClone(type, additionalProps));
3014
3147
  const projection = projectionsByType.get(type);
3015
3148
  if (projection) {
3016
3149
  projectionsByType.set(clone, projection);
@@ -3018,6 +3151,24 @@ export function createChecker(program) {
3018
3151
  compilerAssert(clone.kind === type.kind, "cloneType must not change type kind");
3019
3152
  return clone;
3020
3153
  }
3154
+ /**
3155
+ * Clone a type linking to the given symbol.
3156
+ * @param sym Symbol which to associate the clone
3157
+ * @param type Type to clone
3158
+ * @param additionalProps Additional properties to set/override on the clone
3159
+ * @returns cloned type
3160
+ */
3161
+ function cloneTypeForSymbol(sym, type, additionalProps = {}) {
3162
+ let clone = initializeClone(type, additionalProps);
3163
+ if ("decorators" in clone) {
3164
+ for (const dec of checkAugmentDecorators(sym, clone, undefined)) {
3165
+ clone.decorators.push(dec);
3166
+ }
3167
+ }
3168
+ clone = finishType(clone);
3169
+ compilerAssert(clone.kind === type.kind, "cloneType must not change type kind");
3170
+ return clone;
3171
+ }
3021
3172
  function checkProjectionDeclaration(node) {
3022
3173
  // todo: check for duplicate projection decls on individual types
3023
3174
  // right now you can declare the same projection on a specific type
@@ -4250,8 +4401,19 @@ function finishTypeForProgramAndChecker(program, typePrototype, typeDef) {
4250
4401
  typeDef.isFinished = true;
4251
4402
  return typeDef;
4252
4403
  }
4404
+ function reportDeprecation(program, target, message, reportFunc) {
4405
+ if (program.compilerOptions.ignoreDeprecated !== true) {
4406
+ reportFunc(createDiagnostic({
4407
+ code: "deprecated",
4408
+ format: {
4409
+ message,
4410
+ },
4411
+ target,
4412
+ }));
4413
+ }
4414
+ }
4253
4415
  function applyDecoratorToType(program, decApp, target) {
4254
- var _a;
4416
+ var _a, _b;
4255
4417
  compilerAssert("decorators" in target, "Cannot apply decorator to non-decoratable type", target);
4256
4418
  for (const arg of decApp.args) {
4257
4419
  if (isErrorType(arg.value)) {
@@ -4259,6 +4421,13 @@ function applyDecoratorToType(program, decApp, target) {
4259
4421
  return;
4260
4422
  }
4261
4423
  }
4424
+ // Is the decorator definition deprecated?
4425
+ if (decApp.definition) {
4426
+ const deprecation = getDeprecationDetails(program, decApp.definition);
4427
+ if (deprecation !== undefined) {
4428
+ reportDeprecation(program, (_a = decApp.node) !== null && _a !== void 0 ? _a : target, deprecation.message, program.reportDiagnostic);
4429
+ }
4430
+ }
4262
4431
  // peel `fn` off to avoid setting `this`.
4263
4432
  try {
4264
4433
  const args = decApp.args.map((x) => x.jsValue);
@@ -4272,7 +4441,7 @@ function applyDecoratorToType(program, decApp, target) {
4272
4441
  program.reportDiagnostic(createDiagnostic({
4273
4442
  code: "decorator-fail",
4274
4443
  format: { decoratorName: decApp.decorator.name, error: error.stack },
4275
- target: (_a = decApp.node) !== null && _a !== void 0 ? _a : target,
4444
+ target: (_b = decApp.node) !== null && _b !== void 0 ? _b : target,
4276
4445
  }));
4277
4446
  }
4278
4447
  else {