@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.
- package/dist/generated-defs/TypeSpec.d.ts +30 -24
- package/dist/generated-defs/TypeSpec.d.ts.map +1 -1
- package/dist/generated-defs/TypeSpec.ts-test.js +2 -1
- package/dist/generated-defs/TypeSpec.ts-test.js.map +1 -1
- package/dist/manifest.js +2 -2
- package/dist/src/config/config-schema.d.ts +1 -1
- package/dist/src/config/config-schema.d.ts.map +1 -1
- package/dist/src/core/charcode.d.ts +4 -1
- package/dist/src/core/charcode.d.ts.map +1 -1
- package/dist/src/core/charcode.js +4 -4
- package/dist/src/core/charcode.js.map +1 -1
- package/dist/src/core/checker.d.ts.map +1 -1
- package/dist/src/core/checker.js +307 -26
- package/dist/src/core/checker.js.map +1 -1
- package/dist/src/core/cli/utils.d.ts.map +1 -1
- package/dist/src/core/cli/utils.js +1 -0
- package/dist/src/core/cli/utils.js.map +1 -1
- package/dist/src/core/index.d.ts +1 -0
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -0
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/linter.d.ts +5 -1
- package/dist/src/core/linter.d.ts.map +1 -1
- package/dist/src/core/linter.js +32 -13
- package/dist/src/core/linter.js.map +1 -1
- package/dist/src/core/messages.d.ts +5 -0
- package/dist/src/core/messages.d.ts.map +1 -1
- package/dist/src/core/messages.js +1 -0
- package/dist/src/core/messages.js.map +1 -1
- package/dist/src/core/parser.d.ts +11 -2
- package/dist/src/core/parser.d.ts.map +1 -1
- package/dist/src/core/parser.js +216 -60
- package/dist/src/core/parser.js.map +1 -1
- package/dist/src/core/program.d.ts.map +1 -1
- package/dist/src/core/program.js +4 -2
- package/dist/src/core/program.js.map +1 -1
- package/dist/src/core/scanner.d.ts +17 -1
- package/dist/src/core/scanner.d.ts.map +1 -1
- package/dist/src/core/scanner.js +97 -1
- package/dist/src/core/scanner.js.map +1 -1
- package/dist/src/core/schema-validator.js +1 -1
- package/dist/src/core/schema-validator.js.map +1 -1
- package/dist/src/core/types.d.ts +103 -50
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js +50 -46
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/emitter-framework/asset-emitter.js +2 -2
- package/dist/src/emitter-framework/asset-emitter.js.map +1 -1
- package/dist/src/emitter-framework/type-emitter.d.ts +1 -1
- package/dist/src/emitter-framework/type-emitter.js +1 -1
- package/dist/src/formatter/print/printer.d.ts +1 -1
- package/dist/src/formatter/print/printer.d.ts.map +1 -1
- package/dist/src/formatter/print/printer.js +91 -12
- package/dist/src/formatter/print/printer.js.map +1 -1
- package/dist/src/init/init-template.d.ts +1 -1
- package/dist/src/init/init-template.d.ts.map +1 -1
- package/dist/src/lib/decorators.d.ts +2 -1
- package/dist/src/lib/decorators.d.ts.map +1 -1
- package/dist/src/lib/decorators.js +17 -0
- package/dist/src/lib/decorators.js.map +1 -1
- package/dist/src/server/classify.d.ts.map +1 -1
- package/dist/src/server/classify.js +4 -0
- package/dist/src/server/classify.js.map +1 -1
- package/dist/src/server/compile-service.d.ts +2 -2
- package/dist/src/server/compile-service.d.ts.map +1 -1
- package/dist/src/server/compile-service.js +26 -1
- package/dist/src/server/compile-service.js.map +1 -1
- package/dist/src/server/completion.d.ts +2 -2
- package/dist/src/server/completion.d.ts.map +1 -1
- package/dist/src/server/completion.js +136 -9
- package/dist/src/server/completion.js.map +1 -1
- package/dist/src/server/file-system-cache.d.ts +3 -1
- package/dist/src/server/file-system-cache.d.ts.map +1 -1
- package/dist/src/server/file-system-cache.js +13 -2
- package/dist/src/server/file-system-cache.js.map +1 -1
- package/dist/src/server/server.js +35 -8
- package/dist/src/server/server.js.map +1 -1
- package/dist/src/server/serverlib.d.ts.map +1 -1
- package/dist/src/server/serverlib.js +13 -31
- package/dist/src/server/serverlib.js.map +1 -1
- package/dist/src/server/tmlanguage.d.ts.map +1 -1
- package/dist/src/server/tmlanguage.js +1 -1
- package/dist/src/server/tmlanguage.js.map +1 -1
- package/dist/src/server/type-details.js +14 -6
- package/dist/src/server/type-details.js.map +1 -1
- package/dist/src/server/types.d.ts +9 -3
- package/dist/src/server/types.d.ts.map +1 -1
- package/dist/src/server/types.js.map +1 -1
- package/dist/src/testing/test-server-host.js +2 -2
- package/dist/src/testing/test-server-host.js.map +1 -1
- package/dist/typespec.tmLanguage +1 -1
- package/lib/std/decorators.tsp +6 -0
- package/lib/std/types.tsp +12 -0
- package/package.json +12 -13
- package/templates/scaffolding.json +4 -4
package/dist/src/core/checker.js
CHANGED
|
@@ -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 =
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
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 =
|
|
4051
|
-
if (
|
|
4052
|
-
|
|
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
|
-
|
|
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
|
|
6392
|
+
function extractParamDocs(node) {
|
|
6127
6393
|
if (node.docs === undefined) {
|
|
6128
|
-
return
|
|
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
|
|
6133
|
-
|
|
6399
|
+
if (tag.kind === SyntaxKind.DocParamTag) {
|
|
6400
|
+
paramDocs.set(tag.paramName.sv, getDocContent(tag.content));
|
|
6134
6401
|
}
|
|
6135
6402
|
}
|
|
6136
6403
|
}
|
|
6137
|
-
return
|
|
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 = [];
|