@typespec/compiler 0.62.0-dev.9 → 0.63.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.
- package/dist/generated-defs/TypeSpec.Prototypes.d.ts +6 -0
- package/dist/generated-defs/TypeSpec.Prototypes.d.ts.map +1 -0
- package/dist/generated-defs/TypeSpec.Prototypes.js +2 -0
- package/dist/generated-defs/TypeSpec.Prototypes.js.map +1 -0
- package/dist/generated-defs/TypeSpec.Prototypes.ts-test.d.ts +2 -0
- package/dist/generated-defs/TypeSpec.Prototypes.ts-test.d.ts.map +1 -0
- package/dist/generated-defs/TypeSpec.Prototypes.ts-test.js +5 -0
- package/dist/generated-defs/TypeSpec.Prototypes.ts-test.js.map +1 -0
- package/dist/generated-defs/TypeSpec.d.ts +148 -8
- package/dist/generated-defs/TypeSpec.d.ts.map +1 -1
- package/dist/manifest.js +2 -2
- package/dist/src/core/binder.d.ts +8 -0
- package/dist/src/core/binder.d.ts.map +1 -1
- package/dist/src/core/binder.js +107 -43
- package/dist/src/core/binder.js.map +1 -1
- package/dist/src/core/checker.d.ts +3 -7
- package/dist/src/core/checker.d.ts.map +1 -1
- package/dist/src/core/checker.js +341 -824
- package/dist/src/core/checker.js.map +1 -1
- package/dist/src/core/cli/utils.js +1 -1
- package/dist/src/core/cli/utils.js.map +1 -1
- package/dist/src/core/diagnostics.d.ts +5 -1
- package/dist/src/core/diagnostics.d.ts.map +1 -1
- package/dist/src/core/diagnostics.js +33 -4
- package/dist/src/core/diagnostics.js.map +1 -1
- package/dist/src/core/helpers/operation-utils.d.ts.map +1 -1
- package/dist/src/core/helpers/operation-utils.js +4 -1
- package/dist/src/core/helpers/operation-utils.js.map +1 -1
- package/dist/src/core/helpers/syntax-utils.d.ts +2 -0
- package/dist/src/core/helpers/syntax-utils.d.ts.map +1 -1
- package/dist/src/core/helpers/syntax-utils.js +11 -0
- package/dist/src/core/helpers/syntax-utils.js.map +1 -1
- package/dist/src/core/index.d.ts +1 -1
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +1 -1
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/inspector/node.d.ts +2 -0
- package/dist/src/core/inspector/node.d.ts.map +1 -0
- package/dist/src/core/inspector/node.js +35 -0
- package/dist/src/core/inspector/node.js.map +1 -0
- package/dist/src/core/inspector/symbol.d.ts +3 -0
- package/dist/src/core/inspector/symbol.d.ts.map +1 -0
- package/dist/src/core/inspector/symbol.js +84 -0
- package/dist/src/core/inspector/symbol.js.map +1 -0
- package/dist/src/core/logger/console-sink.d.ts +1 -0
- package/dist/src/core/logger/console-sink.d.ts.map +1 -1
- package/dist/src/core/logger/console-sink.js +22 -6
- package/dist/src/core/logger/console-sink.js.map +1 -1
- package/dist/src/core/logger/logger.js +1 -1
- package/dist/src/core/logger/logger.js.map +1 -1
- package/dist/src/core/messages.d.ts +99 -43
- package/dist/src/core/messages.d.ts.map +1 -1
- package/dist/src/core/messages.js +29 -13
- package/dist/src/core/messages.js.map +1 -1
- package/dist/src/core/name-resolver.d.ts +107 -0
- package/dist/src/core/name-resolver.d.ts.map +1 -0
- package/dist/src/core/name-resolver.js +989 -0
- package/dist/src/core/name-resolver.js.map +1 -0
- package/dist/src/core/program.d.ts.map +1 -1
- package/dist/src/core/program.js +14 -4
- package/dist/src/core/program.js.map +1 -1
- package/dist/src/core/semantic-walker.d.ts.map +1 -1
- package/dist/src/core/semantic-walker.js +3 -1
- package/dist/src/core/semantic-walker.js.map +1 -1
- package/dist/src/core/type-utils.js +2 -2
- package/dist/src/core/type-utils.js.map +1 -1
- package/dist/src/core/types.d.ts +149 -35
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js +9 -0
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/decorators.d.ts +2 -13
- package/dist/src/lib/decorators.d.ts.map +1 -1
- package/dist/src/lib/decorators.js +1 -33
- package/dist/src/lib/decorators.js.map +1 -1
- package/dist/src/lib/intrinsic/decorators.d.ts +5 -0
- package/dist/src/lib/intrinsic/decorators.d.ts.map +1 -0
- package/dist/src/lib/intrinsic/decorators.js +25 -0
- package/dist/src/lib/intrinsic/decorators.js.map +1 -0
- package/dist/src/lib/intrinsic/tsp-index.d.ts +9 -0
- package/dist/src/lib/intrinsic/tsp-index.d.ts.map +1 -0
- package/dist/src/lib/intrinsic/tsp-index.js +11 -0
- package/dist/src/lib/intrinsic/tsp-index.js.map +1 -0
- package/dist/src/lib/paging.d.ts +112 -0
- package/dist/src/lib/paging.d.ts.map +1 -0
- package/dist/src/lib/paging.js +260 -0
- package/dist/src/lib/paging.js.map +1 -0
- package/dist/src/lib/tsp-index.d.ts.map +1 -1
- package/dist/src/lib/tsp-index.js +12 -2
- package/dist/src/lib/tsp-index.js.map +1 -1
- package/dist/src/server/completion.d.ts.map +1 -1
- package/dist/src/server/completion.js +7 -6
- package/dist/src/server/completion.js.map +1 -1
- package/dist/src/server/diagnostics.d.ts +8 -0
- package/dist/src/server/diagnostics.d.ts.map +1 -0
- package/dist/src/server/diagnostics.js +106 -0
- package/dist/src/server/diagnostics.js.map +1 -0
- package/dist/src/server/serverlib.d.ts.map +1 -1
- package/dist/src/server/serverlib.js +18 -43
- package/dist/src/server/serverlib.js.map +1 -1
- package/dist/src/server/type-details.js +3 -2
- package/dist/src/server/type-details.js.map +1 -1
- package/dist/src/server/type-signature.js +2 -1
- package/dist/src/server/type-signature.js.map +1 -1
- package/dist/src/testing/expect.js +1 -1
- package/dist/src/testing/expect.js.map +1 -1
- package/dist/src/testing/test-host.js +1 -1
- package/dist/src/testing/test-host.js.map +1 -1
- package/dist/src/testing/test-utils.d.ts +6 -0
- package/dist/src/testing/test-utils.d.ts.map +1 -1
- package/dist/src/testing/test-utils.js +19 -1
- package/dist/src/testing/test-utils.js.map +1 -1
- package/dist/src/utils/misc.d.ts +6 -5
- package/dist/src/utils/misc.d.ts.map +1 -1
- package/dist/src/utils/misc.js.map +1 -1
- package/lib/intrinsics.tsp +2 -1
- package/lib/prototypes.tsp +18 -0
- package/lib/std/decorators.tsp +151 -7
- package/package.json +5 -6
- package/templates/scaffolding.json +4 -4
- package/dist/src/lib/intrinsic-decorators.d.ts +0 -6
- package/dist/src/lib/intrinsic-decorators.d.ts.map +0 -1
- package/dist/src/lib/intrinsic-decorators.js +0 -17
- package/dist/src/lib/intrinsic-decorators.js.map +0 -1
package/dist/src/core/checker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { docFromCommentDecorator, getIndexer } from "../lib/intrinsic/decorators.js";
|
|
2
|
+
import { DuplicateTracker } from "../utils/duplicate-tracker.js";
|
|
2
3
|
import { MultiKeyMap, createRekeyableMap, isArray, mutate } from "../utils/misc.js";
|
|
3
|
-
import { createSymbol,
|
|
4
|
+
import { createSymbol, getSymNode } from "./binder.js";
|
|
4
5
|
import { createChangeIdentifierCodeFix } from "./compiler-code-fixes/change-identifier.codefix.js";
|
|
5
6
|
import { createModelToObjectValueCodeFix } from "./compiler-code-fixes/model-to-object-literal.codefix.js";
|
|
6
7
|
import { createTupleToArrayValueCodeFix } from "./compiler-code-fixes/tuple-to-array-value.codefix.js";
|
|
@@ -9,6 +10,7 @@ import { ProjectionError, compilerAssert, ignoreDiagnostics } from "./diagnostic
|
|
|
9
10
|
import { validateInheritanceDiscriminatedUnions } from "./helpers/discriminator-utils.js";
|
|
10
11
|
import { getLocationContext } from "./helpers/location-context.js";
|
|
11
12
|
import { explainStringTemplateNotSerializable } from "./helpers/string-template-utils.js";
|
|
13
|
+
import { typeReferenceToString } from "./helpers/syntax-utils.js";
|
|
12
14
|
import { getEntityName, getNamespaceFullName, getTypeName, } from "./helpers/type-name-utils.js";
|
|
13
15
|
import { legacyMarshallTypeForJS, marshallTypeForJS } from "./js-marshaller.js";
|
|
14
16
|
import { createDiagnostic } from "./messages.js";
|
|
@@ -17,20 +19,15 @@ import { exprIsBareIdentifier, getFirstAncestor, getIdentifierContext, hasParseE
|
|
|
17
19
|
import { createProjectionMembers } from "./projection-members.js";
|
|
18
20
|
import { createTypeRelationChecker } from "./type-relation-checker.js";
|
|
19
21
|
import { getFullyQualifiedSymbolName, getParentTemplateNode, isArrayModelType, isErrorType, isNullType, isTemplateInstance, isType, isValue, } from "./type-utils.js";
|
|
20
|
-
import { IdentifierKind, SyntaxKind, } from "./types.js";
|
|
22
|
+
import { IdentifierKind, ResolutionResultFlags, SyntaxKind, } from "./types.js";
|
|
21
23
|
/**
|
|
22
24
|
* Maps type arguments to type instantiation.
|
|
23
25
|
*/
|
|
24
26
|
const TypeInstantiationMap = class extends MultiKeyMap {
|
|
25
27
|
};
|
|
26
|
-
|
|
27
|
-
export function createChecker(program) {
|
|
28
|
+
export function createChecker(program, resolver) {
|
|
28
29
|
const stdTypes = {};
|
|
29
|
-
const symbolLinks = new Map();
|
|
30
|
-
const mergedSymbols = new Map();
|
|
31
30
|
const docFromCommentForSym = new Map();
|
|
32
|
-
const augmentDecoratorsForSym = new Map();
|
|
33
|
-
const augmentedSymbolTables = new Map();
|
|
34
31
|
const referenceSymCache = new WeakMap();
|
|
35
32
|
const valueExactTypes = new WeakMap();
|
|
36
33
|
let onCheckerDiagnostic = (x) => {
|
|
@@ -44,7 +41,6 @@ export function createChecker(program) {
|
|
|
44
41
|
return this.projections.filter((p) => p.id.sv === name);
|
|
45
42
|
},
|
|
46
43
|
};
|
|
47
|
-
const globalNamespaceNode = createGlobalNamespaceNode();
|
|
48
44
|
const globalNamespaceType = createGlobalNamespaceType();
|
|
49
45
|
// Caches the deprecation test of nodes in the program
|
|
50
46
|
const nodeDeprecationMap = new Map();
|
|
@@ -53,7 +49,6 @@ export function createChecker(program) {
|
|
|
53
49
|
const neverType = createType({ kind: "Intrinsic", name: "never" });
|
|
54
50
|
const unknownType = createType({ kind: "Intrinsic", name: "unknown" });
|
|
55
51
|
const nullType = createType({ kind: "Intrinsic", name: "null" });
|
|
56
|
-
const nullSym = createSymbol(undefined, "null", 0 /* SymbolFlags.None */);
|
|
57
52
|
const projectionsByTypeKind = new Map([
|
|
58
53
|
["Model", []],
|
|
59
54
|
["ModelProperty", []],
|
|
@@ -76,21 +71,9 @@ export function createChecker(program) {
|
|
|
76
71
|
* Key is the SymId of a node. It can be retrieved with getNodeSymId(node)
|
|
77
72
|
*/
|
|
78
73
|
const pendingResolutions = new PendingResolutions();
|
|
79
|
-
|
|
80
|
-
mergeSourceFile(file);
|
|
81
|
-
}
|
|
82
|
-
for (const file of program.sourceFiles.values()) {
|
|
83
|
-
mergeSourceFile(file);
|
|
84
|
-
}
|
|
85
|
-
const typespecNamespaceBinding = globalNamespaceNode.symbol.exports.get("TypeSpec");
|
|
74
|
+
const typespecNamespaceBinding = resolver.symbols.global.exports.get("TypeSpec");
|
|
86
75
|
if (typespecNamespaceBinding) {
|
|
87
76
|
initializeTypeSpecIntrinsics();
|
|
88
|
-
for (const file of program.sourceFiles.values()) {
|
|
89
|
-
addUsingSymbols(typespecNamespaceBinding.exports, file.locals);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
for (const file of program.sourceFiles.values()) {
|
|
93
|
-
setUsingsForFile(file);
|
|
94
77
|
}
|
|
95
78
|
let evalContext = undefined;
|
|
96
79
|
const checker = {
|
|
@@ -102,9 +85,7 @@ export function createChecker(program) {
|
|
|
102
85
|
getNamespaceString: getNamespaceFullName,
|
|
103
86
|
getGlobalNamespaceType,
|
|
104
87
|
getGlobalNamespaceNode,
|
|
105
|
-
setUsingsForFile,
|
|
106
88
|
getMergedSymbol,
|
|
107
|
-
mergeSourceFile,
|
|
108
89
|
cloneType,
|
|
109
90
|
resolveIdentifier,
|
|
110
91
|
resolveCompletions,
|
|
@@ -133,8 +114,19 @@ export function createChecker(program) {
|
|
|
133
114
|
checker.isTypeAssignableTo = relation.isTypeAssignableTo;
|
|
134
115
|
const projectionMembers = createProjectionMembers(checker);
|
|
135
116
|
return checker;
|
|
136
|
-
function
|
|
137
|
-
|
|
117
|
+
function wrapInstantiationDiagnostic(diagnostic, templateMapper) {
|
|
118
|
+
if (templateMapper === undefined || typeof diagnostic.target !== "object")
|
|
119
|
+
return diagnostic;
|
|
120
|
+
return {
|
|
121
|
+
...diagnostic,
|
|
122
|
+
target: {
|
|
123
|
+
node: diagnostic.target,
|
|
124
|
+
templateMapper,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function reportCheckerDiagnostic(diagnostic, mapper) {
|
|
129
|
+
onCheckerDiagnostic(wrapInstantiationDiagnostic(diagnostic, mapper));
|
|
138
130
|
}
|
|
139
131
|
function reportCheckerDiagnostics(diagnostics) {
|
|
140
132
|
diagnostics.forEach((x) => reportCheckerDiagnostic(x));
|
|
@@ -142,18 +134,18 @@ export function createChecker(program) {
|
|
|
142
134
|
function initializeTypeSpecIntrinsics() {
|
|
143
135
|
// a utility function to log strings or numbers
|
|
144
136
|
mutate(typespecNamespaceBinding.exports).set("log", {
|
|
145
|
-
flags:
|
|
137
|
+
flags: 8192 /* SymbolFlags.Function */,
|
|
146
138
|
name: "log",
|
|
147
139
|
value(p, ...strs) {
|
|
148
140
|
program.trace("projection.log", strs.join(" "));
|
|
149
141
|
return voidType;
|
|
150
142
|
},
|
|
151
143
|
declarations: [],
|
|
144
|
+
node: undefined, // TODO: is this correct?
|
|
152
145
|
});
|
|
153
146
|
// Until we have an `unit` type for `null`
|
|
154
|
-
mutate(
|
|
155
|
-
|
|
156
|
-
getSymbolLinks(nullSym).type = nullType;
|
|
147
|
+
mutate(resolver.symbols.null).type = nullType;
|
|
148
|
+
getSymbolLinks(resolver.symbols.null).type = nullType;
|
|
157
149
|
}
|
|
158
150
|
function getStdType(name) {
|
|
159
151
|
const type = stdTypes[name];
|
|
@@ -161,7 +153,8 @@ export function createChecker(program) {
|
|
|
161
153
|
return type;
|
|
162
154
|
}
|
|
163
155
|
const sym = typespecNamespaceBinding?.exports?.get(name);
|
|
164
|
-
|
|
156
|
+
compilerAssert(sym, `Unexpected missing symbol to std type "${name}"`);
|
|
157
|
+
if (sym.flags & 2 /* SymbolFlags.Model */) {
|
|
165
158
|
checkModelStatement(sym.declarations[0], undefined);
|
|
166
159
|
}
|
|
167
160
|
else {
|
|
@@ -171,105 +164,6 @@ export function createChecker(program) {
|
|
|
171
164
|
compilerAssert(loadedType, `TypeSpec std type "${name}" should have been initalized before using array syntax.`);
|
|
172
165
|
return loadedType;
|
|
173
166
|
}
|
|
174
|
-
function mergeSourceFile(file) {
|
|
175
|
-
mergeSymbolTable(file.symbol.exports, mutate(globalNamespaceNode.symbol.exports));
|
|
176
|
-
}
|
|
177
|
-
function setUsingsForFile(file) {
|
|
178
|
-
const usedUsing = new Set();
|
|
179
|
-
for (const using of file.usings) {
|
|
180
|
-
const parentNs = using.parent;
|
|
181
|
-
const sym = resolveTypeReferenceSym(using.name, undefined);
|
|
182
|
-
if (!sym) {
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
if (!(sym.flags & 4096 /* SymbolFlags.Namespace */)) {
|
|
186
|
-
reportCheckerDiagnostic(createDiagnostic({ code: "using-invalid-ref", target: using }));
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
const namespaceSym = getMergedSymbol(sym);
|
|
190
|
-
if (usedUsing.has(namespaceSym)) {
|
|
191
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
192
|
-
code: "duplicate-using",
|
|
193
|
-
format: { usingName: memberExpressionToString(using.name) },
|
|
194
|
-
target: using,
|
|
195
|
-
}));
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
usedUsing.add(namespaceSym);
|
|
199
|
-
addUsingSymbols(sym.exports, parentNs.locals);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function applyAugmentDecorators(node) {
|
|
203
|
-
if (!node.statements || !isArray(node.statements)) {
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const augmentDecorators = node.statements.filter((x) => x.kind === SyntaxKind.AugmentDecoratorStatement);
|
|
207
|
-
for (const decNode of augmentDecorators) {
|
|
208
|
-
const ref = resolveTypeReferenceSym(decNode.targetType, undefined);
|
|
209
|
-
if (ref) {
|
|
210
|
-
let args = [];
|
|
211
|
-
if (ref.declarations[0].kind === SyntaxKind.AliasStatement) {
|
|
212
|
-
const aliasNode = ref.declarations[0];
|
|
213
|
-
if (aliasNode.value.kind === SyntaxKind.TypeReference) {
|
|
214
|
-
args = aliasNode.value.arguments;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
args = decNode.targetType.arguments;
|
|
219
|
-
}
|
|
220
|
-
if (ref.flags & 4096 /* SymbolFlags.Namespace */) {
|
|
221
|
-
const links = getSymbolLinks(getMergedSymbol(ref));
|
|
222
|
-
const type = links.type;
|
|
223
|
-
const decApp = checkDecoratorApplication(type, decNode, undefined);
|
|
224
|
-
if (decApp) {
|
|
225
|
-
type.decorators.push(decApp);
|
|
226
|
-
applyDecoratorToType(program, decApp, type);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
else if (args.length > 0 || ref.flags & 67108864 /* SymbolFlags.LateBound */) {
|
|
230
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
231
|
-
code: "augment-decorator-target",
|
|
232
|
-
messageId: "noInstance",
|
|
233
|
-
target: decNode.target,
|
|
234
|
-
}));
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
let list = augmentDecoratorsForSym.get(ref);
|
|
238
|
-
if (list === undefined) {
|
|
239
|
-
list = [];
|
|
240
|
-
augmentDecoratorsForSym.set(ref, list);
|
|
241
|
-
}
|
|
242
|
-
list.unshift(decNode);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
function addUsingSymbols(source, destination) {
|
|
248
|
-
const augmented = getOrCreateAugmentedSymbolTable(destination);
|
|
249
|
-
for (const symbolSource of source.values()) {
|
|
250
|
-
const sym = {
|
|
251
|
-
flags: 524288 /* SymbolFlags.Using */,
|
|
252
|
-
declarations: [],
|
|
253
|
-
name: symbolSource.name,
|
|
254
|
-
symbolSource: symbolSource,
|
|
255
|
-
};
|
|
256
|
-
augmented.set(sym.name, sym);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* We cannot inject symbols into the symbol tables hanging off syntax tree nodes as
|
|
261
|
-
* syntax tree nodes can be shared by other programs. This is called as a copy-on-write
|
|
262
|
-
* to inject using and late-bound symbols, and then we use the copy when resolving
|
|
263
|
-
* in the table.
|
|
264
|
-
*/
|
|
265
|
-
function getOrCreateAugmentedSymbolTable(table) {
|
|
266
|
-
let augmented = augmentedSymbolTables.get(table);
|
|
267
|
-
if (!augmented) {
|
|
268
|
-
augmented = createSymbolTable(table);
|
|
269
|
-
augmentedSymbolTables.set(table, augmented);
|
|
270
|
-
}
|
|
271
|
-
return mutate(augmented);
|
|
272
|
-
}
|
|
273
167
|
/**
|
|
274
168
|
* Create the link for the given type to the symbol links.
|
|
275
169
|
* If currently instantiating a template it will link to the instantiations.
|
|
@@ -300,13 +194,13 @@ export function createChecker(program) {
|
|
|
300
194
|
*/
|
|
301
195
|
function checkMemberSym(sym, mapper) {
|
|
302
196
|
const symbolLinks = getSymbolLinks(sym);
|
|
303
|
-
const memberContainer = getTypeForNode(sym.parent
|
|
197
|
+
const memberContainer = getTypeForNode(getSymNode(sym.parent), mapper);
|
|
304
198
|
const type = symbolLinks.declaredType ?? symbolLinks.type;
|
|
305
199
|
if (type) {
|
|
306
200
|
return type;
|
|
307
201
|
}
|
|
308
202
|
else {
|
|
309
|
-
return checkMember(sym
|
|
203
|
+
return checkMember(getSymNode(sym), mapper, memberContainer);
|
|
310
204
|
}
|
|
311
205
|
}
|
|
312
206
|
/**
|
|
@@ -660,6 +554,10 @@ export function createChecker(program) {
|
|
|
660
554
|
return checkCallExpression(node, mapper);
|
|
661
555
|
case SyntaxKind.TypeOfExpression:
|
|
662
556
|
return checkTypeOfExpression(node, mapper);
|
|
557
|
+
case SyntaxKind.AugmentDecoratorStatement:
|
|
558
|
+
return checkAugmentDecorator(node);
|
|
559
|
+
case SyntaxKind.UsingStatement:
|
|
560
|
+
return checkUsings(node);
|
|
663
561
|
default:
|
|
664
562
|
return errorType;
|
|
665
563
|
}
|
|
@@ -667,13 +565,12 @@ export function createChecker(program) {
|
|
|
667
565
|
/**
|
|
668
566
|
* Return a fully qualified id of node
|
|
669
567
|
*/
|
|
670
|
-
function
|
|
568
|
+
function getNodeSym(node) {
|
|
671
569
|
const symbol = node.kind === SyntaxKind.OperationStatement &&
|
|
672
570
|
node.parent?.kind === SyntaxKind.InterfaceStatement
|
|
673
571
|
? getSymbolForMember(node)
|
|
674
572
|
: node.symbol;
|
|
675
|
-
|
|
676
|
-
return symbol?.id;
|
|
573
|
+
return symbol;
|
|
677
574
|
}
|
|
678
575
|
/**
|
|
679
576
|
* Check if the given namespace is the standard library `TypeSpec` namespace.
|
|
@@ -693,7 +590,7 @@ export function createChecker(program) {
|
|
|
693
590
|
const parentNode = node.parent;
|
|
694
591
|
const grandParentNode = parentNode.parent;
|
|
695
592
|
const links = getSymbolLinks(node.symbol);
|
|
696
|
-
if (pendingResolutions.has(
|
|
593
|
+
if (pendingResolutions.has(getNodeSym(node), ResolutionKind.Constraint)) {
|
|
697
594
|
if (mapper === undefined) {
|
|
698
595
|
reportCheckerDiagnostic(createDiagnostic({
|
|
699
596
|
code: "circular-constraint",
|
|
@@ -720,9 +617,9 @@ export function createChecker(program) {
|
|
|
720
617
|
node: node,
|
|
721
618
|
});
|
|
722
619
|
if (node.constraint) {
|
|
723
|
-
pendingResolutions.start(
|
|
620
|
+
pendingResolutions.start(getNodeSym(node), ResolutionKind.Constraint);
|
|
724
621
|
type.constraint = getParamConstraintEntityForNode(node.constraint);
|
|
725
|
-
pendingResolutions.finish(
|
|
622
|
+
pendingResolutions.finish(getNodeSym(node), ResolutionKind.Constraint);
|
|
726
623
|
}
|
|
727
624
|
if (node.default) {
|
|
728
625
|
type.default = checkTemplateParameterDefault(node.default, parentNode.templateParameters, index, type.constraint);
|
|
@@ -938,7 +835,7 @@ export function createChecker(program) {
|
|
|
938
835
|
mapperArgs.push(type);
|
|
939
836
|
}
|
|
940
837
|
if (init === null) {
|
|
941
|
-
const argumentMapper = createTypeMapper(mapperParams, mapperArgs);
|
|
838
|
+
const argumentMapper = createTypeMapper(mapperParams, mapperArgs, { node, mapper });
|
|
942
839
|
const defaultValue = getResolvedTypeParameterDefault(param, decl, argumentMapper);
|
|
943
840
|
if (defaultValue) {
|
|
944
841
|
commit(param, defaultValue);
|
|
@@ -1020,27 +917,28 @@ export function createChecker(program) {
|
|
|
1020
917
|
return result;
|
|
1021
918
|
}
|
|
1022
919
|
function checkTypeOrValueReferenceSymbol(sym, node, mapper, instantiateTemplates = true) {
|
|
1023
|
-
if (sym.flags &
|
|
920
|
+
if (sym.flags & 524288 /* SymbolFlags.Const */) {
|
|
1024
921
|
return getValueForNode(sym.declarations[0], mapper);
|
|
1025
922
|
}
|
|
1026
|
-
if (sym.flags &
|
|
923
|
+
if (sym.flags & 1024 /* SymbolFlags.Decorator */) {
|
|
1027
924
|
reportCheckerDiagnostic(createDiagnostic({ code: "invalid-type-ref", messageId: "decorator", target: sym }));
|
|
1028
925
|
return errorType;
|
|
1029
926
|
}
|
|
1030
|
-
if (sym.flags &
|
|
927
|
+
if (sym.flags & 8192 /* SymbolFlags.Function */) {
|
|
1031
928
|
reportCheckerDiagnostic(createDiagnostic({ code: "invalid-type-ref", messageId: "function", target: sym }));
|
|
1032
929
|
return errorType;
|
|
1033
930
|
}
|
|
1034
931
|
const argumentNodes = node.kind === SyntaxKind.TypeReference ? node.arguments : [];
|
|
1035
932
|
const symbolLinks = getSymbolLinks(sym);
|
|
1036
933
|
let baseType;
|
|
1037
|
-
if (sym.flags &
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
934
|
+
if (sym.flags & 1048576 /* SymbolFlags.Declaration */ &&
|
|
935
|
+
sym.flags &
|
|
936
|
+
(2 /* SymbolFlags.Model */ |
|
|
937
|
+
4 /* SymbolFlags.Scalar */ |
|
|
938
|
+
128 /* SymbolFlags.Alias */ |
|
|
939
|
+
32 /* SymbolFlags.Interface */ |
|
|
940
|
+
8 /* SymbolFlags.Operation */ |
|
|
941
|
+
64 /* SymbolFlags.Union */)) {
|
|
1044
942
|
const decl = sym.declarations[0];
|
|
1045
943
|
if (!isTemplatedNode(decl)) {
|
|
1046
944
|
if (argumentNodes.length > 0) {
|
|
@@ -1050,14 +948,14 @@ export function createChecker(program) {
|
|
|
1050
948
|
target: node,
|
|
1051
949
|
}));
|
|
1052
950
|
}
|
|
1053
|
-
if (sym.flags &
|
|
951
|
+
if (sym.flags & 4194304 /* SymbolFlags.LateBound */) {
|
|
1054
952
|
compilerAssert(sym.type, "Expected late bound symbol to have type");
|
|
1055
953
|
return sym.type;
|
|
1056
954
|
}
|
|
1057
955
|
else if (symbolLinks.declaredType) {
|
|
1058
956
|
baseType = symbolLinks.declaredType;
|
|
1059
957
|
}
|
|
1060
|
-
else if (sym.flags &
|
|
958
|
+
else if (sym.flags & 262144 /* SymbolFlags.Member */) {
|
|
1061
959
|
baseType = checkMemberSym(sym, mapper);
|
|
1062
960
|
}
|
|
1063
961
|
else {
|
|
@@ -1068,10 +966,11 @@ export function createChecker(program) {
|
|
|
1068
966
|
const declaredType = getOrCheckDeclaredType(sym, decl, mapper);
|
|
1069
967
|
const templateParameters = decl.templateParameters;
|
|
1070
968
|
const instantiation = checkTemplateInstantiationArgs(node, argumentNodes, templateParameters, mapper);
|
|
1071
|
-
baseType = getOrInstantiateTemplate(decl, [...instantiation.keys()], [...instantiation.values()], declaredType.templateMapper, instantiateTemplates);
|
|
969
|
+
baseType = getOrInstantiateTemplate(decl, [...instantiation.keys()], [...instantiation.values()], { node, mapper }, declaredType.templateMapper, instantiateTemplates);
|
|
1072
970
|
}
|
|
1073
971
|
}
|
|
1074
972
|
else {
|
|
973
|
+
const symNode = getSymNode(sym);
|
|
1075
974
|
// some other kind of reference
|
|
1076
975
|
if (argumentNodes.length > 0) {
|
|
1077
976
|
reportCheckerDiagnostic(createDiagnostic({
|
|
@@ -1080,12 +979,12 @@ export function createChecker(program) {
|
|
|
1080
979
|
target: node,
|
|
1081
980
|
}));
|
|
1082
981
|
}
|
|
1083
|
-
if (sym.flags &
|
|
982
|
+
if (sym.flags & 4194304 /* SymbolFlags.LateBound */) {
|
|
1084
983
|
compilerAssert(sym.type, `Expected late bound symbol to have type`);
|
|
1085
984
|
return sym.type;
|
|
1086
985
|
}
|
|
1087
|
-
else if (sym.flags &
|
|
1088
|
-
const mapped = checkTemplateParameterDeclaration(
|
|
986
|
+
else if (sym.flags & 2048 /* SymbolFlags.TemplateParameter */) {
|
|
987
|
+
const mapped = checkTemplateParameterDeclaration(symNode, mapper);
|
|
1089
988
|
baseType = mapped;
|
|
1090
989
|
}
|
|
1091
990
|
else if (symbolLinks.type) {
|
|
@@ -1096,12 +995,12 @@ export function createChecker(program) {
|
|
|
1096
995
|
baseType = symbolLinks.declaredType;
|
|
1097
996
|
}
|
|
1098
997
|
else {
|
|
1099
|
-
if (sym.flags &
|
|
998
|
+
if (sym.flags & 262144 /* SymbolFlags.Member */) {
|
|
1100
999
|
baseType = checkMemberSym(sym, mapper);
|
|
1101
1000
|
}
|
|
1102
1001
|
else {
|
|
1103
1002
|
// don't have a cached type for this symbol, so go grab it and cache it
|
|
1104
|
-
baseType = getTypeForNode(
|
|
1003
|
+
baseType = getTypeForNode(symNode, mapper);
|
|
1105
1004
|
symbolLinks.type = baseType;
|
|
1106
1005
|
}
|
|
1107
1006
|
}
|
|
@@ -1109,7 +1008,7 @@ export function createChecker(program) {
|
|
|
1109
1008
|
// Check for deprecations here, first on symbol, then on type. However,
|
|
1110
1009
|
// don't raise deprecation when the usage site is also a deprecated
|
|
1111
1010
|
// declaration.
|
|
1112
|
-
const declarationNode = sym
|
|
1011
|
+
const declarationNode = getSymNode(sym);
|
|
1113
1012
|
if (declarationNode && mapper === undefined && isType(baseType)) {
|
|
1114
1013
|
if (!isTypeReferenceContextDeprecated(node.parent)) {
|
|
1115
1014
|
checkDeprecated(baseType, declarationNode, node);
|
|
@@ -1134,11 +1033,11 @@ export function createChecker(program) {
|
|
|
1134
1033
|
if (symbolLinks.declaredType) {
|
|
1135
1034
|
return symbolLinks.declaredType;
|
|
1136
1035
|
}
|
|
1137
|
-
if (sym.flags &
|
|
1036
|
+
if (sym.flags & 4194304 /* SymbolFlags.LateBound */) {
|
|
1138
1037
|
compilerAssert(sym.type, "Expected late bound symbol to have type");
|
|
1139
1038
|
return sym.type;
|
|
1140
1039
|
}
|
|
1141
|
-
if (sym.flags &
|
|
1040
|
+
if (sym.flags & 262144 /* SymbolFlags.Member */) {
|
|
1142
1041
|
return checkMemberSym(sym, mapper);
|
|
1143
1042
|
}
|
|
1144
1043
|
else {
|
|
@@ -1155,13 +1054,13 @@ export function createChecker(program) {
|
|
|
1155
1054
|
function checkDeclaredTypeOrIndeterminate(sym, node, mapper) {
|
|
1156
1055
|
const type = sym.flags & 2 /* SymbolFlags.Model */
|
|
1157
1056
|
? checkModelStatement(node, mapper)
|
|
1158
|
-
: sym.flags &
|
|
1057
|
+
: sym.flags & 4 /* SymbolFlags.Scalar */
|
|
1159
1058
|
? checkScalar(node, mapper)
|
|
1160
|
-
: sym.flags &
|
|
1059
|
+
: sym.flags & 128 /* SymbolFlags.Alias */
|
|
1161
1060
|
? checkAlias(node, mapper)
|
|
1162
|
-
: sym.flags &
|
|
1061
|
+
: sym.flags & 32 /* SymbolFlags.Interface */
|
|
1163
1062
|
? checkInterface(node, mapper)
|
|
1164
|
-
: sym.flags &
|
|
1063
|
+
: sym.flags & 8 /* SymbolFlags.Operation */
|
|
1165
1064
|
? checkOperation(node, mapper)
|
|
1166
1065
|
: checkUnion(node, mapper);
|
|
1167
1066
|
return type;
|
|
@@ -1169,7 +1068,7 @@ export function createChecker(program) {
|
|
|
1169
1068
|
function checkDeclaredType(sym, node, mapper) {
|
|
1170
1069
|
return getTypeForTypeOrIndeterminate(checkDeclaredTypeOrIndeterminate(sym, node, mapper));
|
|
1171
1070
|
}
|
|
1172
|
-
function getOrInstantiateTemplate(templateNode, params, args, parentMapper, instantiateTempalates = true) {
|
|
1071
|
+
function getOrInstantiateTemplate(templateNode, params, args, source, parentMapper, instantiateTempalates = true) {
|
|
1173
1072
|
const symbolLinks = templateNode.kind === SyntaxKind.OperationStatement &&
|
|
1174
1073
|
templateNode.parent.kind === SyntaxKind.InterfaceStatement
|
|
1175
1074
|
? getSymbolLinksForMember(templateNode)
|
|
@@ -1184,7 +1083,7 @@ export function createChecker(program) {
|
|
|
1184
1083
|
compilerAssert(false, `Unexpected checker error. symbolLinks.instantiations was not defined for ${SyntaxKind[templateNode.kind]}`);
|
|
1185
1084
|
}
|
|
1186
1085
|
}
|
|
1187
|
-
const mapper = createTypeMapper(params, args, parentMapper);
|
|
1086
|
+
const mapper = createTypeMapper(params, args, source, parentMapper);
|
|
1188
1087
|
const cached = symbolLinks.instantiations?.get(mapper.args);
|
|
1189
1088
|
if (cached) {
|
|
1190
1089
|
return cached;
|
|
@@ -1309,8 +1208,15 @@ export function createChecker(program) {
|
|
|
1309
1208
|
* with unions). The resulting model is anonymous.
|
|
1310
1209
|
*/
|
|
1311
1210
|
function checkIntersectionExpression(node, mapper) {
|
|
1211
|
+
const links = getSymbolLinks(node.symbol);
|
|
1212
|
+
if (links.declaredType && mapper === undefined) {
|
|
1213
|
+
// we're not instantiating this model and we've already checked it
|
|
1214
|
+
return links.declaredType;
|
|
1215
|
+
}
|
|
1312
1216
|
const options = node.options.map((o) => [o, getTypeForNode(o, mapper)]);
|
|
1313
|
-
|
|
1217
|
+
const type = mergeModelTypes(node.symbol, node, options, mapper);
|
|
1218
|
+
linkType(links, type, mapper);
|
|
1219
|
+
return type;
|
|
1314
1220
|
}
|
|
1315
1221
|
function checkDecoratorDeclaration(node, mapper) {
|
|
1316
1222
|
const symbol = getMergedSymbol(node.symbol);
|
|
@@ -1441,7 +1347,7 @@ export function createChecker(program) {
|
|
|
1441
1347
|
};
|
|
1442
1348
|
}
|
|
1443
1349
|
}
|
|
1444
|
-
function mergeModelTypes(node, options, mapper) {
|
|
1350
|
+
function mergeModelTypes(parentModelSym, node, options, mapper) {
|
|
1445
1351
|
const properties = createRekeyableMap();
|
|
1446
1352
|
const intersection = createType({
|
|
1447
1353
|
kind: "Model",
|
|
@@ -1491,11 +1397,16 @@ export function createChecker(program) {
|
|
|
1491
1397
|
}));
|
|
1492
1398
|
continue;
|
|
1493
1399
|
}
|
|
1494
|
-
const
|
|
1400
|
+
const memberSym = parentModelSym && getMemberSymbol(parentModelSym, prop.name);
|
|
1401
|
+
const overrides = {
|
|
1495
1402
|
sourceProperty: prop,
|
|
1496
1403
|
model: intersection,
|
|
1497
|
-
}
|
|
1404
|
+
};
|
|
1405
|
+
const newPropType = memberSym
|
|
1406
|
+
? cloneTypeForSymbol(memberSym, prop, overrides)
|
|
1407
|
+
: cloneType(prop, overrides);
|
|
1498
1408
|
properties.set(prop.name, newPropType);
|
|
1409
|
+
linkIndirectMember(node, newPropType, mapper);
|
|
1499
1410
|
for (const indexer of indexers.filter((x) => x !== option.indexer)) {
|
|
1500
1411
|
checkPropertyCompatibleWithIndexer(indexer, prop, node);
|
|
1501
1412
|
}
|
|
@@ -1507,7 +1418,7 @@ export function createChecker(program) {
|
|
|
1507
1418
|
else if (indexers.length > 1) {
|
|
1508
1419
|
intersection.indexer = {
|
|
1509
1420
|
key: indexers[0].key,
|
|
1510
|
-
value: mergeModelTypes(node, indexers.map((x) => [x.value.node, x.value]), mapper),
|
|
1421
|
+
value: mergeModelTypes(undefined, node, indexers.map((x) => [x.value.node, x.value]), mapper),
|
|
1511
1422
|
};
|
|
1512
1423
|
}
|
|
1513
1424
|
linkMapper(intersection, mapper);
|
|
@@ -1518,7 +1429,7 @@ export function createChecker(program) {
|
|
|
1518
1429
|
const arrayType = getStdType("Array");
|
|
1519
1430
|
const arrayNode = arrayType.node;
|
|
1520
1431
|
const param = getTypeForNode(arrayNode.templateParameters[0]);
|
|
1521
|
-
return getOrInstantiateTemplate(arrayNode, [param], [elementType], undefined);
|
|
1432
|
+
return getOrInstantiateTemplate(arrayNode, [param], [elementType], { node, mapper }, undefined);
|
|
1522
1433
|
}
|
|
1523
1434
|
function checkNamespace(node) {
|
|
1524
1435
|
const links = getSymbolLinks(getMergedSymbol(node.symbol));
|
|
@@ -1643,9 +1554,9 @@ export function createChecker(program) {
|
|
|
1643
1554
|
const namespace = getParentNamespaceType(node);
|
|
1644
1555
|
const name = node.id.sv;
|
|
1645
1556
|
let decorators = [];
|
|
1646
|
-
const parameterModelSym =
|
|
1557
|
+
const { resolvedSymbol: parameterModelSym } = resolver.resolveMetaMemberByName(symbol, "parameters");
|
|
1647
1558
|
if (parameterModelSym?.members) {
|
|
1648
|
-
const members =
|
|
1559
|
+
const members = resolver.getAugmentedSymbolTable(parameterModelSym.members);
|
|
1649
1560
|
const paramDocs = extractParamDocs(node);
|
|
1650
1561
|
for (const [name, memberSym] of members) {
|
|
1651
1562
|
const doc = paramDocs.get(name);
|
|
@@ -1732,27 +1643,24 @@ export function createChecker(program) {
|
|
|
1732
1643
|
if (!opReference)
|
|
1733
1644
|
return undefined;
|
|
1734
1645
|
// Ensure that we don't end up with a circular reference to the same operation
|
|
1735
|
-
const opSymId =
|
|
1646
|
+
const opSymId = getNodeSym(operation);
|
|
1736
1647
|
if (opSymId) {
|
|
1737
1648
|
pendingResolutions.start(opSymId, ResolutionKind.BaseType);
|
|
1738
1649
|
}
|
|
1739
|
-
const target =
|
|
1740
|
-
if (target === undefined) {
|
|
1741
|
-
return undefined;
|
|
1742
|
-
}
|
|
1650
|
+
const target = resolver.getNodeLinks(opReference).resolvedSymbol;
|
|
1743
1651
|
// Did we encounter a circular operation reference?
|
|
1744
|
-
if (pendingResolutions.has(
|
|
1652
|
+
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
1745
1653
|
if (mapper === undefined) {
|
|
1746
1654
|
reportCheckerDiagnostic(createDiagnostic({
|
|
1747
1655
|
code: "circular-op-signature",
|
|
1748
|
-
format: { typeName: target.
|
|
1656
|
+
format: { typeName: target.name },
|
|
1749
1657
|
target: opReference,
|
|
1750
1658
|
}));
|
|
1751
1659
|
}
|
|
1752
1660
|
return undefined;
|
|
1753
1661
|
}
|
|
1754
1662
|
// Resolve the base operation type
|
|
1755
|
-
const baseOperation =
|
|
1663
|
+
const baseOperation = getTypeForNode(opReference, mapper);
|
|
1756
1664
|
if (opSymId) {
|
|
1757
1665
|
pendingResolutions.finish(opSymId, ResolutionKind.BaseType);
|
|
1758
1666
|
}
|
|
@@ -1770,7 +1678,7 @@ export function createChecker(program) {
|
|
|
1770
1678
|
return globalNamespaceType;
|
|
1771
1679
|
}
|
|
1772
1680
|
function getGlobalNamespaceNode() {
|
|
1773
|
-
return
|
|
1681
|
+
return resolver.symbols.global.declarations[0];
|
|
1774
1682
|
}
|
|
1775
1683
|
function checkTupleExpression(node, mapper) {
|
|
1776
1684
|
return createAndFinishType({
|
|
@@ -1780,47 +1688,7 @@ export function createChecker(program) {
|
|
|
1780
1688
|
});
|
|
1781
1689
|
}
|
|
1782
1690
|
function getSymbolLinks(s) {
|
|
1783
|
-
|
|
1784
|
-
if (symbolLinks.has(id)) {
|
|
1785
|
-
return symbolLinks.get(id);
|
|
1786
|
-
}
|
|
1787
|
-
const links = {};
|
|
1788
|
-
symbolLinks.set(id, links);
|
|
1789
|
-
return links;
|
|
1790
|
-
}
|
|
1791
|
-
function getSymbolId(s) {
|
|
1792
|
-
if (s.id === undefined) {
|
|
1793
|
-
mutate(s).id = currentSymbolId++;
|
|
1794
|
-
}
|
|
1795
|
-
return s.id;
|
|
1796
|
-
}
|
|
1797
|
-
function resolveIdentifierInTable(node, table, options) {
|
|
1798
|
-
if (!table) {
|
|
1799
|
-
return undefined;
|
|
1800
|
-
}
|
|
1801
|
-
table = augmentedSymbolTables.get(table) ?? table;
|
|
1802
|
-
let sym;
|
|
1803
|
-
if (options.resolveDecorators) {
|
|
1804
|
-
sym = table.get("@" + node.sv);
|
|
1805
|
-
}
|
|
1806
|
-
else {
|
|
1807
|
-
sym = table.get(node.sv);
|
|
1808
|
-
}
|
|
1809
|
-
if (!sym)
|
|
1810
|
-
return sym;
|
|
1811
|
-
if (sym.flags & 1048576 /* SymbolFlags.DuplicateUsing */) {
|
|
1812
|
-
reportAmbiguousIdentifier(node, [...(table.duplicates.get(sym) ?? [])]);
|
|
1813
|
-
return sym;
|
|
1814
|
-
}
|
|
1815
|
-
return getMergedSymbol(sym);
|
|
1816
|
-
}
|
|
1817
|
-
function reportAmbiguousIdentifier(node, symbols) {
|
|
1818
|
-
const duplicateNames = symbols.map((s) => getFullyQualifiedSymbolName(s, { useGlobalPrefixAtTopLevel: true }));
|
|
1819
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
1820
|
-
code: "ambiguous-symbol",
|
|
1821
|
-
format: { name: node.sv, duplicateNames: duplicateNames.join(", ") },
|
|
1822
|
-
target: node,
|
|
1823
|
-
}));
|
|
1691
|
+
return resolver.getSymbolLinks(s);
|
|
1824
1692
|
}
|
|
1825
1693
|
function resolveIdentifier(id, mapper) {
|
|
1826
1694
|
let sym;
|
|
@@ -1838,29 +1706,8 @@ export function createChecker(program) {
|
|
|
1838
1706
|
break;
|
|
1839
1707
|
case IdentifierKind.ModelStatementProperty:
|
|
1840
1708
|
case IdentifierKind.Declaration:
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
break;
|
|
1844
|
-
}
|
|
1845
|
-
compilerAssert(node.parent, "Parent expected.");
|
|
1846
|
-
const containerType = getTypeOrValueForNode(node.parent, mapper);
|
|
1847
|
-
if (containerType === null || isValue(containerType)) {
|
|
1848
|
-
return undefined;
|
|
1849
|
-
}
|
|
1850
|
-
if (isAnonymous(containerType)) {
|
|
1851
|
-
return undefined; // member of anonymous type cannot be referenced.
|
|
1852
|
-
}
|
|
1853
|
-
lateBindMemberContainer(containerType);
|
|
1854
|
-
let container = node.parent.symbol;
|
|
1855
|
-
if (!container && "symbol" in containerType && containerType.symbol) {
|
|
1856
|
-
container = containerType.symbol;
|
|
1857
|
-
}
|
|
1858
|
-
if (!container) {
|
|
1859
|
-
return undefined;
|
|
1860
|
-
}
|
|
1861
|
-
lateBindMembers(containerType, container);
|
|
1862
|
-
sym = resolveIdentifierInTable(id, container.exports ?? container.members, defaultSymbolResolutionOptions);
|
|
1863
|
-
break;
|
|
1709
|
+
const links = resolver.getNodeLinks(id);
|
|
1710
|
+
return links.resolvedSymbol;
|
|
1864
1711
|
case IdentifierKind.Other:
|
|
1865
1712
|
return undefined;
|
|
1866
1713
|
case IdentifierKind.Decorator:
|
|
@@ -2147,19 +1994,12 @@ export function createChecker(program) {
|
|
|
2147
1994
|
}
|
|
2148
1995
|
}
|
|
2149
1996
|
else if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
|
|
2150
|
-
let base =
|
|
1997
|
+
let base = resolver.getNodeLinks(identifier.parent.base).resolvedSymbol;
|
|
2151
1998
|
if (base) {
|
|
2152
|
-
if (base.flags &
|
|
2153
|
-
base = getAliasedSymbol(base, undefined
|
|
1999
|
+
if (base.flags & 128 /* SymbolFlags.Alias */) {
|
|
2000
|
+
base = getAliasedSymbol(base, undefined);
|
|
2154
2001
|
}
|
|
2155
2002
|
if (base) {
|
|
2156
|
-
if (isTemplatedNode(base.declarations[0])) {
|
|
2157
|
-
const type = base.type ?? getTypeForNode(base.declarations[0], undefined);
|
|
2158
|
-
if (isTemplateInstance(type)) {
|
|
2159
|
-
lateBindMemberContainer(type);
|
|
2160
|
-
lateBindMembers(type, base);
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
2003
|
addCompletions(base.exports ?? base.members);
|
|
2164
2004
|
}
|
|
2165
2005
|
}
|
|
@@ -2196,7 +2036,7 @@ export function createChecker(program) {
|
|
|
2196
2036
|
addCompletions(mergedSymbol.exports);
|
|
2197
2037
|
}
|
|
2198
2038
|
// check "global scope" declarations
|
|
2199
|
-
addCompletions(
|
|
2039
|
+
addCompletions(resolver.symbols.global.exports);
|
|
2200
2040
|
// check "global scope" usings
|
|
2201
2041
|
addCompletions(scope.locals);
|
|
2202
2042
|
}
|
|
@@ -2206,12 +2046,12 @@ export function createChecker(program) {
|
|
|
2206
2046
|
if (!table) {
|
|
2207
2047
|
return;
|
|
2208
2048
|
}
|
|
2209
|
-
table =
|
|
2049
|
+
table = resolver.getAugmentedSymbolTable(table);
|
|
2210
2050
|
for (const [key, sym] of table) {
|
|
2211
|
-
if (sym.flags &
|
|
2051
|
+
if (sym.flags & 65536 /* SymbolFlags.DuplicateUsing */) {
|
|
2212
2052
|
const duplicates = table.duplicates.get(sym);
|
|
2213
2053
|
for (const duplicate of duplicates) {
|
|
2214
|
-
if (duplicate.flags &
|
|
2054
|
+
if (duplicate.flags & 32768 /* SymbolFlags.Using */) {
|
|
2215
2055
|
const fqn = getFullyQualifiedSymbolName(duplicate.symbolSource);
|
|
2216
2056
|
addCompletion(fqn, duplicate);
|
|
2217
2057
|
}
|
|
@@ -2241,79 +2081,23 @@ export function createChecker(program) {
|
|
|
2241
2081
|
case IdentifierKind.ModelExpressionProperty:
|
|
2242
2082
|
case IdentifierKind.ModelStatementProperty:
|
|
2243
2083
|
case IdentifierKind.ObjectLiteralProperty:
|
|
2244
|
-
return !!(sym.flags &
|
|
2084
|
+
return !!(sym.flags & 262144 /* SymbolFlags.Member */);
|
|
2245
2085
|
case IdentifierKind.Decorator:
|
|
2246
2086
|
// Only return decorators and namespaces when completing decorator
|
|
2247
|
-
return !!(sym.flags & (
|
|
2087
|
+
return !!(sym.flags & (1024 /* SymbolFlags.Decorator */ | 256 /* SymbolFlags.Namespace */));
|
|
2248
2088
|
case IdentifierKind.Using:
|
|
2249
2089
|
// Only return namespaces when completing using
|
|
2250
|
-
return !!(sym.flags &
|
|
2090
|
+
return !!(sym.flags & 256 /* SymbolFlags.Namespace */);
|
|
2251
2091
|
case IdentifierKind.TypeReference:
|
|
2252
2092
|
// Do not return functions or decorators when completing types
|
|
2253
|
-
return !(sym.flags & (
|
|
2093
|
+
return !(sym.flags & (8192 /* SymbolFlags.Function */ | 1024 /* SymbolFlags.Decorator */));
|
|
2254
2094
|
case IdentifierKind.TemplateArgument:
|
|
2255
|
-
return !!(sym.flags &
|
|
2095
|
+
return !!(sym.flags & 2048 /* SymbolFlags.TemplateParameter */);
|
|
2256
2096
|
default:
|
|
2257
2097
|
compilerAssert(false, "We should have bailed up-front on other kinds.");
|
|
2258
2098
|
}
|
|
2259
2099
|
}
|
|
2260
2100
|
}
|
|
2261
|
-
function resolveIdentifierInScope(node, mapper, options) {
|
|
2262
|
-
compilerAssert(node.parent?.kind !== SyntaxKind.MemberExpression || node.parent.id !== node, "This function should not be used to resolve Y in member expression X.Y. Use resolveIdentifier() to resolve an arbitrary identifier.");
|
|
2263
|
-
if (hasParseError(node)) {
|
|
2264
|
-
// Don't report synthetic identifiers used for parser error recovery.
|
|
2265
|
-
// The parse error is the root cause and will already have been logged.
|
|
2266
|
-
return undefined;
|
|
2267
|
-
}
|
|
2268
|
-
let scope = node.parent;
|
|
2269
|
-
let binding;
|
|
2270
|
-
while (scope && scope.kind !== SyntaxKind.TypeSpecScript) {
|
|
2271
|
-
if (scope.symbol && "exports" in scope.symbol) {
|
|
2272
|
-
const mergedSymbol = getMergedSymbol(scope.symbol);
|
|
2273
|
-
binding = resolveIdentifierInTable(node, mergedSymbol.exports, options);
|
|
2274
|
-
if (binding)
|
|
2275
|
-
return binding;
|
|
2276
|
-
}
|
|
2277
|
-
if ("locals" in scope) {
|
|
2278
|
-
binding = resolveIdentifierInTable(node, scope.locals, options);
|
|
2279
|
-
if (binding)
|
|
2280
|
-
return binding;
|
|
2281
|
-
}
|
|
2282
|
-
scope = scope.parent;
|
|
2283
|
-
}
|
|
2284
|
-
if (!binding && scope && scope.kind === SyntaxKind.TypeSpecScript) {
|
|
2285
|
-
// check any blockless namespace decls
|
|
2286
|
-
for (const ns of scope.inScopeNamespaces) {
|
|
2287
|
-
const mergedSymbol = getMergedSymbol(ns.symbol);
|
|
2288
|
-
binding = resolveIdentifierInTable(node, mergedSymbol.exports, options);
|
|
2289
|
-
if (binding)
|
|
2290
|
-
return binding;
|
|
2291
|
-
}
|
|
2292
|
-
// check "global scope" declarations
|
|
2293
|
-
const globalBinding = resolveIdentifierInTable(node, globalNamespaceNode.symbol.exports, options);
|
|
2294
|
-
// check using types
|
|
2295
|
-
const usingBinding = resolveIdentifierInTable(node, scope.locals, options);
|
|
2296
|
-
if (globalBinding && usingBinding) {
|
|
2297
|
-
reportAmbiguousIdentifier(node, [globalBinding, usingBinding]);
|
|
2298
|
-
return globalBinding;
|
|
2299
|
-
}
|
|
2300
|
-
else if (globalBinding) {
|
|
2301
|
-
return globalBinding;
|
|
2302
|
-
}
|
|
2303
|
-
else if (usingBinding) {
|
|
2304
|
-
return usingBinding.flags & 1048576 /* SymbolFlags.DuplicateUsing */ ? undefined : usingBinding;
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
if (mapper === undefined) {
|
|
2308
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
2309
|
-
code: "unknown-identifier",
|
|
2310
|
-
format: { id: node.sv },
|
|
2311
|
-
target: node,
|
|
2312
|
-
codefixes: getCodefixesForUnknownIdentifier(node),
|
|
2313
|
-
}));
|
|
2314
|
-
}
|
|
2315
|
-
return undefined;
|
|
2316
|
-
}
|
|
2317
2101
|
function getCodefixesForUnknownIdentifier(node) {
|
|
2318
2102
|
switch (node.sv) {
|
|
2319
2103
|
case "number":
|
|
@@ -2344,14 +2128,37 @@ export function createChecker(program) {
|
|
|
2344
2128
|
if (node.kind === SyntaxKind.TypeReference) {
|
|
2345
2129
|
return resolveTypeReferenceSym(node.target, mapper, options);
|
|
2346
2130
|
}
|
|
2347
|
-
if (node.kind === SyntaxKind.
|
|
2348
|
-
|
|
2131
|
+
else if (node.kind === SyntaxKind.Identifier) {
|
|
2132
|
+
const links = resolver.getNodeLinks(node);
|
|
2133
|
+
if (mapper === undefined && links.resolutionResult) {
|
|
2134
|
+
if (mapper === undefined && // do not report error when instantiating
|
|
2135
|
+
links.resolutionResult & (ResolutionResultFlags.NotFound | ResolutionResultFlags.Unknown)) {
|
|
2136
|
+
reportCheckerDiagnostic(createDiagnostic({
|
|
2137
|
+
code: "invalid-ref",
|
|
2138
|
+
messageId: options.resolveDecorators ? "decorator" : "identifier",
|
|
2139
|
+
format: { id: printTypeReferenceNode(node) },
|
|
2140
|
+
target: node,
|
|
2141
|
+
codefixes: getCodefixesForUnknownIdentifier(node),
|
|
2142
|
+
}));
|
|
2143
|
+
}
|
|
2144
|
+
else if (links.resolutionResult & ResolutionResultFlags.Ambiguous) {
|
|
2145
|
+
reportAmbiguousIdentifier(node, links.ambiguousSymbols);
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
const sym = links.resolvedSymbol;
|
|
2149
|
+
return sym?.symbolSource ?? sym;
|
|
2150
|
+
}
|
|
2151
|
+
else if (node.kind === SyntaxKind.MemberExpression) {
|
|
2152
|
+
let base = resolveTypeReferenceSym(node.base, mapper, {
|
|
2153
|
+
...options,
|
|
2154
|
+
resolveDecorators: false, // when resolving decorator the base cannot also be one
|
|
2155
|
+
});
|
|
2349
2156
|
if (!base) {
|
|
2350
2157
|
return undefined;
|
|
2351
2158
|
}
|
|
2352
2159
|
// when resolving a type reference based on an alias, unwrap the alias.
|
|
2353
|
-
if (base.flags &
|
|
2354
|
-
const aliasedSym = getAliasedSymbol(base, mapper
|
|
2160
|
+
if (base.flags & 128 /* SymbolFlags.Alias */) {
|
|
2161
|
+
const aliasedSym = getAliasedSymbol(base, mapper);
|
|
2355
2162
|
if (!aliasedSym) {
|
|
2356
2163
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2357
2164
|
code: "invalid-ref",
|
|
@@ -2368,104 +2175,72 @@ export function createChecker(program) {
|
|
|
2368
2175
|
}
|
|
2369
2176
|
base = aliasedSym;
|
|
2370
2177
|
}
|
|
2371
|
-
|
|
2372
|
-
return resolveMemberInContainer(node, base, mapper, options);
|
|
2373
|
-
}
|
|
2374
|
-
else {
|
|
2375
|
-
return resolveMetaProperty(node, base);
|
|
2376
|
-
}
|
|
2377
|
-
}
|
|
2378
|
-
if (node.kind === SyntaxKind.Identifier) {
|
|
2379
|
-
const sym = resolveIdentifierInScope(node, mapper, options);
|
|
2380
|
-
if (!sym)
|
|
2381
|
-
return undefined;
|
|
2382
|
-
return sym.flags & 524288 /* SymbolFlags.Using */ ? sym.symbolSource : sym;
|
|
2178
|
+
return resolveMemberInContainer(base, node, options);
|
|
2383
2179
|
}
|
|
2384
2180
|
compilerAssert(false, `Unknown type reference kind "${SyntaxKind[node.kind]}"`, node);
|
|
2385
2181
|
}
|
|
2386
|
-
function
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
}));
|
|
2399
|
-
return undefined;
|
|
2400
|
-
}
|
|
2182
|
+
function reportAmbiguousIdentifier(node, symbols) {
|
|
2183
|
+
const duplicateNames = symbols.map((s) => getFullyQualifiedSymbolName(s, { useGlobalPrefixAtTopLevel: true }));
|
|
2184
|
+
program.reportDiagnostic(createDiagnostic({
|
|
2185
|
+
code: "ambiguous-symbol",
|
|
2186
|
+
format: { name: node.sv, duplicateNames: duplicateNames.join(", ") },
|
|
2187
|
+
target: node,
|
|
2188
|
+
}));
|
|
2189
|
+
}
|
|
2190
|
+
function resolveMemberInContainer(base, node, options) {
|
|
2191
|
+
const { finalSymbol: sym, resolvedSymbol: nextSym } = resolver.resolveMemberExpressionForSym(base, node, options);
|
|
2192
|
+
const symbol = nextSym ?? sym;
|
|
2193
|
+
if (symbol) {
|
|
2401
2194
|
return symbol;
|
|
2402
2195
|
}
|
|
2403
|
-
|
|
2196
|
+
if (base.flags & 256 /* SymbolFlags.Namespace */) {
|
|
2197
|
+
reportCheckerDiagnostic(createDiagnostic({
|
|
2198
|
+
code: "invalid-ref",
|
|
2199
|
+
messageId: "underNamespace",
|
|
2200
|
+
format: {
|
|
2201
|
+
namespace: getFullyQualifiedSymbolName(base),
|
|
2202
|
+
id: node.id.sv,
|
|
2203
|
+
},
|
|
2204
|
+
target: node,
|
|
2205
|
+
}));
|
|
2206
|
+
}
|
|
2207
|
+
else if (base.flags & 1024 /* SymbolFlags.Decorator */) {
|
|
2404
2208
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2405
2209
|
code: "invalid-ref",
|
|
2406
2210
|
messageId: "inDecorator",
|
|
2407
2211
|
format: { id: node.id.sv },
|
|
2408
2212
|
target: node,
|
|
2409
2213
|
}));
|
|
2410
|
-
return undefined;
|
|
2411
2214
|
}
|
|
2412
|
-
else if (base.flags &
|
|
2215
|
+
else if (base.flags & 8192 /* SymbolFlags.Function */) {
|
|
2413
2216
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2414
2217
|
code: "invalid-ref",
|
|
2415
2218
|
messageId: "node",
|
|
2416
2219
|
format: { id: node.id.sv, nodeName: "function" },
|
|
2417
2220
|
target: node,
|
|
2418
2221
|
}));
|
|
2419
|
-
return undefined;
|
|
2420
2222
|
}
|
|
2421
|
-
else if (base.flags &
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
}
|
|
2429
|
-
}
|
|
2430
|
-
const sym = resolveIdentifierInTable(node.id, base.members, options);
|
|
2431
|
-
if (!sym) {
|
|
2432
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
2433
|
-
code: "invalid-ref",
|
|
2434
|
-
messageId: "underContainer",
|
|
2435
|
-
format: { kind: getMemberKindName(base.declarations[0]), id: node.id.sv },
|
|
2436
|
-
target: node,
|
|
2437
|
-
}));
|
|
2438
|
-
return undefined;
|
|
2439
|
-
}
|
|
2440
|
-
return sym;
|
|
2223
|
+
else if (base.flags & 118 /* SymbolFlags.MemberContainer */) {
|
|
2224
|
+
reportCheckerDiagnostic(createDiagnostic({
|
|
2225
|
+
code: "invalid-ref",
|
|
2226
|
+
messageId: node.selector === "." ? "member" : "metaProperty",
|
|
2227
|
+
format: { kind: getMemberKindName(getSymNode(base)), id: node.id.sv },
|
|
2228
|
+
target: node,
|
|
2229
|
+
}));
|
|
2441
2230
|
}
|
|
2442
2231
|
else {
|
|
2232
|
+
const symNode = getSymNode(base);
|
|
2443
2233
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2444
2234
|
code: "invalid-ref",
|
|
2445
2235
|
messageId: "node",
|
|
2446
2236
|
format: {
|
|
2447
2237
|
id: node.id.sv,
|
|
2448
|
-
nodeName:
|
|
2238
|
+
nodeName: symNode ? SyntaxKind[symNode.kind] : "Unknown node",
|
|
2449
2239
|
},
|
|
2450
2240
|
target: node,
|
|
2451
2241
|
}));
|
|
2452
|
-
return undefined;
|
|
2453
|
-
}
|
|
2454
|
-
}
|
|
2455
|
-
function resolveMetaProperty(node, base) {
|
|
2456
|
-
const resolved = resolveIdentifierInTable(node.id, base.metatypeMembers, {
|
|
2457
|
-
resolveDecorators: false,
|
|
2458
|
-
checkTemplateTypes: false,
|
|
2459
|
-
});
|
|
2460
|
-
if (!resolved) {
|
|
2461
|
-
reportCheckerDiagnostic(createDiagnostic({
|
|
2462
|
-
code: "invalid-ref",
|
|
2463
|
-
messageId: "metaProperty",
|
|
2464
|
-
format: { kind: getMemberKindName(base.declarations[0]), id: node.id.sv },
|
|
2465
|
-
target: node,
|
|
2466
|
-
}));
|
|
2467
2242
|
}
|
|
2468
|
-
return
|
|
2243
|
+
return undefined;
|
|
2469
2244
|
}
|
|
2470
2245
|
function getMemberKindName(node) {
|
|
2471
2246
|
switch (node.kind) {
|
|
@@ -2490,30 +2265,13 @@ export function createChecker(program) {
|
|
|
2490
2265
|
* (i.e. they contain symbols we don't know until we've instantiated the type and the type is an
|
|
2491
2266
|
* instantiation) we late bind the container which creates the symbol that will hold its members.
|
|
2492
2267
|
*/
|
|
2493
|
-
function getAliasedSymbol(aliasSymbol, mapper
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
if (targetNode.kind === SyntaxKind.TypeReference ||
|
|
2499
|
-
targetNode.kind === SyntaxKind.MemberExpression ||
|
|
2500
|
-
targetNode.kind === SyntaxKind.Identifier) {
|
|
2501
|
-
const sym = resolveTypeReferenceSymInternal(targetNode, mapper, options);
|
|
2502
|
-
if (sym === undefined) {
|
|
2503
|
-
return undefined;
|
|
2504
|
-
}
|
|
2505
|
-
current = sym;
|
|
2506
|
-
}
|
|
2507
|
-
else {
|
|
2508
|
-
return undefined;
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
2511
|
-
const sym = current;
|
|
2512
|
-
const node = aliasSymbol.declarations[0];
|
|
2513
|
-
const resolvedTargetNode = sym.declarations[0];
|
|
2514
|
-
if (!options.checkTemplateTypes || !isTemplatedNode(resolvedTargetNode)) {
|
|
2515
|
-
return sym;
|
|
2268
|
+
function getAliasedSymbol(aliasSymbol, mapper) {
|
|
2269
|
+
const node = getSymNode(aliasSymbol);
|
|
2270
|
+
const links = resolver.getSymbolLinks(aliasSymbol);
|
|
2271
|
+
if (!links.aliasResolutionIsTemplate) {
|
|
2272
|
+
return links.aliasedSymbol ?? resolver.getNodeLinks(node).resolvedSymbol;
|
|
2516
2273
|
}
|
|
2274
|
+
// Otherwise for templates we need to get the type and retrieve the late bound symbol.
|
|
2517
2275
|
const aliasType = getTypeForNode(node, mapper);
|
|
2518
2276
|
if (isErrorType(aliasType)) {
|
|
2519
2277
|
return undefined;
|
|
@@ -2677,27 +2435,58 @@ export function createChecker(program) {
|
|
|
2677
2435
|
};
|
|
2678
2436
|
}
|
|
2679
2437
|
function checkProgram() {
|
|
2680
|
-
|
|
2438
|
+
checkDuplicateSymbols();
|
|
2681
2439
|
for (const file of program.sourceFiles.values()) {
|
|
2682
|
-
|
|
2440
|
+
checkDuplicateUsings(file);
|
|
2441
|
+
for (const ns of file.namespaces) {
|
|
2442
|
+
initializeTypeForNamespace(ns);
|
|
2443
|
+
}
|
|
2683
2444
|
}
|
|
2684
2445
|
for (const file of program.sourceFiles.values()) {
|
|
2685
|
-
|
|
2446
|
+
checkSourceFile(file);
|
|
2686
2447
|
}
|
|
2448
|
+
internalDecoratorValidation();
|
|
2449
|
+
}
|
|
2450
|
+
function checkDuplicateSymbols() {
|
|
2451
|
+
program.reportDuplicateSymbols(resolver.symbols.global.exports);
|
|
2687
2452
|
for (const file of program.sourceFiles.values()) {
|
|
2688
2453
|
for (const ns of file.namespaces) {
|
|
2689
|
-
const exports =
|
|
2454
|
+
const exports = getMergedSymbol(ns.symbol).exports ?? ns.symbol.exports;
|
|
2690
2455
|
program.reportDuplicateSymbols(exports);
|
|
2691
|
-
initializeTypeForNamespace(ns);
|
|
2692
2456
|
}
|
|
2693
2457
|
}
|
|
2694
|
-
|
|
2695
|
-
|
|
2458
|
+
}
|
|
2459
|
+
/** Report error with duplicate using in the same scope. */
|
|
2460
|
+
function checkDuplicateUsings(file) {
|
|
2461
|
+
const duplicateTrackers = new Map();
|
|
2462
|
+
function getTracker(sym) {
|
|
2463
|
+
const existing = duplicateTrackers.get(sym);
|
|
2464
|
+
if (existing)
|
|
2465
|
+
return existing;
|
|
2466
|
+
const newTacker = new DuplicateTracker();
|
|
2467
|
+
duplicateTrackers.set(sym, newTacker);
|
|
2468
|
+
return newTacker;
|
|
2696
2469
|
}
|
|
2697
|
-
for (const
|
|
2698
|
-
|
|
2470
|
+
for (const using of file.usings) {
|
|
2471
|
+
const ns = using.parent;
|
|
2472
|
+
const sym = getMergedSymbol(ns.symbol);
|
|
2473
|
+
const tracker = getTracker(sym);
|
|
2474
|
+
const targetSym = resolver.getNodeLinks(using.name).resolvedSymbol;
|
|
2475
|
+
if (!targetSym)
|
|
2476
|
+
continue;
|
|
2477
|
+
tracker.track(targetSym, using);
|
|
2478
|
+
}
|
|
2479
|
+
for (const tracker of duplicateTrackers.values()) {
|
|
2480
|
+
for (const [_, nodes] of tracker.entries()) {
|
|
2481
|
+
for (const node of nodes) {
|
|
2482
|
+
program.reportDiagnostic(createDiagnostic({
|
|
2483
|
+
code: "duplicate-using",
|
|
2484
|
+
format: { usingName: typeReferenceToString(node.name) },
|
|
2485
|
+
target: node,
|
|
2486
|
+
}));
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2699
2489
|
}
|
|
2700
|
-
internalDecoratorValidation();
|
|
2701
2490
|
}
|
|
2702
2491
|
/**
|
|
2703
2492
|
* Post checking validation for internal decorators.
|
|
@@ -2705,22 +2494,6 @@ export function createChecker(program) {
|
|
|
2705
2494
|
function internalDecoratorValidation() {
|
|
2706
2495
|
validateInheritanceDiscriminatedUnions(program);
|
|
2707
2496
|
}
|
|
2708
|
-
function applyAugmentDecoratorsInScope(scope) {
|
|
2709
|
-
applyAugmentDecorators(scope);
|
|
2710
|
-
if (scope.statements === undefined) {
|
|
2711
|
-
return;
|
|
2712
|
-
}
|
|
2713
|
-
if (isArray(scope.statements)) {
|
|
2714
|
-
for (const statement of scope.statements) {
|
|
2715
|
-
if (statement.kind === SyntaxKind.NamespaceStatement) {
|
|
2716
|
-
applyAugmentDecoratorsInScope(statement);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
else {
|
|
2721
|
-
applyAugmentDecoratorsInScope(scope.statements);
|
|
2722
|
-
}
|
|
2723
|
-
}
|
|
2724
2497
|
function checkSourceFile(file) {
|
|
2725
2498
|
for (const statement of file.statements) {
|
|
2726
2499
|
checkNode(statement, undefined);
|
|
@@ -2767,7 +2540,7 @@ export function createChecker(program) {
|
|
|
2767
2540
|
});
|
|
2768
2541
|
linkType(links, type, mapper);
|
|
2769
2542
|
if (node.symbol.members) {
|
|
2770
|
-
const members =
|
|
2543
|
+
const members = resolver.getAugmentedSymbolTable(node.symbol.members);
|
|
2771
2544
|
const propDocs = extractPropDocs(node);
|
|
2772
2545
|
for (const [name, memberSym] of members) {
|
|
2773
2546
|
const doc = propDocs.get(name);
|
|
@@ -2831,6 +2604,8 @@ export function createChecker(program) {
|
|
|
2831
2604
|
if (indexer) {
|
|
2832
2605
|
type.indexer = indexer;
|
|
2833
2606
|
}
|
|
2607
|
+
lateBindMemberContainer(type);
|
|
2608
|
+
lateBindMembers(type);
|
|
2834
2609
|
return type;
|
|
2835
2610
|
}
|
|
2836
2611
|
function shouldCreateTypeForTemplate(node, mapper) {
|
|
@@ -2847,6 +2622,11 @@ export function createChecker(program) {
|
|
|
2847
2622
|
mapper.args.every((t) => isValue(t) || t.entityKind === "Indeterminate" || t.kind !== "TemplateParameter"));
|
|
2848
2623
|
}
|
|
2849
2624
|
function checkModelExpression(node, mapper) {
|
|
2625
|
+
const links = getSymbolLinks(node.symbol);
|
|
2626
|
+
if (links.declaredType && mapper === undefined) {
|
|
2627
|
+
// we're not instantiating this model and we've already checked it
|
|
2628
|
+
return links.declaredType;
|
|
2629
|
+
}
|
|
2850
2630
|
const properties = createRekeyableMap();
|
|
2851
2631
|
const type = createType({
|
|
2852
2632
|
kind: "Model",
|
|
@@ -2859,6 +2639,7 @@ export function createChecker(program) {
|
|
|
2859
2639
|
derivedModels: [],
|
|
2860
2640
|
sourceModels: [],
|
|
2861
2641
|
});
|
|
2642
|
+
linkType(links, type, mapper);
|
|
2862
2643
|
linkMapper(type, mapper);
|
|
2863
2644
|
checkModelProperties(node, properties, type, mapper);
|
|
2864
2645
|
return finishType(type);
|
|
@@ -3418,190 +3199,6 @@ export function createChecker(program) {
|
|
|
3418
3199
|
}
|
|
3419
3200
|
properties.set(newProp.name, newProp);
|
|
3420
3201
|
}
|
|
3421
|
-
function bindAllMembers(node) {
|
|
3422
|
-
const bound = new Set();
|
|
3423
|
-
if (node.symbol) {
|
|
3424
|
-
bindMembers(node, node.symbol);
|
|
3425
|
-
}
|
|
3426
|
-
visitChildren(node, (child) => {
|
|
3427
|
-
bindAllMembers(child);
|
|
3428
|
-
});
|
|
3429
|
-
function bindMembers(node, containerSym) {
|
|
3430
|
-
if (bound.has(containerSym)) {
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
bound.add(containerSym);
|
|
3434
|
-
let containerMembers;
|
|
3435
|
-
switch (node.kind) {
|
|
3436
|
-
case SyntaxKind.ModelStatement:
|
|
3437
|
-
if (node.extends && node.extends.kind === SyntaxKind.TypeReference) {
|
|
3438
|
-
resolveAndCopyMembers(node.extends);
|
|
3439
|
-
}
|
|
3440
|
-
if (node.is && node.is.kind === SyntaxKind.TypeReference) {
|
|
3441
|
-
resolveAndCopyMembers(node.is);
|
|
3442
|
-
}
|
|
3443
|
-
for (const prop of node.properties) {
|
|
3444
|
-
if (prop.kind === SyntaxKind.ModelSpreadProperty) {
|
|
3445
|
-
resolveAndCopyMembers(prop.target);
|
|
3446
|
-
}
|
|
3447
|
-
else {
|
|
3448
|
-
const name = prop.id.sv;
|
|
3449
|
-
bindMember(name, prop, 4 /* SymbolFlags.ModelProperty */);
|
|
3450
|
-
}
|
|
3451
|
-
}
|
|
3452
|
-
break;
|
|
3453
|
-
case SyntaxKind.ScalarStatement:
|
|
3454
|
-
if (node.extends && node.extends.kind === SyntaxKind.TypeReference) {
|
|
3455
|
-
resolveAndCopyMembers(node.extends);
|
|
3456
|
-
}
|
|
3457
|
-
for (const member of node.members) {
|
|
3458
|
-
const name = member.id.sv;
|
|
3459
|
-
bindMember(name, member, 33554432 /* SymbolFlags.ScalarMember */);
|
|
3460
|
-
}
|
|
3461
|
-
break;
|
|
3462
|
-
case SyntaxKind.ModelExpression:
|
|
3463
|
-
for (const prop of node.properties) {
|
|
3464
|
-
if (prop.kind === SyntaxKind.ModelSpreadProperty) {
|
|
3465
|
-
resolveAndCopyMembers(prop.target);
|
|
3466
|
-
}
|
|
3467
|
-
else {
|
|
3468
|
-
const name = prop.id.sv;
|
|
3469
|
-
bindMember(name, prop, 4 /* SymbolFlags.ModelProperty */);
|
|
3470
|
-
}
|
|
3471
|
-
}
|
|
3472
|
-
break;
|
|
3473
|
-
case SyntaxKind.EnumStatement:
|
|
3474
|
-
for (const member of node.members.values()) {
|
|
3475
|
-
if (member.kind === SyntaxKind.EnumSpreadMember) {
|
|
3476
|
-
resolveAndCopyMembers(member.target);
|
|
3477
|
-
}
|
|
3478
|
-
else {
|
|
3479
|
-
const name = member.id.sv;
|
|
3480
|
-
bindMember(name, member, 64 /* SymbolFlags.EnumMember */);
|
|
3481
|
-
}
|
|
3482
|
-
}
|
|
3483
|
-
break;
|
|
3484
|
-
case SyntaxKind.InterfaceStatement:
|
|
3485
|
-
for (const member of node.operations.values()) {
|
|
3486
|
-
bindMember(member.id.sv, member, 256 /* SymbolFlags.InterfaceMember */ | 16 /* SymbolFlags.Operation */);
|
|
3487
|
-
}
|
|
3488
|
-
if (node.extends) {
|
|
3489
|
-
for (const ext of node.extends) {
|
|
3490
|
-
resolveAndCopyMembers(ext);
|
|
3491
|
-
}
|
|
3492
|
-
}
|
|
3493
|
-
break;
|
|
3494
|
-
case SyntaxKind.UnionStatement:
|
|
3495
|
-
for (const variant of node.options.values()) {
|
|
3496
|
-
if (!variant.id) {
|
|
3497
|
-
continue;
|
|
3498
|
-
}
|
|
3499
|
-
const name = variant.id.sv;
|
|
3500
|
-
bindMember(name, variant, 1024 /* SymbolFlags.UnionVariant */);
|
|
3501
|
-
}
|
|
3502
|
-
break;
|
|
3503
|
-
}
|
|
3504
|
-
function resolveAndCopyMembers(node) {
|
|
3505
|
-
let ref = resolveTypeReferenceSym(node, undefined);
|
|
3506
|
-
if (ref && ref.flags & 2048 /* SymbolFlags.Alias */) {
|
|
3507
|
-
ref = resolveAliasedSymbol(ref);
|
|
3508
|
-
}
|
|
3509
|
-
if (ref && ref.members) {
|
|
3510
|
-
bindMembers(ref.declarations[0], ref);
|
|
3511
|
-
copyMembers(ref.members);
|
|
3512
|
-
}
|
|
3513
|
-
}
|
|
3514
|
-
function resolveAliasedSymbol(ref) {
|
|
3515
|
-
const node = ref.declarations[0];
|
|
3516
|
-
switch (node.value.kind) {
|
|
3517
|
-
case SyntaxKind.MemberExpression:
|
|
3518
|
-
case SyntaxKind.TypeReference:
|
|
3519
|
-
const resolvedSym = resolveTypeReferenceSym(node.value, undefined);
|
|
3520
|
-
if (resolvedSym && resolvedSym.flags & 2048 /* SymbolFlags.Alias */) {
|
|
3521
|
-
return resolveAliasedSymbol(resolvedSym);
|
|
3522
|
-
}
|
|
3523
|
-
return resolvedSym;
|
|
3524
|
-
default:
|
|
3525
|
-
return undefined;
|
|
3526
|
-
}
|
|
3527
|
-
}
|
|
3528
|
-
function copyMembers(table) {
|
|
3529
|
-
const members = augmentedSymbolTables.get(table) ?? table;
|
|
3530
|
-
for (const member of members.values()) {
|
|
3531
|
-
bindMember(member.name, member.declarations[0], member.flags);
|
|
3532
|
-
}
|
|
3533
|
-
}
|
|
3534
|
-
function bindMember(name, node, kind) {
|
|
3535
|
-
const sym = createSymbol(node, name, kind, containerSym);
|
|
3536
|
-
compilerAssert(containerSym.members, "containerSym.members is undefined");
|
|
3537
|
-
containerMembers ??= getOrCreateAugmentedSymbolTable(containerSym.members);
|
|
3538
|
-
containerMembers.set(name, sym);
|
|
3539
|
-
}
|
|
3540
|
-
}
|
|
3541
|
-
}
|
|
3542
|
-
function copyMembersToContainer(targetContainerSym, table) {
|
|
3543
|
-
const members = augmentedSymbolTables.get(table) ?? table;
|
|
3544
|
-
compilerAssert(targetContainerSym.members, "containerSym.members is undefined");
|
|
3545
|
-
const containerMembers = getOrCreateAugmentedSymbolTable(targetContainerSym.members);
|
|
3546
|
-
for (const member of members.values()) {
|
|
3547
|
-
bindMemberToContainer(targetContainerSym, containerMembers, member.name, member.declarations[0], member.flags);
|
|
3548
|
-
}
|
|
3549
|
-
}
|
|
3550
|
-
function bindMemberToContainer(containerSym, containerMembers, name, node, kind) {
|
|
3551
|
-
const sym = createSymbol(node, name, kind, containerSym);
|
|
3552
|
-
compilerAssert(containerSym.members, "containerSym.members is undefined");
|
|
3553
|
-
containerMembers.set(name, sym);
|
|
3554
|
-
}
|
|
3555
|
-
function bindMetaTypes(node) {
|
|
3556
|
-
const visited = new Set();
|
|
3557
|
-
function visit(node, symbol) {
|
|
3558
|
-
if (visited.has(node)) {
|
|
3559
|
-
return;
|
|
3560
|
-
}
|
|
3561
|
-
visited.add(node);
|
|
3562
|
-
switch (node.kind) {
|
|
3563
|
-
case SyntaxKind.ModelProperty: {
|
|
3564
|
-
const sym = getSymbolForMember(node);
|
|
3565
|
-
if (sym) {
|
|
3566
|
-
const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
|
|
3567
|
-
table.set("type", node.value.kind === SyntaxKind.TypeReference
|
|
3568
|
-
? createSymbol(node.value, "", 2048 /* SymbolFlags.Alias */)
|
|
3569
|
-
: node.value.symbol);
|
|
3570
|
-
}
|
|
3571
|
-
break;
|
|
3572
|
-
}
|
|
3573
|
-
case SyntaxKind.OperationStatement: {
|
|
3574
|
-
const sym = symbol ?? node.symbol ?? getSymbolForMember(node);
|
|
3575
|
-
const table = getOrCreateAugmentedSymbolTable(sym.metatypeMembers);
|
|
3576
|
-
if (node.signature.kind === SyntaxKind.OperationSignatureDeclaration) {
|
|
3577
|
-
table.set("parameters", node.signature.parameters.symbol);
|
|
3578
|
-
table.set("returnType", node.signature.returnType.symbol);
|
|
3579
|
-
}
|
|
3580
|
-
else {
|
|
3581
|
-
const sig = resolveTypeReferenceSym(node.signature.baseOperation, undefined, {
|
|
3582
|
-
checkTemplateTypes: false,
|
|
3583
|
-
});
|
|
3584
|
-
if (sig) {
|
|
3585
|
-
visit(sig.declarations[0], sig);
|
|
3586
|
-
const sigTable = getOrCreateAugmentedSymbolTable(sig.metatypeMembers);
|
|
3587
|
-
const sigParameterSym = sigTable.get("parameters");
|
|
3588
|
-
if (sigParameterSym !== undefined) {
|
|
3589
|
-
const parametersSym = createSymbol(sigParameterSym.declarations[0], "parameters", 2 /* SymbolFlags.Model */ & 682 /* SymbolFlags.MemberContainer */);
|
|
3590
|
-
copyMembersToContainer(parametersSym, sigParameterSym.members);
|
|
3591
|
-
table.set("parameters", parametersSym);
|
|
3592
|
-
table.set("returnType", sigTable.get("returnType"));
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
}
|
|
3596
|
-
break;
|
|
3597
|
-
}
|
|
3598
|
-
}
|
|
3599
|
-
visitChildren(node, (child) => {
|
|
3600
|
-
bindMetaTypes(child);
|
|
3601
|
-
});
|
|
3602
|
-
}
|
|
3603
|
-
visit(node);
|
|
3604
|
-
}
|
|
3605
3202
|
/**
|
|
3606
3203
|
* Initializes a late bound symbol for the type. This is generally necessary when attempting to
|
|
3607
3204
|
* access a symbol for a type that is created during the check phase.
|
|
@@ -3611,47 +3208,53 @@ export function createChecker(program) {
|
|
|
3611
3208
|
return;
|
|
3612
3209
|
switch (type.kind) {
|
|
3613
3210
|
case "Model":
|
|
3614
|
-
type.symbol = createSymbol(type.node, type.name, 2 /* SymbolFlags.Model */ |
|
|
3211
|
+
type.symbol = createSymbol(type.node, type.name, 2 /* SymbolFlags.Model */ | 4194304 /* SymbolFlags.LateBound */);
|
|
3615
3212
|
mutate(type.symbol).type = type;
|
|
3616
3213
|
break;
|
|
3617
3214
|
case "Interface":
|
|
3618
|
-
type.symbol = createSymbol(type.node, type.name,
|
|
3215
|
+
type.symbol = createSymbol(type.node, type.name, 32 /* SymbolFlags.Interface */ | 4194304 /* SymbolFlags.LateBound */);
|
|
3216
|
+
if (isTemplateInstance(type) && type.name === "Foo") {
|
|
3217
|
+
getSymbolLinks(type.symbol);
|
|
3218
|
+
}
|
|
3619
3219
|
mutate(type.symbol).type = type;
|
|
3620
3220
|
break;
|
|
3621
3221
|
case "Union":
|
|
3622
3222
|
if (!type.name)
|
|
3623
3223
|
return; // don't make a symbol for anonymous unions
|
|
3624
|
-
type.symbol = createSymbol(type.node, type.name,
|
|
3224
|
+
type.symbol = createSymbol(type.node, type.name, 64 /* SymbolFlags.Union */ | 4194304 /* SymbolFlags.LateBound */);
|
|
3625
3225
|
mutate(type.symbol).type = type;
|
|
3626
3226
|
break;
|
|
3627
3227
|
}
|
|
3628
3228
|
}
|
|
3629
|
-
function lateBindMembers(type
|
|
3630
|
-
|
|
3229
|
+
function lateBindMembers(type) {
|
|
3230
|
+
compilerAssert(type.symbol, "Type must have a symbol to late bind members");
|
|
3231
|
+
const containerSym = type.symbol;
|
|
3232
|
+
compilerAssert(containerSym.members, "Container symbol didn't have members at late-bind");
|
|
3233
|
+
const containerMembers = resolver.getAugmentedSymbolTable(containerSym.members);
|
|
3631
3234
|
switch (type.kind) {
|
|
3632
3235
|
case "Model":
|
|
3633
3236
|
for (const prop of walkPropertiesInherited(type)) {
|
|
3634
|
-
lateBindMember(prop,
|
|
3237
|
+
lateBindMember(prop, 262144 /* SymbolFlags.Member */ | 1048576 /* SymbolFlags.Declaration */);
|
|
3635
3238
|
}
|
|
3636
3239
|
break;
|
|
3637
3240
|
case "Scalar":
|
|
3638
3241
|
for (const member of type.constructors.values()) {
|
|
3639
|
-
lateBindMember(member,
|
|
3242
|
+
lateBindMember(member, 262144 /* SymbolFlags.Member */ | 1048576 /* SymbolFlags.Declaration */);
|
|
3640
3243
|
}
|
|
3641
3244
|
break;
|
|
3642
3245
|
case "Enum":
|
|
3643
3246
|
for (const member of type.members.values()) {
|
|
3644
|
-
lateBindMember(member,
|
|
3247
|
+
lateBindMember(member, 262144 /* SymbolFlags.Member */ | 1048576 /* SymbolFlags.Declaration */);
|
|
3645
3248
|
}
|
|
3646
3249
|
break;
|
|
3647
3250
|
case "Interface":
|
|
3648
3251
|
for (const member of type.operations.values()) {
|
|
3649
|
-
lateBindMember(member,
|
|
3252
|
+
lateBindMember(member, 262144 /* SymbolFlags.Member */ | 8 /* SymbolFlags.Operation */ | 1048576 /* SymbolFlags.Declaration */);
|
|
3650
3253
|
}
|
|
3651
3254
|
break;
|
|
3652
3255
|
case "Union":
|
|
3653
3256
|
for (const variant of type.variants.values()) {
|
|
3654
|
-
lateBindMember(variant,
|
|
3257
|
+
lateBindMember(variant, 262144 /* SymbolFlags.Member */ | 1048576 /* SymbolFlags.Declaration */);
|
|
3655
3258
|
}
|
|
3656
3259
|
break;
|
|
3657
3260
|
}
|
|
@@ -3660,10 +3263,9 @@ export function createChecker(program) {
|
|
|
3660
3263
|
// don't bind anything for union expressions
|
|
3661
3264
|
return;
|
|
3662
3265
|
}
|
|
3663
|
-
const sym = createSymbol(member.node, member.name, kind |
|
|
3266
|
+
const sym = createSymbol(member.node, member.name, kind | 4194304 /* SymbolFlags.LateBound */, containerSym);
|
|
3664
3267
|
mutate(sym).type = member;
|
|
3665
3268
|
compilerAssert(containerSym.members, "containerSym.members is undefined");
|
|
3666
|
-
containerMembers ??= getOrCreateAugmentedSymbolTable(containerSym.members);
|
|
3667
3269
|
containerMembers.set(member.name, sym);
|
|
3668
3270
|
}
|
|
3669
3271
|
}
|
|
@@ -3683,23 +3285,20 @@ export function createChecker(program) {
|
|
|
3683
3285
|
}));
|
|
3684
3286
|
return undefined;
|
|
3685
3287
|
}
|
|
3686
|
-
const modelSymId =
|
|
3288
|
+
const modelSymId = getNodeSym(model);
|
|
3687
3289
|
pendingResolutions.start(modelSymId, ResolutionKind.BaseType);
|
|
3688
|
-
const target =
|
|
3689
|
-
if (target
|
|
3690
|
-
return undefined;
|
|
3691
|
-
}
|
|
3692
|
-
if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
|
|
3290
|
+
const target = resolver.getNodeLinks(heritageRef).resolvedSymbol;
|
|
3291
|
+
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
3693
3292
|
if (mapper === undefined) {
|
|
3694
3293
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3695
3294
|
code: "circular-base-type",
|
|
3696
|
-
format: { typeName: target.
|
|
3295
|
+
format: { typeName: target.name },
|
|
3697
3296
|
target: target,
|
|
3698
3297
|
}));
|
|
3699
3298
|
}
|
|
3700
3299
|
return undefined;
|
|
3701
3300
|
}
|
|
3702
|
-
const heritageType =
|
|
3301
|
+
const heritageType = getTypeForNode(heritageRef, mapper);
|
|
3703
3302
|
pendingResolutions.finish(modelSymId, ResolutionKind.BaseType);
|
|
3704
3303
|
if (isErrorType(heritageType)) {
|
|
3705
3304
|
compilerAssert(program.hasError(), "Should already have reported an error.", heritageRef);
|
|
@@ -3721,7 +3320,7 @@ export function createChecker(program) {
|
|
|
3721
3320
|
function checkModelIs(model, isExpr, mapper) {
|
|
3722
3321
|
if (!isExpr)
|
|
3723
3322
|
return undefined;
|
|
3724
|
-
const modelSymId =
|
|
3323
|
+
const modelSymId = getNodeSym(model);
|
|
3725
3324
|
pendingResolutions.start(modelSymId, ResolutionKind.BaseType);
|
|
3726
3325
|
let isType;
|
|
3727
3326
|
if (isExpr.kind === SyntaxKind.ModelExpression) {
|
|
@@ -3736,21 +3335,18 @@ export function createChecker(program) {
|
|
|
3736
3335
|
isType = checkArrayExpression(isExpr, mapper);
|
|
3737
3336
|
}
|
|
3738
3337
|
else if (isExpr.kind === SyntaxKind.TypeReference) {
|
|
3739
|
-
const target =
|
|
3740
|
-
if (target
|
|
3741
|
-
return undefined;
|
|
3742
|
-
}
|
|
3743
|
-
if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
|
|
3338
|
+
const target = resolver.getNodeLinks(isExpr).resolvedSymbol;
|
|
3339
|
+
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
3744
3340
|
if (mapper === undefined) {
|
|
3745
3341
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3746
3342
|
code: "circular-base-type",
|
|
3747
|
-
format: { typeName: target.
|
|
3343
|
+
format: { typeName: target.name },
|
|
3748
3344
|
target: target,
|
|
3749
3345
|
}));
|
|
3750
3346
|
}
|
|
3751
3347
|
return undefined;
|
|
3752
3348
|
}
|
|
3753
|
-
isType =
|
|
3349
|
+
isType = getTypeForNode(isExpr, mapper);
|
|
3754
3350
|
}
|
|
3755
3351
|
else {
|
|
3756
3352
|
reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
|
|
@@ -3773,11 +3369,11 @@ export function createChecker(program) {
|
|
|
3773
3369
|
return [[], undefined];
|
|
3774
3370
|
}
|
|
3775
3371
|
if (targetType.kind !== "Model") {
|
|
3776
|
-
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }));
|
|
3372
|
+
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), mapper);
|
|
3777
3373
|
return [[], undefined];
|
|
3778
3374
|
}
|
|
3779
3375
|
if (isArrayModelType(program, targetType)) {
|
|
3780
|
-
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }));
|
|
3376
|
+
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), mapper);
|
|
3781
3377
|
return [[], undefined];
|
|
3782
3378
|
}
|
|
3783
3379
|
if (parentModel === targetType) {
|
|
@@ -3813,16 +3409,14 @@ export function createChecker(program) {
|
|
|
3813
3409
|
if (containerNode.symbol === undefined) {
|
|
3814
3410
|
return;
|
|
3815
3411
|
}
|
|
3816
|
-
|
|
3817
|
-
const memberSym = getOrCreateAugmentedSymbolTable(containerNode.symbol.members).get(member.name);
|
|
3412
|
+
const memberSym = getMemberSymbol(containerNode.symbol, member.name);
|
|
3818
3413
|
if (memberSym) {
|
|
3819
|
-
const links = getSymbolLinks(memberSym);
|
|
3414
|
+
const links = resolver.getSymbolLinks(memberSym);
|
|
3820
3415
|
linkMemberType(links, member, mapper);
|
|
3821
3416
|
}
|
|
3822
3417
|
}
|
|
3823
3418
|
function checkModelProperty(prop, mapper) {
|
|
3824
3419
|
const sym = getSymbolForMember(prop);
|
|
3825
|
-
const symId = getSymbolId(sym);
|
|
3826
3420
|
const links = getSymbolLinksForMember(prop);
|
|
3827
3421
|
if (links && links.declaredType && mapper === undefined) {
|
|
3828
3422
|
return links.declaredType;
|
|
@@ -3836,7 +3430,7 @@ export function createChecker(program) {
|
|
|
3836
3430
|
type: undefined,
|
|
3837
3431
|
decorators: [],
|
|
3838
3432
|
});
|
|
3839
|
-
if (pendingResolutions.has(
|
|
3433
|
+
if (pendingResolutions.has(sym, ResolutionKind.Type) && mapper === undefined) {
|
|
3840
3434
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3841
3435
|
code: "circular-prop",
|
|
3842
3436
|
format: { propName: name },
|
|
@@ -3845,7 +3439,7 @@ export function createChecker(program) {
|
|
|
3845
3439
|
type.type = errorType;
|
|
3846
3440
|
}
|
|
3847
3441
|
else {
|
|
3848
|
-
pendingResolutions.start(
|
|
3442
|
+
pendingResolutions.start(sym, ResolutionKind.Type);
|
|
3849
3443
|
type.type = getTypeForNode(prop.value, mapper);
|
|
3850
3444
|
if (prop.default) {
|
|
3851
3445
|
const defaultValue = checkDefaultValue(prop.default, type.type);
|
|
@@ -3869,12 +3463,12 @@ export function createChecker(program) {
|
|
|
3869
3463
|
}
|
|
3870
3464
|
finishType(type);
|
|
3871
3465
|
}
|
|
3872
|
-
pendingResolutions.finish(
|
|
3466
|
+
pendingResolutions.finish(sym, ResolutionKind.Type);
|
|
3873
3467
|
return type;
|
|
3874
3468
|
}
|
|
3875
3469
|
function createDocFromCommentDecorator(key, doc) {
|
|
3876
3470
|
return {
|
|
3877
|
-
decorator:
|
|
3471
|
+
decorator: docFromCommentDecorator,
|
|
3878
3472
|
args: [
|
|
3879
3473
|
{ value: createLiteralType(key), jsValue: key },
|
|
3880
3474
|
{ value: createLiteralType(doc), jsValue: doc },
|
|
@@ -3919,13 +3513,10 @@ export function createChecker(program) {
|
|
|
3919
3513
|
function checkDecoratorApplication(targetType, decNode, mapper) {
|
|
3920
3514
|
const sym = resolveTypeReferenceSym(decNode.target, undefined, true);
|
|
3921
3515
|
if (!sym) {
|
|
3922
|
-
|
|
3923
|
-
code: "unknown-decorator",
|
|
3924
|
-
target: decNode,
|
|
3925
|
-
}));
|
|
3516
|
+
// Error should already have been reported above
|
|
3926
3517
|
return undefined;
|
|
3927
3518
|
}
|
|
3928
|
-
if (!(sym.flags &
|
|
3519
|
+
if (!(sym.flags & 1024 /* SymbolFlags.Decorator */)) {
|
|
3929
3520
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3930
3521
|
code: "invalid-decorator",
|
|
3931
3522
|
format: { id: sym.name },
|
|
@@ -3942,7 +3533,7 @@ export function createChecker(program) {
|
|
|
3942
3533
|
}
|
|
3943
3534
|
}
|
|
3944
3535
|
if (symbolLinks.declaredType) {
|
|
3945
|
-
compilerAssert(symbolLinks.declaredType.kind === "Decorator",
|
|
3536
|
+
compilerAssert(symbolLinks.declaredType.kind === "Decorator", `Expected to find a decorator type but got ${symbolLinks.declaredType.kind}`);
|
|
3946
3537
|
if (!checkDecoratorTarget(targetType, symbolLinks.declaredType, decNode)) {
|
|
3947
3538
|
hasError = true;
|
|
3948
3539
|
}
|
|
@@ -4151,7 +3742,7 @@ export function createChecker(program) {
|
|
|
4151
3742
|
return valid;
|
|
4152
3743
|
}
|
|
4153
3744
|
function checkAugmentDecorators(sym, targetType, mapper) {
|
|
4154
|
-
const augmentDecoratorNodes =
|
|
3745
|
+
const augmentDecoratorNodes = resolver.getAugmentDecoratorsForSym(sym);
|
|
4155
3746
|
const decorators = [];
|
|
4156
3747
|
for (const decNode of augmentDecoratorNodes) {
|
|
4157
3748
|
const decorator = checkDecoratorApplication(targetType, decNode, mapper);
|
|
@@ -4161,10 +3752,42 @@ export function createChecker(program) {
|
|
|
4161
3752
|
}
|
|
4162
3753
|
return decorators;
|
|
4163
3754
|
}
|
|
3755
|
+
/**
|
|
3756
|
+
* Check that augment decorator are targeting valid symbols.
|
|
3757
|
+
*/
|
|
3758
|
+
function checkAugmentDecorator(node) {
|
|
3759
|
+
// This will validate the target type is pointing to a valid ref.
|
|
3760
|
+
resolveTypeReferenceSym(node.targetType, undefined);
|
|
3761
|
+
const links = resolver.getNodeLinks(node.targetType);
|
|
3762
|
+
if (links.isTemplateInstantiation) {
|
|
3763
|
+
program.reportDiagnostic(createDiagnostic({
|
|
3764
|
+
code: "augment-decorator-target",
|
|
3765
|
+
messageId: "noInstance",
|
|
3766
|
+
target: node.targetType,
|
|
3767
|
+
}));
|
|
3768
|
+
}
|
|
3769
|
+
// If this was used to get a type this is invalid, only used for validation.
|
|
3770
|
+
return errorType;
|
|
3771
|
+
}
|
|
3772
|
+
/**
|
|
3773
|
+
* Check that using statements are targeting valid symbols.
|
|
3774
|
+
*/
|
|
3775
|
+
function checkUsings(node) {
|
|
3776
|
+
const usedSym = resolveTypeReferenceSym(node.name, undefined);
|
|
3777
|
+
if (usedSym) {
|
|
3778
|
+
if (~usedSym.flags & 256 /* SymbolFlags.Namespace */) {
|
|
3779
|
+
reportCheckerDiagnostic(createDiagnostic({ code: "using-invalid-ref", target: node.name }));
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
// If this was used to get a type this is invalid, only used for validation.
|
|
3783
|
+
return errorType;
|
|
3784
|
+
}
|
|
4164
3785
|
function checkDecorators(targetType, node, mapper) {
|
|
4165
|
-
const sym = isMemberNode(node)
|
|
3786
|
+
const sym = isMemberNode(node)
|
|
3787
|
+
? (getSymbolForMember(node) ?? node.symbol)
|
|
3788
|
+
: getMergedSymbol(node.symbol);
|
|
4166
3789
|
const decorators = [];
|
|
4167
|
-
const augmentDecoratorNodes =
|
|
3790
|
+
const augmentDecoratorNodes = resolver.getAugmentDecoratorsForSym(sym);
|
|
4168
3791
|
const decoratorNodes = [
|
|
4169
3792
|
...augmentDecoratorNodes, // the first decorator will be executed at last, so augmented decorator should be placed at first.
|
|
4170
3793
|
...node.decorators,
|
|
@@ -4233,13 +3856,10 @@ export function createChecker(program) {
|
|
|
4233
3856
|
return type;
|
|
4234
3857
|
}
|
|
4235
3858
|
function checkScalarExtends(scalar, extendsRef, mapper) {
|
|
4236
|
-
const symId =
|
|
3859
|
+
const symId = getNodeSym(scalar);
|
|
4237
3860
|
pendingResolutions.start(symId, ResolutionKind.BaseType);
|
|
4238
|
-
const target =
|
|
4239
|
-
if (target
|
|
4240
|
-
return undefined;
|
|
4241
|
-
}
|
|
4242
|
-
if (pendingResolutions.has(getNodeSymId(target.declarations[0]), ResolutionKind.BaseType)) {
|
|
3861
|
+
const target = resolver.getNodeLinks(extendsRef).resolvedSymbol;
|
|
3862
|
+
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
4243
3863
|
if (mapper === undefined) {
|
|
4244
3864
|
reportCheckerDiagnostic(createDiagnostic({
|
|
4245
3865
|
code: "circular-base-type",
|
|
@@ -4249,7 +3869,7 @@ export function createChecker(program) {
|
|
|
4249
3869
|
}
|
|
4250
3870
|
return undefined;
|
|
4251
3871
|
}
|
|
4252
|
-
const extendsType =
|
|
3872
|
+
const extendsType = getTypeForNode(extendsRef, mapper);
|
|
4253
3873
|
pendingResolutions.finish(symId, ResolutionKind.BaseType);
|
|
4254
3874
|
if (isErrorType(extendsType)) {
|
|
4255
3875
|
compilerAssert(program.hasError(), "Should already have reported an error.", extendsRef);
|
|
@@ -4314,7 +3934,7 @@ export function createChecker(program) {
|
|
|
4314
3934
|
return links.declaredType;
|
|
4315
3935
|
}
|
|
4316
3936
|
checkTemplateDeclaration(node, mapper);
|
|
4317
|
-
const aliasSymId =
|
|
3937
|
+
const aliasSymId = getNodeSym(node);
|
|
4318
3938
|
if (pendingResolutions.has(aliasSymId, ResolutionKind.Type)) {
|
|
4319
3939
|
if (mapper === undefined) {
|
|
4320
3940
|
reportCheckerDiagnostic(createDiagnostic({
|
|
@@ -4347,8 +3967,7 @@ export function createChecker(program) {
|
|
|
4347
3967
|
return links.value;
|
|
4348
3968
|
}
|
|
4349
3969
|
const type = node.type ? getTypeForNode(node.type, undefined) : undefined;
|
|
4350
|
-
|
|
4351
|
-
if (pendingResolutions.has(symId, ResolutionKind.Value)) {
|
|
3970
|
+
if (pendingResolutions.has(node.symbol, ResolutionKind.Value)) {
|
|
4352
3971
|
reportCheckerDiagnostic(createDiagnostic({
|
|
4353
3972
|
code: "circular-const",
|
|
4354
3973
|
format: { name: node.id.sv },
|
|
@@ -4356,9 +3975,9 @@ export function createChecker(program) {
|
|
|
4356
3975
|
}));
|
|
4357
3976
|
return null;
|
|
4358
3977
|
}
|
|
4359
|
-
pendingResolutions.start(
|
|
3978
|
+
pendingResolutions.start(node.symbol, ResolutionKind.Value);
|
|
4360
3979
|
const value = getValueForNode(node.value, undefined, type && { kind: "assignment", type });
|
|
4361
|
-
pendingResolutions.finish(
|
|
3980
|
+
pendingResolutions.finish(node.symbol, ResolutionKind.Value);
|
|
4362
3981
|
if (value === null || (type && !checkValueOfType(value, type, node.id))) {
|
|
4363
3982
|
links.value = null;
|
|
4364
3983
|
return links.value;
|
|
@@ -4482,6 +4101,8 @@ export function createChecker(program) {
|
|
|
4482
4101
|
if (mapper === undefined) {
|
|
4483
4102
|
interfaceType.namespace?.interfaces.set(interfaceType.name, interfaceType);
|
|
4484
4103
|
}
|
|
4104
|
+
lateBindMemberContainer(interfaceType);
|
|
4105
|
+
lateBindMembers(interfaceType);
|
|
4485
4106
|
return interfaceType;
|
|
4486
4107
|
}
|
|
4487
4108
|
function checkInterfaceMembers(node, mapper, interfaceType) {
|
|
@@ -4530,6 +4151,8 @@ export function createChecker(program) {
|
|
|
4530
4151
|
if (mapper === undefined) {
|
|
4531
4152
|
unionType.namespace?.unions.set(unionType.name, unionType);
|
|
4532
4153
|
}
|
|
4154
|
+
lateBindMemberContainer(unionType);
|
|
4155
|
+
lateBindMembers(unionType);
|
|
4533
4156
|
return unionType;
|
|
4534
4157
|
}
|
|
4535
4158
|
function checkUnionVariants(parentUnion, node, variants, mapper) {
|
|
@@ -4574,13 +4197,10 @@ export function createChecker(program) {
|
|
|
4574
4197
|
return variantType;
|
|
4575
4198
|
}
|
|
4576
4199
|
function isMemberNode(node) {
|
|
4577
|
-
return (node.
|
|
4578
|
-
node.kind === SyntaxKind.EnumMember ||
|
|
4579
|
-
node.kind === SyntaxKind.OperationStatement ||
|
|
4580
|
-
node.kind === SyntaxKind.UnionVariant);
|
|
4200
|
+
return node.symbol && !!(node.symbol.flags & 262144 /* SymbolFlags.Member */);
|
|
4581
4201
|
}
|
|
4582
4202
|
function getMemberSymbol(parentSym, name) {
|
|
4583
|
-
return parentSym ?
|
|
4203
|
+
return parentSym ? resolver.getAugmentedSymbolTable(parentSym.members).get(name) : undefined;
|
|
4584
4204
|
}
|
|
4585
4205
|
function getSymbolForMember(node) {
|
|
4586
4206
|
if (!node.id) {
|
|
@@ -4588,11 +4208,11 @@ export function createChecker(program) {
|
|
|
4588
4208
|
}
|
|
4589
4209
|
const name = node.id.sv;
|
|
4590
4210
|
const parentSym = node.parent?.symbol;
|
|
4591
|
-
return parentSym ?
|
|
4211
|
+
return parentSym ? getMemberSymbol(parentSym, name) : undefined;
|
|
4592
4212
|
}
|
|
4593
4213
|
function getSymbolLinksForMember(node) {
|
|
4594
4214
|
const sym = getSymbolForMember(node);
|
|
4595
|
-
return sym ? (sym
|
|
4215
|
+
return sym ? (getSymNode(sym) === node ? getSymbolLinks(sym) : undefined) : undefined;
|
|
4596
4216
|
}
|
|
4597
4217
|
function checkEnumMember(node, mapper, parentEnum) {
|
|
4598
4218
|
const name = node.id.sv;
|
|
@@ -4712,119 +4332,17 @@ export function createChecker(program) {
|
|
|
4712
4332
|
function getLiteralType(node) {
|
|
4713
4333
|
return createLiteralType(node.value, node);
|
|
4714
4334
|
}
|
|
4715
|
-
function mergeSymbolTable(source, target) {
|
|
4716
|
-
for (const [sym, duplicates] of source.duplicates) {
|
|
4717
|
-
const targetSet = target.duplicates.get(sym);
|
|
4718
|
-
if (targetSet === undefined) {
|
|
4719
|
-
mutate(target.duplicates).set(sym, new Set([...duplicates]));
|
|
4720
|
-
}
|
|
4721
|
-
else {
|
|
4722
|
-
for (const duplicate of duplicates) {
|
|
4723
|
-
mutate(targetSet).add(duplicate);
|
|
4724
|
-
}
|
|
4725
|
-
}
|
|
4726
|
-
}
|
|
4727
|
-
for (const [key, sourceBinding] of source) {
|
|
4728
|
-
if (sourceBinding.flags & 4096 /* SymbolFlags.Namespace */) {
|
|
4729
|
-
let targetBinding = target.get(key);
|
|
4730
|
-
if (!targetBinding) {
|
|
4731
|
-
targetBinding = {
|
|
4732
|
-
...sourceBinding,
|
|
4733
|
-
declarations: [],
|
|
4734
|
-
exports: createSymbolTable(),
|
|
4735
|
-
};
|
|
4736
|
-
target.set(key, targetBinding);
|
|
4737
|
-
}
|
|
4738
|
-
if (targetBinding.flags & 4096 /* SymbolFlags.Namespace */) {
|
|
4739
|
-
mergedSymbols.set(sourceBinding, targetBinding);
|
|
4740
|
-
mutate(targetBinding.declarations).push(...sourceBinding.declarations);
|
|
4741
|
-
mergeSymbolTable(sourceBinding.exports, mutate(targetBinding.exports));
|
|
4742
|
-
}
|
|
4743
|
-
else {
|
|
4744
|
-
// this will set a duplicate error
|
|
4745
|
-
target.set(key, sourceBinding);
|
|
4746
|
-
}
|
|
4747
|
-
}
|
|
4748
|
-
else if (sourceBinding.flags & 4194304 /* SymbolFlags.Declaration */ ||
|
|
4749
|
-
sourceBinding.flags & 8388608 /* SymbolFlags.Implementation */) {
|
|
4750
|
-
if (sourceBinding.flags & 16384 /* SymbolFlags.Decorator */) {
|
|
4751
|
-
mergeDeclarationOrImplementation(key, sourceBinding, target, 16384 /* SymbolFlags.Decorator */);
|
|
4752
|
-
}
|
|
4753
|
-
else if (sourceBinding.flags & 131072 /* SymbolFlags.Function */) {
|
|
4754
|
-
mergeDeclarationOrImplementation(key, sourceBinding, target, 131072 /* SymbolFlags.Function */);
|
|
4755
|
-
}
|
|
4756
|
-
else {
|
|
4757
|
-
target.set(key, sourceBinding);
|
|
4758
|
-
}
|
|
4759
|
-
}
|
|
4760
|
-
else {
|
|
4761
|
-
target.set(key, sourceBinding);
|
|
4762
|
-
}
|
|
4763
|
-
}
|
|
4764
|
-
}
|
|
4765
|
-
function mergeDeclarationOrImplementation(key, sourceBinding, target, expectTargetFlags) {
|
|
4766
|
-
const targetBinding = target.get(key);
|
|
4767
|
-
if (!targetBinding || !(targetBinding.flags & expectTargetFlags)) {
|
|
4768
|
-
target.set(key, sourceBinding);
|
|
4769
|
-
return;
|
|
4770
|
-
}
|
|
4771
|
-
const isSourceDeclaration = sourceBinding.flags & 4194304 /* SymbolFlags.Declaration */;
|
|
4772
|
-
const isSourceImplementation = sourceBinding.flags & 8388608 /* SymbolFlags.Implementation */;
|
|
4773
|
-
const isTargetDeclaration = targetBinding.flags & 4194304 /* SymbolFlags.Declaration */;
|
|
4774
|
-
const isTargetImplementation = targetBinding.flags & 8388608 /* SymbolFlags.Implementation */;
|
|
4775
|
-
if (isTargetDeclaration && isTargetImplementation) {
|
|
4776
|
-
// If the target already has both a declration and implementation set the symbol which will mark it as duplicate
|
|
4777
|
-
target.set(key, sourceBinding);
|
|
4778
|
-
}
|
|
4779
|
-
else if (isTargetDeclaration && isSourceImplementation) {
|
|
4780
|
-
mergedSymbols.set(sourceBinding, targetBinding);
|
|
4781
|
-
mutate(targetBinding).value = sourceBinding.value;
|
|
4782
|
-
mutate(targetBinding).flags |= sourceBinding.flags;
|
|
4783
|
-
mutate(targetBinding.declarations).push(...sourceBinding.declarations);
|
|
4784
|
-
}
|
|
4785
|
-
else if (isTargetImplementation && isSourceDeclaration) {
|
|
4786
|
-
mergedSymbols.set(sourceBinding, targetBinding);
|
|
4787
|
-
mutate(targetBinding).flags |= sourceBinding.flags;
|
|
4788
|
-
mutate(targetBinding.declarations).unshift(...sourceBinding.declarations);
|
|
4789
|
-
}
|
|
4790
|
-
else {
|
|
4791
|
-
// this will set a duplicate error
|
|
4792
|
-
target.set(key, sourceBinding);
|
|
4793
|
-
}
|
|
4794
|
-
}
|
|
4795
4335
|
function getMergedSymbol(sym) {
|
|
4796
|
-
if (!sym)
|
|
4797
|
-
|
|
4798
|
-
return
|
|
4799
|
-
}
|
|
4800
|
-
function createGlobalNamespaceNode() {
|
|
4801
|
-
const nsId = {
|
|
4802
|
-
kind: SyntaxKind.Identifier,
|
|
4803
|
-
pos: 0,
|
|
4804
|
-
end: 0,
|
|
4805
|
-
sv: "global",
|
|
4806
|
-
symbol: undefined,
|
|
4807
|
-
flags: 8 /* NodeFlags.Synthetic */,
|
|
4808
|
-
};
|
|
4809
|
-
const nsNode = {
|
|
4810
|
-
kind: SyntaxKind.NamespaceStatement,
|
|
4811
|
-
decorators: [],
|
|
4812
|
-
pos: 0,
|
|
4813
|
-
end: 0,
|
|
4814
|
-
id: nsId,
|
|
4815
|
-
symbol: undefined,
|
|
4816
|
-
locals: createSymbolTable(),
|
|
4817
|
-
flags: 8 /* NodeFlags.Synthetic */,
|
|
4818
|
-
};
|
|
4819
|
-
mutate(nsNode).symbol = createSymbol(nsNode, nsId.sv, 4096 /* SymbolFlags.Namespace */);
|
|
4820
|
-
mutate(nsNode.symbol.exports).set(nsId.sv, nsNode.symbol);
|
|
4821
|
-
return nsNode;
|
|
4336
|
+
// if (!sym) return sym;
|
|
4337
|
+
// return mergedSymbols.get(sym) || sym;
|
|
4338
|
+
return resolver.getMergedSymbol(sym);
|
|
4822
4339
|
}
|
|
4823
4340
|
function createGlobalNamespaceType() {
|
|
4824
|
-
const
|
|
4341
|
+
const sym = resolver.symbols.global;
|
|
4342
|
+
const type = createType({
|
|
4825
4343
|
kind: "Namespace",
|
|
4826
4344
|
name: "",
|
|
4827
|
-
node:
|
|
4345
|
+
node: getGlobalNamespaceNode(),
|
|
4828
4346
|
models: new Map(),
|
|
4829
4347
|
scalars: new Map(),
|
|
4830
4348
|
operations: new Map(),
|
|
@@ -4836,8 +4354,9 @@ export function createChecker(program) {
|
|
|
4836
4354
|
functionDeclarations: new Map(),
|
|
4837
4355
|
decorators: [],
|
|
4838
4356
|
});
|
|
4839
|
-
getSymbolLinks(
|
|
4840
|
-
|
|
4357
|
+
getSymbolLinks(sym).type = type;
|
|
4358
|
+
type.decorators = checkAugmentDecorators(sym, type, undefined);
|
|
4359
|
+
return finishType(type);
|
|
4841
4360
|
}
|
|
4842
4361
|
function initializeClone(type, additionalProps) {
|
|
4843
4362
|
let clone;
|
|
@@ -5464,7 +4983,7 @@ export function createChecker(program) {
|
|
|
5464
4983
|
const ref = resolveTypeReferenceSym(node.target, undefined, true);
|
|
5465
4984
|
if (!ref)
|
|
5466
4985
|
throw new ProjectionError("Can't find decorator.");
|
|
5467
|
-
compilerAssert(ref.flags &
|
|
4986
|
+
compilerAssert(ref.flags & 1024 /* SymbolFlags.Decorator */, "should only resolve decorator symbols");
|
|
5468
4987
|
return createFunctionType((...args) => {
|
|
5469
4988
|
ref.value({ program }, ...args.map(unsafe_projectionArgumentMarshalForJS));
|
|
5470
4989
|
return voidType;
|
|
@@ -5480,15 +4999,15 @@ export function createChecker(program) {
|
|
|
5480
4999
|
currentContext = currentContext.parent;
|
|
5481
5000
|
}
|
|
5482
5001
|
// next, resolve outside
|
|
5483
|
-
const ref =
|
|
5002
|
+
const { finalSymbol: ref } = resolver.resolveTypeReference(node);
|
|
5484
5003
|
if (!ref)
|
|
5485
5004
|
throw new ProjectionError("Unknown identifier " + node.sv);
|
|
5486
|
-
if (ref.flags &
|
|
5005
|
+
if (ref.flags & 1024 /* SymbolFlags.Decorator */) {
|
|
5487
5006
|
// shouldn't ever resolve a decorator symbol here (without passing
|
|
5488
5007
|
// true to resolveTypeReference)
|
|
5489
5008
|
return errorType;
|
|
5490
5009
|
}
|
|
5491
|
-
else if (ref.flags &
|
|
5010
|
+
else if (ref.flags & 8192 /* SymbolFlags.Function */) {
|
|
5492
5011
|
// TODO: store this in a symbol link probably?
|
|
5493
5012
|
const t = createFunctionType((...args) => {
|
|
5494
5013
|
const retval = ref.value(program, ...args.map(unsafe_projectionArgumentMarshalForJS));
|
|
@@ -5555,16 +5074,6 @@ export function createChecker(program) {
|
|
|
5555
5074
|
function project(target, projection, args = []) {
|
|
5556
5075
|
return evalProjection(projection, target, args.map((x) => marshalProjectionReturn(x)));
|
|
5557
5076
|
}
|
|
5558
|
-
function memberExpressionToString(expr) {
|
|
5559
|
-
let current = expr;
|
|
5560
|
-
const parts = [];
|
|
5561
|
-
while (current.kind === SyntaxKind.MemberExpression) {
|
|
5562
|
-
parts.push(current.id.sv);
|
|
5563
|
-
current = current.base;
|
|
5564
|
-
}
|
|
5565
|
-
parts.push(current.sv);
|
|
5566
|
-
return parts.reverse().join(".");
|
|
5567
|
-
}
|
|
5568
5077
|
/**
|
|
5569
5078
|
* Check if the source type can be assigned to the target type and emit diagnostics
|
|
5570
5079
|
* @param source Type of a value
|
|
@@ -5630,9 +5139,6 @@ export function createChecker(program) {
|
|
|
5630
5139
|
return valueExactTypes.get(value);
|
|
5631
5140
|
}
|
|
5632
5141
|
}
|
|
5633
|
-
function isAnonymous(type) {
|
|
5634
|
-
return !("name" in type) || typeof type.name !== "string" || !type.name;
|
|
5635
|
-
}
|
|
5636
5142
|
/**
|
|
5637
5143
|
* Find all named models that could have been the source of the given
|
|
5638
5144
|
* property. This includes the named parents of all property sources in a
|
|
@@ -5666,7 +5172,7 @@ function addDerivedModels(models, possiblyDerivedModels) {
|
|
|
5666
5172
|
}
|
|
5667
5173
|
}
|
|
5668
5174
|
}
|
|
5669
|
-
function createTypeMapper(parameters, args, parentMapper) {
|
|
5175
|
+
function createTypeMapper(parameters, args, source, parentMapper) {
|
|
5670
5176
|
const map = new Map(parentMapper?.map ?? []);
|
|
5671
5177
|
for (const [index, param] of parameters.entries()) {
|
|
5672
5178
|
map.set(param, args[index]);
|
|
@@ -5677,6 +5183,7 @@ function createTypeMapper(parameters, args, parentMapper) {
|
|
|
5677
5183
|
getMappedType: (type) => {
|
|
5678
5184
|
return map.get(type) ?? type;
|
|
5679
5185
|
},
|
|
5186
|
+
source,
|
|
5680
5187
|
map,
|
|
5681
5188
|
};
|
|
5682
5189
|
}
|
|
@@ -6055,4 +5562,14 @@ function unsafe_projectionArgumentMarshalForJS(arg) {
|
|
|
6055
5562
|
}
|
|
6056
5563
|
return arg;
|
|
6057
5564
|
}
|
|
5565
|
+
function printTypeReferenceNode(node) {
|
|
5566
|
+
switch (node.kind) {
|
|
5567
|
+
case SyntaxKind.MemberExpression:
|
|
5568
|
+
return `${printTypeReferenceNode(node.base)}.${printTypeReferenceNode(node.id)}`;
|
|
5569
|
+
case SyntaxKind.TypeReference:
|
|
5570
|
+
return printTypeReferenceNode(node.target);
|
|
5571
|
+
case SyntaxKind.Identifier:
|
|
5572
|
+
return node.sv;
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
6058
5575
|
//# sourceMappingURL=checker.js.map
|