@typespec/compiler 0.57.0-dev.8 → 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 +284 -18
  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();
@@ -1661,6 +1662,17 @@ export function createChecker(program) {
1661
1662
  const namespace = getParentNamespaceType(node);
1662
1663
  const name = node.id.sv;
1663
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
+ }
1664
1676
  // Is this a definition or reference?
1665
1677
  let parameters, returnType, sourceOperation;
1666
1678
  if (node.signature.kind === SyntaxKind.OperationSignatureReference) {
@@ -1668,7 +1680,6 @@ export function createChecker(program) {
1668
1680
  const baseOperation = checkOperationIs(node, node.signature.baseOperation, mapper);
1669
1681
  if (baseOperation) {
1670
1682
  sourceOperation = baseOperation;
1671
- const parameterModelSym = getOrCreateAugmentedSymbolTable(symbol.metatypeMembers).get("parameters");
1672
1683
  // Reference the same return type and create the parameters type
1673
1684
  const clone = initializeClone(baseOperation.parameters, {
1674
1685
  properties: createRekeyableMap(),
@@ -1834,6 +1845,17 @@ export function createChecker(program) {
1834
1845
  let sym;
1835
1846
  const { node, kind } = getIdentifierContext(id);
1836
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:
1837
1859
  case IdentifierKind.Declaration:
1838
1860
  if (node.symbol && (!isTemplatedNode(node) || mapper === undefined)) {
1839
1861
  sym = getMergedSymbol(node.symbol);
@@ -1898,6 +1920,164 @@ export function createChecker(program) {
1898
1920
  const resolved = resolveTypeReferenceSym(node.parent, mapper, false);
1899
1921
  return (resolved?.declarations.filter((n) => isTemplatedNode(n)) ?? []);
1900
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
+ }
1901
2081
  function resolveCompletions(identifier) {
1902
2082
  const completions = new Map();
1903
2083
  const { kind, node: ancestor } = getIdentifierContext(identifier);
@@ -1906,6 +2086,9 @@ export function createChecker(program) {
1906
2086
  case IdentifierKind.Decorator:
1907
2087
  case IdentifierKind.Function:
1908
2088
  case IdentifierKind.TypeReference:
2089
+ case IdentifierKind.ModelExpressionProperty:
2090
+ case IdentifierKind.ModelStatementProperty:
2091
+ case IdentifierKind.ObjectLiteralProperty:
1909
2092
  break; // supported
1910
2093
  case IdentifierKind.Other:
1911
2094
  return completions; // not implemented
@@ -1924,7 +2107,43 @@ export function createChecker(program) {
1924
2107
  const _assertNever = kind;
1925
2108
  compilerAssert(false, "Unreachable");
1926
2109
  }
1927
- 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) {
1928
2147
  let base = resolveTypeReferenceSym(identifier.parent.base, undefined, false);
1929
2148
  if (base) {
1930
2149
  if (base.flags & 2048 /* SymbolFlags.Alias */) {
@@ -2016,6 +2235,10 @@ export function createChecker(program) {
2016
2235
  }
2017
2236
  function shouldAddCompletion(sym) {
2018
2237
  switch (kind) {
2238
+ case IdentifierKind.ModelExpressionProperty:
2239
+ case IdentifierKind.ModelStatementProperty:
2240
+ case IdentifierKind.ObjectLiteralProperty:
2241
+ return !!(sym.flags & 4 /* SymbolFlags.ModelProperty */);
2019
2242
  case IdentifierKind.Decorator:
2020
2243
  // Only return decorators and namespaces when completing decorator
2021
2244
  return !!(sym.flags & (16384 /* SymbolFlags.Decorator */ | 4096 /* SymbolFlags.Namespace */));
@@ -2540,6 +2763,16 @@ export function createChecker(program) {
2540
2763
  derivedModels: [],
2541
2764
  });
2542
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
+ }
2543
2776
  const isBase = checkModelIs(node, node.is, mapper);
2544
2777
  if (isBase) {
2545
2778
  type.sourceModel = isBase;
@@ -2553,7 +2786,8 @@ export function createChecker(program) {
2553
2786
  decorators.push(...checkDecorators(type, node, mapper));
2554
2787
  if (isBase) {
2555
2788
  for (const prop of isBase.properties.values()) {
2556
- const newProp = cloneType(prop, {
2789
+ const memberSym = getMemberSymbol(node.symbol, prop.name);
2790
+ const newProp = cloneTypeForSymbol(memberSym, prop, {
2557
2791
  sourceProperty: prop,
2558
2792
  model: type,
2559
2793
  });
@@ -3559,7 +3793,8 @@ export function createChecker(program) {
3559
3793
  }
3560
3794
  }
3561
3795
  function checkModelProperty(prop, mapper) {
3562
- const symId = getSymbolId(getSymbolForMember(prop));
3796
+ const sym = getSymbolForMember(prop);
3797
+ const symId = getSymbolId(sym);
3563
3798
  const links = getSymbolLinksForMember(prop);
3564
3799
  if (links && links.declaredType && mapper === undefined) {
3565
3800
  return links.declaredType;
@@ -3600,12 +3835,9 @@ export function createChecker(program) {
3600
3835
  const parentTemplate = getParentTemplateNode(prop);
3601
3836
  linkMapper(type, mapper);
3602
3837
  if (!parentTemplate || shouldCreateTypeForTemplate(parentTemplate, mapper)) {
3603
- if (prop.parent?.parent?.kind === SyntaxKind.OperationSignatureDeclaration &&
3604
- prop.parent.parent.parent?.kind === SyntaxKind.OperationStatement) {
3605
- const doc = extractParamDoc(prop.parent.parent.parent, type.name);
3606
- if (doc) {
3607
- type.decorators.unshift(createDocFromCommentDecorator("self", doc));
3608
- }
3838
+ const docComment = docFromCommentForSym.get(sym);
3839
+ if (docComment) {
3840
+ type.decorators.unshift(createDocFromCommentDecorator("self", docComment));
3609
3841
  }
3610
3842
  finishType(type);
3611
3843
  }
@@ -3929,6 +4161,8 @@ export function createChecker(program) {
3929
4161
  decorators.unshift(createDocFromCommentDecorator("errors", returnTypesDocs.errors));
3930
4162
  }
3931
4163
  }
4164
+ else if (targetType.kind === "ModelProperty") {
4165
+ }
3932
4166
  return decorators;
3933
4167
  }
3934
4168
  function checkScalar(node, mapper) {
@@ -3948,7 +4182,6 @@ export function createChecker(program) {
3948
4182
  decorators,
3949
4183
  derivedScalars: [],
3950
4184
  });
3951
- checkScalarConstructors(type, node, type.constructors, mapper);
3952
4185
  linkType(links, type, mapper);
3953
4186
  if (node.extends) {
3954
4187
  type.baseScalar = checkScalarExtends(node, node.extends, mapper);
@@ -3957,6 +4190,7 @@ export function createChecker(program) {
3957
4190
  type.baseScalar.derivedScalars.push(type);
3958
4191
  }
3959
4192
  }
4193
+ checkScalarConstructors(type, node, type.constructors, mapper);
3960
4194
  decorators.push(...checkDecorators(type, node, mapper));
3961
4195
  if (mapper === undefined) {
3962
4196
  type.namespace?.scalars.set(type.name, type);
@@ -4000,6 +4234,16 @@ export function createChecker(program) {
4000
4234
  return extendsType;
4001
4235
  }
4002
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
+ }
4003
4247
  for (const member of node.members) {
4004
4248
  const constructor = checkScalarConstructor(member, mapper, parentScalar);
4005
4249
  if (constructors.has(constructor.name)) {
@@ -4659,7 +4903,10 @@ export function createChecker(program) {
4659
4903
  * recursively by the caller.
4660
4904
  */
4661
4905
  function cloneType(type, additionalProps = {}) {
4662
- const clone = finishType(initializeClone(type, additionalProps));
4906
+ let clone = initializeClone(type, additionalProps);
4907
+ if (type.isFinished) {
4908
+ clone = finishType(clone);
4909
+ }
4663
4910
  const projection = projectionsByType.get(type);
4664
4911
  if (projection) {
4665
4912
  projectionsByType.set(clone, projection);
@@ -4677,6 +4924,10 @@ export function createChecker(program) {
4677
4924
  function cloneTypeForSymbol(sym, type, additionalProps = {}) {
4678
4925
  let clone = initializeClone(type, additionalProps);
4679
4926
  if ("decorators" in clone) {
4927
+ const docComment = docFromCommentForSym.get(sym);
4928
+ if (docComment) {
4929
+ clone.decorators.push(createDocFromCommentDecorator("self", docComment));
4930
+ }
4680
4931
  for (const dec of checkAugmentDecorators(sym, clone, undefined)) {
4681
4932
  clone.decorators.push(dec);
4682
4933
  }
@@ -6138,18 +6389,33 @@ function extractReturnsDocs(type) {
6138
6389
  }
6139
6390
  return result;
6140
6391
  }
6141
- function extractParamDoc(node, paramName) {
6392
+ function extractParamDocs(node) {
6142
6393
  if (node.docs === undefined) {
6143
- return undefined;
6394
+ return new Map();
6144
6395
  }
6396
+ const paramDocs = new Map();
6145
6397
  for (const doc of node.docs) {
6146
6398
  for (const tag of doc.tags) {
6147
- if (tag.kind === SyntaxKind.DocParamTag && tag.paramName.sv === paramName) {
6148
- return getDocContent(tag.content);
6399
+ if (tag.kind === SyntaxKind.DocParamTag) {
6400
+ paramDocs.set(tag.paramName.sv, getDocContent(tag.content));
6149
6401
  }
6150
6402
  }
6151
6403
  }
6152
- 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;
6153
6419
  }
6154
6420
  function getDocContent(content) {
6155
6421
  const docs = [];