@typespec/compiler 0.57.0-dev.7 → 0.57.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 (95) hide show
  1. package/dist/generated-defs/TypeSpec.d.ts +30 -24
  2. package/dist/generated-defs/TypeSpec.d.ts.map +1 -1
  3. package/dist/generated-defs/TypeSpec.ts-test.js +2 -1
  4. package/dist/generated-defs/TypeSpec.ts-test.js.map +1 -1
  5. package/dist/manifest.js +2 -2
  6. package/dist/src/config/config-schema.d.ts +1 -1
  7. package/dist/src/config/config-schema.d.ts.map +1 -1
  8. package/dist/src/core/charcode.d.ts +4 -1
  9. package/dist/src/core/charcode.d.ts.map +1 -1
  10. package/dist/src/core/charcode.js +4 -4
  11. package/dist/src/core/charcode.js.map +1 -1
  12. package/dist/src/core/checker.d.ts.map +1 -1
  13. package/dist/src/core/checker.js +307 -26
  14. package/dist/src/core/checker.js.map +1 -1
  15. package/dist/src/core/cli/utils.d.ts.map +1 -1
  16. package/dist/src/core/cli/utils.js +1 -0
  17. package/dist/src/core/cli/utils.js.map +1 -1
  18. package/dist/src/core/index.d.ts +1 -0
  19. package/dist/src/core/index.d.ts.map +1 -1
  20. package/dist/src/core/index.js +1 -0
  21. package/dist/src/core/index.js.map +1 -1
  22. package/dist/src/core/linter.d.ts +5 -1
  23. package/dist/src/core/linter.d.ts.map +1 -1
  24. package/dist/src/core/linter.js +32 -13
  25. package/dist/src/core/linter.js.map +1 -1
  26. package/dist/src/core/messages.d.ts +5 -0
  27. package/dist/src/core/messages.d.ts.map +1 -1
  28. package/dist/src/core/messages.js +1 -0
  29. package/dist/src/core/messages.js.map +1 -1
  30. package/dist/src/core/parser.d.ts +11 -2
  31. package/dist/src/core/parser.d.ts.map +1 -1
  32. package/dist/src/core/parser.js +216 -60
  33. package/dist/src/core/parser.js.map +1 -1
  34. package/dist/src/core/program.d.ts.map +1 -1
  35. package/dist/src/core/program.js +4 -2
  36. package/dist/src/core/program.js.map +1 -1
  37. package/dist/src/core/scanner.d.ts +17 -1
  38. package/dist/src/core/scanner.d.ts.map +1 -1
  39. package/dist/src/core/scanner.js +97 -1
  40. package/dist/src/core/scanner.js.map +1 -1
  41. package/dist/src/core/schema-validator.js +1 -1
  42. package/dist/src/core/schema-validator.js.map +1 -1
  43. package/dist/src/core/types.d.ts +103 -50
  44. package/dist/src/core/types.d.ts.map +1 -1
  45. package/dist/src/core/types.js +50 -46
  46. package/dist/src/core/types.js.map +1 -1
  47. package/dist/src/emitter-framework/asset-emitter.js +2 -2
  48. package/dist/src/emitter-framework/asset-emitter.js.map +1 -1
  49. package/dist/src/emitter-framework/type-emitter.d.ts +1 -1
  50. package/dist/src/emitter-framework/type-emitter.js +1 -1
  51. package/dist/src/formatter/print/printer.d.ts +1 -1
  52. package/dist/src/formatter/print/printer.d.ts.map +1 -1
  53. package/dist/src/formatter/print/printer.js +91 -12
  54. package/dist/src/formatter/print/printer.js.map +1 -1
  55. package/dist/src/init/init-template.d.ts +1 -1
  56. package/dist/src/init/init-template.d.ts.map +1 -1
  57. package/dist/src/lib/decorators.d.ts +2 -1
  58. package/dist/src/lib/decorators.d.ts.map +1 -1
  59. package/dist/src/lib/decorators.js +17 -0
  60. package/dist/src/lib/decorators.js.map +1 -1
  61. package/dist/src/server/classify.d.ts.map +1 -1
  62. package/dist/src/server/classify.js +4 -0
  63. package/dist/src/server/classify.js.map +1 -1
  64. package/dist/src/server/compile-service.d.ts +2 -2
  65. package/dist/src/server/compile-service.d.ts.map +1 -1
  66. package/dist/src/server/compile-service.js +26 -1
  67. package/dist/src/server/compile-service.js.map +1 -1
  68. package/dist/src/server/completion.d.ts +2 -2
  69. package/dist/src/server/completion.d.ts.map +1 -1
  70. package/dist/src/server/completion.js +136 -9
  71. package/dist/src/server/completion.js.map +1 -1
  72. package/dist/src/server/file-system-cache.d.ts +3 -1
  73. package/dist/src/server/file-system-cache.d.ts.map +1 -1
  74. package/dist/src/server/file-system-cache.js +13 -2
  75. package/dist/src/server/file-system-cache.js.map +1 -1
  76. package/dist/src/server/server.js +35 -8
  77. package/dist/src/server/server.js.map +1 -1
  78. package/dist/src/server/serverlib.d.ts.map +1 -1
  79. package/dist/src/server/serverlib.js +13 -31
  80. package/dist/src/server/serverlib.js.map +1 -1
  81. package/dist/src/server/tmlanguage.d.ts.map +1 -1
  82. package/dist/src/server/tmlanguage.js +1 -1
  83. package/dist/src/server/tmlanguage.js.map +1 -1
  84. package/dist/src/server/type-details.js +14 -6
  85. package/dist/src/server/type-details.js.map +1 -1
  86. package/dist/src/server/types.d.ts +9 -3
  87. package/dist/src/server/types.d.ts.map +1 -1
  88. package/dist/src/server/types.js.map +1 -1
  89. package/dist/src/testing/test-server-host.js +2 -2
  90. package/dist/src/testing/test-server-host.js.map +1 -1
  91. package/dist/typespec.tmLanguage +1 -1
  92. package/lib/std/decorators.tsp +6 -0
  93. package/lib/std/types.tsp +12 -0
  94. package/package.json +12 -13
  95. package/templates/scaffolding.json +4 -4
@@ -15,7 +15,7 @@ import { canNumericConstraintBeJsNumber, legacyMarshallTypeForJS, marshallTypeFo
15
15
  import { createDiagnostic } from "./messages.js";
16
16
  import { numericRanges } from "./numeric-ranges.js";
17
17
  import { Numeric } from "./numeric.js";
18
- import { exprIsBareIdentifier, getIdentifierContext, hasParseError, visitChildren, } from "./parser.js";
18
+ import { exprIsBareIdentifier, getFirstAncestor, getIdentifierContext, hasParseError, visitChildren, } from "./parser.js";
19
19
  import { createProjectionMembers } from "./projection-members.js";
20
20
  import { getFullyQualifiedSymbolName, getParentTemplateNode, isArrayModelType, isErrorType, isNeverType, isNullType, isTemplateInstance, isType, isUnknownType, isValue, isVoidType, } from "./type-utils.js";
21
21
  import { IdentifierKind, SyntaxKind, } from "./types.js";
@@ -29,6 +29,7 @@ export function createChecker(program) {
29
29
  const stdTypes = {};
30
30
  const symbolLinks = new Map();
31
31
  const mergedSymbols = new Map();
32
+ const docFromCommentForSym = new Map();
32
33
  const augmentDecoratorsForSym = new Map();
33
34
  const augmentedSymbolTables = new Map();
34
35
  const referenceSymCache = new WeakMap();
@@ -326,6 +327,12 @@ export function createChecker(program) {
326
327
  return checkScalarConstructor(node, mapper, containerType);
327
328
  }
328
329
  }
330
+ function getTypeForTypeOrIndeterminate(entity) {
331
+ if (entity.entityKind === "Indeterminate") {
332
+ return entity.type;
333
+ }
334
+ return entity;
335
+ }
329
336
  function getTypeForNode(node, mapper) {
330
337
  const entity = checkNode(node, mapper);
331
338
  if (entity === null) {
@@ -1046,7 +1053,7 @@ export function createChecker(program) {
1046
1053
  baseType = checkMemberSym(sym, mapper);
1047
1054
  }
1048
1055
  else {
1049
- baseType = checkDeclaredType(sym, decl, mapper);
1056
+ baseType = checkDeclaredTypeOrIndeterminate(sym, decl, mapper);
1050
1057
  }
1051
1058
  }
1052
1059
  else {
@@ -1095,14 +1102,13 @@ export function createChecker(program) {
1095
1102
  // don't raise deprecation when the usage site is also a deprecated
1096
1103
  // declaration.
1097
1104
  const declarationNode = sym?.declarations[0];
1098
- if (declarationNode && mapper === undefined) {
1105
+ if (declarationNode && mapper === undefined && isType(baseType)) {
1099
1106
  if (!isTypeReferenceContextDeprecated(node.parent)) {
1100
1107
  checkDeprecated(baseType, declarationNode, node);
1101
1108
  }
1102
1109
  }
1103
1110
  // Elements that could be used as type or values depending on the context
1104
- if (baseType.kind === "EnumMember" ||
1105
- baseType.kind === "UnionVariant" ||
1111
+ if ((isType(baseType) && (baseType.kind === "EnumMember" || baseType.kind === "UnionVariant")) ||
1106
1112
  isNullType(baseType)) {
1107
1113
  return createIndeterminateEntity(baseType);
1108
1114
  }
@@ -1138,7 +1144,7 @@ export function createChecker(program) {
1138
1144
  * @param mapper Type mapper for template resolution
1139
1145
  * @returns The declared type for the given node.
1140
1146
  */
1141
- function checkDeclaredType(sym, node, mapper) {
1147
+ function checkDeclaredTypeOrIndeterminate(sym, node, mapper) {
1142
1148
  const type = sym.flags & 2 /* SymbolFlags.Model */
1143
1149
  ? checkModelStatement(node, mapper)
1144
1150
  : sym.flags & 8 /* SymbolFlags.Scalar */
@@ -1152,6 +1158,9 @@ export function createChecker(program) {
1152
1158
  : checkUnion(node, mapper);
1153
1159
  return type;
1154
1160
  }
1161
+ function checkDeclaredType(sym, node, mapper) {
1162
+ return getTypeForTypeOrIndeterminate(checkDeclaredTypeOrIndeterminate(sym, node, mapper));
1163
+ }
1155
1164
  function getOrInstantiateTemplate(templateNode, params, args, parentMapper, instantiateTempalates = true) {
1156
1165
  const symbolLinks = templateNode.kind === SyntaxKind.OperationStatement &&
1157
1166
  templateNode.parent.kind === SyntaxKind.InterfaceStatement
@@ -1653,6 +1662,17 @@ export function createChecker(program) {
1653
1662
  const namespace = getParentNamespaceType(node);
1654
1663
  const name = node.id.sv;
1655
1664
  let decorators = [];
1665
+ const parameterModelSym = getOrCreateAugmentedSymbolTable(symbol.metatypeMembers).get("parameters");
1666
+ if (parameterModelSym?.members) {
1667
+ const members = getOrCreateAugmentedSymbolTable(parameterModelSym.members);
1668
+ const paramDocs = extractParamDocs(node);
1669
+ for (const [name, memberSym] of members) {
1670
+ const doc = paramDocs.get(name);
1671
+ if (doc) {
1672
+ docFromCommentForSym.set(memberSym, doc);
1673
+ }
1674
+ }
1675
+ }
1656
1676
  // Is this a definition or reference?
1657
1677
  let parameters, returnType, sourceOperation;
1658
1678
  if (node.signature.kind === SyntaxKind.OperationSignatureReference) {
@@ -1660,7 +1680,6 @@ export function createChecker(program) {
1660
1680
  const baseOperation = checkOperationIs(node, node.signature.baseOperation, mapper);
1661
1681
  if (baseOperation) {
1662
1682
  sourceOperation = baseOperation;
1663
- const parameterModelSym = getOrCreateAugmentedSymbolTable(symbol.metatypeMembers).get("parameters");
1664
1683
  // Reference the same return type and create the parameters type
1665
1684
  const clone = initializeClone(baseOperation.parameters, {
1666
1685
  properties: createRekeyableMap(),
@@ -1826,6 +1845,17 @@ export function createChecker(program) {
1826
1845
  let sym;
1827
1846
  const { node, kind } = getIdentifierContext(id);
1828
1847
  switch (kind) {
1848
+ case IdentifierKind.ModelExpressionProperty:
1849
+ case IdentifierKind.ObjectLiteralProperty:
1850
+ const model = getReferencedModel(node);
1851
+ if (model) {
1852
+ sym = getMemberSymbol(model.node.symbol, id.sv);
1853
+ }
1854
+ else {
1855
+ return undefined;
1856
+ }
1857
+ break;
1858
+ case IdentifierKind.ModelStatementProperty:
1829
1859
  case IdentifierKind.Declaration:
1830
1860
  if (node.symbol && (!isTemplatedNode(node) || mapper === undefined)) {
1831
1861
  sym = getMergedSymbol(node.symbol);
@@ -1890,6 +1920,164 @@ export function createChecker(program) {
1890
1920
  const resolved = resolveTypeReferenceSym(node.parent, mapper, false);
1891
1921
  return (resolved?.declarations.filter((n) => isTemplatedNode(n)) ?? []);
1892
1922
  }
1923
+ function getReferencedModel(propertyNode) {
1924
+ const isModelOrArrayValue = (n) => n?.kind === SyntaxKind.ArrayLiteral || n?.kind === SyntaxKind.ObjectLiteral;
1925
+ const isModelOrArrayType = (n) => n?.kind === SyntaxKind.ModelExpression || n?.kind === SyntaxKind.TupleExpression;
1926
+ const isModelOrArray = (n) => isModelOrArrayValue(n) || isModelOrArrayType(n);
1927
+ const path = [];
1928
+ let preNode;
1929
+ const foundNode = getFirstAncestor(propertyNode, (n) => {
1930
+ pushToModelPath(n, preNode, path);
1931
+ preNode = n;
1932
+ return ((isModelOrArray(n) &&
1933
+ (n.parent?.kind === SyntaxKind.TemplateParameterDeclaration ||
1934
+ n.parent?.kind === SyntaxKind.DecoratorExpression)) ||
1935
+ (isModelOrArrayValue(n) &&
1936
+ (n.parent?.kind === SyntaxKind.CallExpression ||
1937
+ n.parent?.kind === SyntaxKind.ConstStatement)));
1938
+ });
1939
+ let refType;
1940
+ switch (foundNode?.parent?.kind) {
1941
+ case SyntaxKind.TemplateParameterDeclaration:
1942
+ refType = getReferencedTypeFromTemplateDeclaration(foundNode);
1943
+ break;
1944
+ case SyntaxKind.DecoratorExpression:
1945
+ refType = getReferencedTypeFromDecoratorArgument(foundNode);
1946
+ break;
1947
+ case SyntaxKind.CallExpression:
1948
+ refType = getReferencedTypeFromScalarConstructor(foundNode);
1949
+ break;
1950
+ case SyntaxKind.ConstStatement:
1951
+ refType = getReferencedTypeFromConstAssignment(foundNode);
1952
+ break;
1953
+ }
1954
+ return refType?.kind === "Model" || refType?.kind === "Tuple"
1955
+ ? getNestedModel(refType, path)
1956
+ : undefined;
1957
+ function pushToModelPath(node, preNode, path) {
1958
+ if (node.kind === SyntaxKind.ArrayLiteral || node.kind === SyntaxKind.TupleExpression) {
1959
+ const index = node.values.findIndex((n) => n === preNode);
1960
+ if (index >= 0) {
1961
+ path.unshift({ tupleIndex: index });
1962
+ }
1963
+ else {
1964
+ compilerAssert(false, "not expected, can't find child from the parent?");
1965
+ }
1966
+ }
1967
+ if (node.kind === SyntaxKind.ModelProperty ||
1968
+ node.kind === SyntaxKind.ObjectLiteralProperty) {
1969
+ path.unshift({ propertyName: node.id.sv });
1970
+ }
1971
+ }
1972
+ function getNestedModel(modelOrTuple, path) {
1973
+ let cur = modelOrTuple;
1974
+ for (const seg of path) {
1975
+ switch (cur?.kind) {
1976
+ case "Tuple":
1977
+ if (seg.tupleIndex !== undefined &&
1978
+ seg.tupleIndex >= 0 &&
1979
+ seg.tupleIndex < cur.values.length) {
1980
+ cur = cur.values[seg.tupleIndex];
1981
+ }
1982
+ else {
1983
+ return undefined;
1984
+ }
1985
+ break;
1986
+ case "Model":
1987
+ if (cur.name === "Array" && seg.tupleIndex !== undefined) {
1988
+ cur = cur.templateMapper?.args[0];
1989
+ }
1990
+ else if (cur.name !== "Array" && seg.propertyName) {
1991
+ cur = cur.properties.get(seg.propertyName)?.type;
1992
+ }
1993
+ else {
1994
+ return undefined;
1995
+ }
1996
+ break;
1997
+ default:
1998
+ return undefined;
1999
+ }
2000
+ }
2001
+ return cur?.kind === "Model" ? cur : undefined;
2002
+ }
2003
+ function getReferencedTypeFromTemplateDeclaration(dftNode) {
2004
+ const templateParmaeterDeclNode = dftNode?.parent;
2005
+ if (templateParmaeterDeclNode?.kind !== SyntaxKind.TemplateParameterDeclaration ||
2006
+ !templateParmaeterDeclNode.constraint ||
2007
+ !templateParmaeterDeclNode.default ||
2008
+ templateParmaeterDeclNode.default !== dftNode) {
2009
+ return undefined;
2010
+ }
2011
+ let constraintType;
2012
+ if (isModelOrArrayValue(dftNode) &&
2013
+ templateParmaeterDeclNode.constraint.kind === SyntaxKind.ValueOfExpression) {
2014
+ constraintType = program.checker.getTypeForNode(templateParmaeterDeclNode.constraint.target);
2015
+ }
2016
+ else if (isModelOrArrayType(dftNode) &&
2017
+ templateParmaeterDeclNode.constraint.kind !== SyntaxKind.ValueOfExpression) {
2018
+ constraintType = program.checker.getTypeForNode(templateParmaeterDeclNode.constraint);
2019
+ }
2020
+ return constraintType;
2021
+ }
2022
+ function getReferencedTypeFromScalarConstructor(argNode) {
2023
+ const callExpNode = argNode?.parent;
2024
+ if (callExpNode?.kind !== SyntaxKind.CallExpression) {
2025
+ return undefined;
2026
+ }
2027
+ const ctorType = checkCallExpressionTarget(callExpNode, undefined);
2028
+ if (ctorType?.kind !== "ScalarConstructor") {
2029
+ return undefined;
2030
+ }
2031
+ const argIndex = callExpNode.arguments.findIndex((n) => n === argNode);
2032
+ if (argIndex < 0 || argIndex >= ctorType.parameters.length) {
2033
+ return undefined;
2034
+ }
2035
+ const arg = ctorType.parameters[argIndex];
2036
+ return arg.type;
2037
+ }
2038
+ function getReferencedTypeFromConstAssignment(valueNode) {
2039
+ const constNode = valueNode?.parent;
2040
+ if (!constNode ||
2041
+ constNode.kind !== SyntaxKind.ConstStatement ||
2042
+ !constNode.type ||
2043
+ constNode.value !== valueNode) {
2044
+ return undefined;
2045
+ }
2046
+ return program.checker.getTypeForNode(constNode.type);
2047
+ }
2048
+ function getReferencedTypeFromDecoratorArgument(decArgNode) {
2049
+ const decNode = decArgNode?.parent;
2050
+ if (decNode?.kind !== SyntaxKind.DecoratorExpression) {
2051
+ return undefined;
2052
+ }
2053
+ const decSym = program.checker.resolveIdentifier(decNode.target.kind === SyntaxKind.MemberExpression ? decNode.target.id : decNode.target);
2054
+ if (!decSym) {
2055
+ return undefined;
2056
+ }
2057
+ const decDecl = decSym.declarations.find((x) => x.kind === SyntaxKind.DecoratorDeclarationStatement);
2058
+ if (!decDecl) {
2059
+ return undefined;
2060
+ }
2061
+ const decType = program.checker.getTypeForNode(decDecl);
2062
+ compilerAssert(decType.kind === "Decorator", "Expected type to be a Decorator.");
2063
+ const argIndex = decNode.arguments.findIndex((n) => n === decArgNode);
2064
+ if (argIndex < 0 || argIndex >= decType.parameters.length) {
2065
+ return undefined;
2066
+ }
2067
+ const decArg = decType.parameters[argIndex];
2068
+ let type;
2069
+ if (isModelOrArrayValue(decArgNode)) {
2070
+ type = decArg.type.valueType;
2071
+ }
2072
+ else if (isModelOrArrayType(decArgNode)) {
2073
+ type = decArg.type.type ?? decArg.type.valueType;
2074
+ }
2075
+ else {
2076
+ compilerAssert(false, "not expected node type to get reference model from decorator argument");
2077
+ }
2078
+ return type;
2079
+ }
2080
+ }
1893
2081
  function resolveCompletions(identifier) {
1894
2082
  const completions = new Map();
1895
2083
  const { kind, node: ancestor } = getIdentifierContext(identifier);
@@ -1898,6 +2086,9 @@ export function createChecker(program) {
1898
2086
  case IdentifierKind.Decorator:
1899
2087
  case IdentifierKind.Function:
1900
2088
  case IdentifierKind.TypeReference:
2089
+ case IdentifierKind.ModelExpressionProperty:
2090
+ case IdentifierKind.ModelStatementProperty:
2091
+ case IdentifierKind.ObjectLiteralProperty:
1901
2092
  break; // supported
1902
2093
  case IdentifierKind.Other:
1903
2094
  return completions; // not implemented
@@ -1916,7 +2107,43 @@ export function createChecker(program) {
1916
2107
  const _assertNever = kind;
1917
2108
  compilerAssert(false, "Unreachable");
1918
2109
  }
1919
- if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
2110
+ if (kind === IdentifierKind.ModelStatementProperty) {
2111
+ const model = ancestor.parent;
2112
+ const modelType = program.checker.getTypeForNode(model);
2113
+ const baseType = modelType.baseModel;
2114
+ const baseNode = baseType?.node;
2115
+ if (!baseNode) {
2116
+ return completions;
2117
+ }
2118
+ for (const prop of baseType.properties.values()) {
2119
+ if (identifier.sv === prop.name || !modelType.properties.has(prop.name)) {
2120
+ const sym = getMemberSymbol(baseNode.symbol, prop.name);
2121
+ if (sym) {
2122
+ addCompletion(prop.name, sym);
2123
+ }
2124
+ }
2125
+ }
2126
+ }
2127
+ else if (kind === IdentifierKind.ModelExpressionProperty ||
2128
+ kind === IdentifierKind.ObjectLiteralProperty) {
2129
+ const model = getReferencedModel(ancestor);
2130
+ if (!model) {
2131
+ return completions;
2132
+ }
2133
+ const curModelNode = ancestor.parent;
2134
+ for (const prop of walkPropertiesInherited(model)) {
2135
+ if (identifier.sv === prop.name ||
2136
+ !curModelNode.properties.find((p) => (p.kind === SyntaxKind.ModelProperty ||
2137
+ p.kind === SyntaxKind.ObjectLiteralProperty) &&
2138
+ p.id.sv === prop.name)) {
2139
+ const sym = getMemberSymbol(model.node.symbol, prop.name);
2140
+ if (sym) {
2141
+ addCompletion(prop.name, sym);
2142
+ }
2143
+ }
2144
+ }
2145
+ }
2146
+ else if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
1920
2147
  let base = resolveTypeReferenceSym(identifier.parent.base, undefined, false);
1921
2148
  if (base) {
1922
2149
  if (base.flags & 2048 /* SymbolFlags.Alias */) {
@@ -2008,6 +2235,10 @@ export function createChecker(program) {
2008
2235
  }
2009
2236
  function shouldAddCompletion(sym) {
2010
2237
  switch (kind) {
2238
+ case IdentifierKind.ModelExpressionProperty:
2239
+ case IdentifierKind.ModelStatementProperty:
2240
+ case IdentifierKind.ObjectLiteralProperty:
2241
+ return !!(sym.flags & 4 /* SymbolFlags.ModelProperty */);
2011
2242
  case IdentifierKind.Decorator:
2012
2243
  // Only return decorators and namespaces when completing decorator
2013
2244
  return !!(sym.flags & (16384 /* SymbolFlags.Decorator */ | 4096 /* SymbolFlags.Namespace */));
@@ -2532,6 +2763,16 @@ export function createChecker(program) {
2532
2763
  derivedModels: [],
2533
2764
  });
2534
2765
  linkType(links, type, mapper);
2766
+ if (node.symbol.members) {
2767
+ const members = getOrCreateAugmentedSymbolTable(node.symbol.members);
2768
+ const propDocs = extractPropDocs(node);
2769
+ for (const [name, memberSym] of members) {
2770
+ const doc = propDocs.get(name);
2771
+ if (doc) {
2772
+ docFromCommentForSym.set(memberSym, doc);
2773
+ }
2774
+ }
2775
+ }
2535
2776
  const isBase = checkModelIs(node, node.is, mapper);
2536
2777
  if (isBase) {
2537
2778
  type.sourceModel = isBase;
@@ -2545,7 +2786,8 @@ export function createChecker(program) {
2545
2786
  decorators.push(...checkDecorators(type, node, mapper));
2546
2787
  if (isBase) {
2547
2788
  for (const prop of isBase.properties.values()) {
2548
- const newProp = cloneType(prop, {
2789
+ const memberSym = getMemberSymbol(node.symbol, prop.name);
2790
+ const newProp = cloneTypeForSymbol(memberSym, prop, {
2549
2791
  sourceProperty: prop,
2550
2792
  model: type,
2551
2793
  });
@@ -3551,7 +3793,8 @@ export function createChecker(program) {
3551
3793
  }
3552
3794
  }
3553
3795
  function checkModelProperty(prop, mapper) {
3554
- const symId = getSymbolId(getSymbolForMember(prop));
3796
+ const sym = getSymbolForMember(prop);
3797
+ const symId = getSymbolId(sym);
3555
3798
  const links = getSymbolLinksForMember(prop);
3556
3799
  if (links && links.declaredType && mapper === undefined) {
3557
3800
  return links.declaredType;
@@ -3592,12 +3835,9 @@ export function createChecker(program) {
3592
3835
  const parentTemplate = getParentTemplateNode(prop);
3593
3836
  linkMapper(type, mapper);
3594
3837
  if (!parentTemplate || shouldCreateTypeForTemplate(parentTemplate, mapper)) {
3595
- if (prop.parent?.parent?.kind === SyntaxKind.OperationSignatureDeclaration &&
3596
- prop.parent.parent.parent?.kind === SyntaxKind.OperationStatement) {
3597
- const doc = extractParamDoc(prop.parent.parent.parent, type.name);
3598
- if (doc) {
3599
- type.decorators.unshift(createDocFromCommentDecorator("self", doc));
3600
- }
3838
+ const docComment = docFromCommentForSym.get(sym);
3839
+ if (docComment) {
3840
+ type.decorators.unshift(createDocFromCommentDecorator("self", docComment));
3601
3841
  }
3602
3842
  finishType(type);
3603
3843
  }
@@ -3921,6 +4161,8 @@ export function createChecker(program) {
3921
4161
  decorators.unshift(createDocFromCommentDecorator("errors", returnTypesDocs.errors));
3922
4162
  }
3923
4163
  }
4164
+ else if (targetType.kind === "ModelProperty") {
4165
+ }
3924
4166
  return decorators;
3925
4167
  }
3926
4168
  function checkScalar(node, mapper) {
@@ -3940,7 +4182,6 @@ export function createChecker(program) {
3940
4182
  decorators,
3941
4183
  derivedScalars: [],
3942
4184
  });
3943
- checkScalarConstructors(type, node, type.constructors, mapper);
3944
4185
  linkType(links, type, mapper);
3945
4186
  if (node.extends) {
3946
4187
  type.baseScalar = checkScalarExtends(node, node.extends, mapper);
@@ -3949,6 +4190,7 @@ export function createChecker(program) {
3949
4190
  type.baseScalar.derivedScalars.push(type);
3950
4191
  }
3951
4192
  }
4193
+ checkScalarConstructors(type, node, type.constructors, mapper);
3952
4194
  decorators.push(...checkDecorators(type, node, mapper));
3953
4195
  if (mapper === undefined) {
3954
4196
  type.namespace?.scalars.set(type.name, type);
@@ -3992,6 +4234,16 @@ export function createChecker(program) {
3992
4234
  return extendsType;
3993
4235
  }
3994
4236
  function checkScalarConstructors(parentScalar, node, constructors, mapper) {
4237
+ if (parentScalar.baseScalar) {
4238
+ for (const member of parentScalar.baseScalar.constructors.values()) {
4239
+ const newConstructor = cloneTypeForSymbol(getMemberSymbol(node.symbol, member.name), {
4240
+ ...member,
4241
+ scalar: parentScalar,
4242
+ });
4243
+ linkIndirectMember(node, newConstructor, mapper);
4244
+ constructors.set(member.name, newConstructor);
4245
+ }
4246
+ }
3995
4247
  for (const member of node.members) {
3996
4248
  const constructor = checkScalarConstructor(member, mapper, parentScalar);
3997
4249
  if (constructors.has(constructor.name)) {
@@ -4047,10 +4299,17 @@ export function createChecker(program) {
4047
4299
  return errorType;
4048
4300
  }
4049
4301
  pendingResolutions.start(aliasSymId, ResolutionKind.Type);
4050
- const type = getTypeForNode(node.value, mapper);
4051
- if (!isValue(type)) {
4052
- linkType(links, type, mapper);
4302
+ const type = checkNode(node.value, mapper);
4303
+ if (type === null) {
4304
+ links.declaredType = errorType;
4305
+ return errorType;
4053
4306
  }
4307
+ if (isValue(type)) {
4308
+ reportCheckerDiagnostic(createDiagnostic({ code: "value-in-type", target: node.value }));
4309
+ links.declaredType = errorType;
4310
+ return errorType;
4311
+ }
4312
+ linkType(links, type, mapper);
4054
4313
  pendingResolutions.finish(aliasSymId, ResolutionKind.Type);
4055
4314
  return type;
4056
4315
  }
@@ -4644,7 +4903,10 @@ export function createChecker(program) {
4644
4903
  * recursively by the caller.
4645
4904
  */
4646
4905
  function cloneType(type, additionalProps = {}) {
4647
- const clone = finishType(initializeClone(type, additionalProps));
4906
+ let clone = initializeClone(type, additionalProps);
4907
+ if (type.isFinished) {
4908
+ clone = finishType(clone);
4909
+ }
4648
4910
  const projection = projectionsByType.get(type);
4649
4911
  if (projection) {
4650
4912
  projectionsByType.set(clone, projection);
@@ -4662,6 +4924,10 @@ export function createChecker(program) {
4662
4924
  function cloneTypeForSymbol(sym, type, additionalProps = {}) {
4663
4925
  let clone = initializeClone(type, additionalProps);
4664
4926
  if ("decorators" in clone) {
4927
+ const docComment = docFromCommentForSym.get(sym);
4928
+ if (docComment) {
4929
+ clone.decorators.push(createDocFromCommentDecorator("self", docComment));
4930
+ }
4665
4931
  for (const dec of checkAugmentDecorators(sym, clone, undefined)) {
4666
4932
  clone.decorators.push(dec);
4667
4933
  }
@@ -6123,18 +6389,33 @@ function extractReturnsDocs(type) {
6123
6389
  }
6124
6390
  return result;
6125
6391
  }
6126
- function extractParamDoc(node, paramName) {
6392
+ function extractParamDocs(node) {
6127
6393
  if (node.docs === undefined) {
6128
- return undefined;
6394
+ return new Map();
6129
6395
  }
6396
+ const paramDocs = new Map();
6130
6397
  for (const doc of node.docs) {
6131
6398
  for (const tag of doc.tags) {
6132
- if (tag.kind === SyntaxKind.DocParamTag && tag.paramName.sv === paramName) {
6133
- return getDocContent(tag.content);
6399
+ if (tag.kind === SyntaxKind.DocParamTag) {
6400
+ paramDocs.set(tag.paramName.sv, getDocContent(tag.content));
6134
6401
  }
6135
6402
  }
6136
6403
  }
6137
- return undefined;
6404
+ return paramDocs;
6405
+ }
6406
+ function extractPropDocs(node) {
6407
+ if (node.docs === undefined) {
6408
+ return new Map();
6409
+ }
6410
+ const propDocs = new Map();
6411
+ for (const doc of node.docs) {
6412
+ for (const tag of doc.tags) {
6413
+ if (tag.kind === SyntaxKind.DocPropTag) {
6414
+ propDocs.set(tag.propName.sv, getDocContent(tag.content));
6415
+ }
6416
+ }
6417
+ }
6418
+ return propDocs;
6138
6419
  }
6139
6420
  function getDocContent(content) {
6140
6421
  const docs = [];