@typespec/compiler 1.9.0-dev.1 → 1.9.0-dev.10
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/manifest.js +2 -2
- package/dist/src/core/checker.d.ts.map +1 -1
- package/dist/src/core/checker.js +516 -378
- package/dist/src/core/checker.js.map +1 -1
- package/dist/src/core/cli/actions/compile/compile.js +3 -1
- package/dist/src/core/cli/actions/compile/compile.js.map +1 -1
- package/dist/src/core/emitter-utils.d.ts +1 -1
- package/dist/src/core/emitter-utils.d.ts.map +1 -1
- package/dist/src/core/emitter-utils.js +12 -4
- package/dist/src/core/emitter-utils.js.map +1 -1
- package/dist/src/core/linter.d.ts.map +1 -1
- package/dist/src/core/linter.js +4 -4
- package/dist/src/core/linter.js.map +1 -1
- package/dist/src/core/perf.d.ts +12 -0
- package/dist/src/core/perf.d.ts.map +1 -0
- package/dist/src/core/perf.js +57 -0
- package/dist/src/core/perf.js.map +1 -0
- package/dist/src/core/program.d.ts.map +1 -1
- package/dist/src/core/program.js +20 -17
- package/dist/src/core/program.js.map +1 -1
- package/dist/src/core/stats.d.ts +6 -7
- package/dist/src/core/stats.d.ts.map +1 -1
- package/dist/src/core/stats.js +1 -18
- package/dist/src/core/stats.js.map +1 -1
- package/dist/src/core/type-relation-checker.d.ts.map +1 -1
- package/dist/src/core/type-relation-checker.js +3 -7
- package/dist/src/core/type-relation-checker.js.map +1 -1
- package/dist/src/core/type-utils.d.ts +17 -2
- package/dist/src/core/type-utils.d.ts.map +1 -1
- package/dist/src/core/type-utils.js +4 -9
- package/dist/src/core/type-utils.js.map +1 -1
- package/dist/src/core/types.d.ts +42 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/decorators.d.ts.map +1 -1
- package/dist/src/lib/decorators.js +1 -1
- package/dist/src/lib/decorators.js.map +1 -1
- package/dist/src/lib/examples.d.ts +21 -2
- package/dist/src/lib/examples.d.ts.map +1 -1
- package/dist/src/lib/examples.js +43 -10
- package/dist/src/lib/examples.js.map +1 -1
- package/dist/src/lib/paging.d.ts.map +1 -1
- package/dist/src/lib/paging.js +3 -14
- package/dist/src/lib/paging.js.map +1 -1
- package/dist/src/server/serverlib.d.ts.map +1 -1
- package/dist/src/server/serverlib.js +1 -1
- package/dist/src/server/serverlib.js.map +1 -1
- package/dist/src/typekit/kits/array.js +1 -1
- package/dist/src/typekit/kits/array.js.map +1 -1
- package/dist/src/typekit/kits/record.js +1 -1
- package/dist/src/typekit/kits/record.js.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +1 -0
- package/dist/src/utils/index.js.map +1 -1
- package/package.json +7 -7
package/dist/src/core/checker.js
CHANGED
|
@@ -19,6 +19,106 @@ import { exprIsBareIdentifier, getFirstAncestor, getIdentifierContext, hasParseE
|
|
|
19
19
|
import { createTypeRelationChecker } from "./type-relation-checker.js";
|
|
20
20
|
import { getFullyQualifiedSymbolName, getParentTemplateNode, isArrayModelType, isErrorType, isNullType, isTemplateInstance, isType, isValue, } from "./type-utils.js";
|
|
21
21
|
import { IdentifierKind, ResolutionResultFlags, SyntaxKind, } from "./types.js";
|
|
22
|
+
var CheckFlags;
|
|
23
|
+
(function (CheckFlags) {
|
|
24
|
+
/** No flags set. */
|
|
25
|
+
CheckFlags[CheckFlags["None"] = 0] = "None";
|
|
26
|
+
/** Currently checking within an uninstantiated template declaration. */
|
|
27
|
+
CheckFlags[CheckFlags["InTemplateDeclaration"] = 1] = "InTemplateDeclaration";
|
|
28
|
+
})(CheckFlags || (CheckFlags = {}));
|
|
29
|
+
class CheckContext {
|
|
30
|
+
/** The type mapper associated with this context, if any. */
|
|
31
|
+
mapper;
|
|
32
|
+
/** The flags enabled in this context. */
|
|
33
|
+
flags;
|
|
34
|
+
#templateParametersObserved;
|
|
35
|
+
static from(contextOrMapper) {
|
|
36
|
+
if (contextOrMapper instanceof CheckContext) {
|
|
37
|
+
return contextOrMapper;
|
|
38
|
+
}
|
|
39
|
+
return new CheckContext(contextOrMapper, CheckFlags.None);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The default CheckContext to use at API entrypoints.
|
|
43
|
+
*/
|
|
44
|
+
static DEFAULT = new CheckContext(undefined, CheckFlags.None);
|
|
45
|
+
constructor(mapper, flags, templateParametersObserved) {
|
|
46
|
+
this.mapper = mapper;
|
|
47
|
+
this.flags = flags;
|
|
48
|
+
this.#templateParametersObserved = templateParametersObserved;
|
|
49
|
+
Object.freeze(this);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns a new context with the given flags _added_ to the existing flags.
|
|
53
|
+
*
|
|
54
|
+
* @param flags - the flags to enable
|
|
55
|
+
* @returns a new CheckContext with the given flags enabled.
|
|
56
|
+
*/
|
|
57
|
+
withFlags(flags) {
|
|
58
|
+
return new CheckContext(this.mapper, this.flags | flags, this.#templateParametersObserved);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns a new context with the given flags disabled.
|
|
62
|
+
*
|
|
63
|
+
* @param flags - the flags to disable
|
|
64
|
+
* @returns a new CheckContext with the given flags disabled.
|
|
65
|
+
*/
|
|
66
|
+
maskFlags(flags) {
|
|
67
|
+
return new CheckContext(this.mapper, this.flags & ~flags, this.#templateParametersObserved);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Returns true if ALL of the given flags are enabled in this context.
|
|
71
|
+
*/
|
|
72
|
+
hasFlags(flags) {
|
|
73
|
+
return (this.flags & flags) === flags;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns a new context with the given mapper.
|
|
77
|
+
*
|
|
78
|
+
* @param mapper - the new type mapper, or undefined to clear the mapper
|
|
79
|
+
* @returns a new CheckContext with the given mapper.
|
|
80
|
+
*/
|
|
81
|
+
withMapper(mapper) {
|
|
82
|
+
return new CheckContext(mapper, this.flags, this.#templateParametersObserved);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Observes a template parameter within the current observation scope, if any.
|
|
86
|
+
*
|
|
87
|
+
* @param param - the TemplateParameter type instance to observe
|
|
88
|
+
*/
|
|
89
|
+
observeTemplateParameter(param) {
|
|
90
|
+
this.#templateParametersObserved?.add(param);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns a new CheckContext with a new (empty) template parameter observation scope.
|
|
94
|
+
*
|
|
95
|
+
* Call this when you need to observe template parameters used within a specific context.
|
|
96
|
+
*
|
|
97
|
+
* @returns a new CheckContext with an empty template parameter observation scope.
|
|
98
|
+
*/
|
|
99
|
+
enterTemplateObserverScope() {
|
|
100
|
+
return new CheckContext(this.mapper, this.flags, new Set());
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Creates a new CheckContext with no template parameter observation enabled.
|
|
104
|
+
*
|
|
105
|
+
* Call this when the checker is moving from one declaration to another, where usage of template parameters
|
|
106
|
+
* from the next scope should not impact the usage from the previous scope.
|
|
107
|
+
*
|
|
108
|
+
* @returns a new CheckContext with no template parameter observation.
|
|
109
|
+
*/
|
|
110
|
+
exitTemplateObserverScope() {
|
|
111
|
+
return new CheckContext(this.mapper, this.flags, undefined);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* @returns true if the observer scope in this context has seen any template parameter usage.
|
|
115
|
+
*/
|
|
116
|
+
hasObservedTemplateParameters() {
|
|
117
|
+
return this.#templateParametersObserved !== undefined
|
|
118
|
+
? this.#templateParametersObserved.size > 0
|
|
119
|
+
: false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
22
122
|
/**
|
|
23
123
|
* Maps type arguments to type instantiation.
|
|
24
124
|
*/
|
|
@@ -140,10 +240,10 @@ export function createChecker(program, resolver) {
|
|
|
140
240
|
const sym = typespecNamespaceBinding?.exports?.get(name);
|
|
141
241
|
compilerAssert(sym, `Unexpected missing symbol to std type "${name}"`);
|
|
142
242
|
if (sym.flags & 2 /* SymbolFlags.Model */) {
|
|
143
|
-
checkModelStatement(sym.declarations[0]
|
|
243
|
+
checkModelStatement(CheckContext.DEFAULT, sym.declarations[0]);
|
|
144
244
|
}
|
|
145
245
|
else {
|
|
146
|
-
checkScalar(sym.declarations[0]
|
|
246
|
+
checkScalar(CheckContext.DEFAULT, sym.declarations[0]);
|
|
147
247
|
}
|
|
148
248
|
const loadedType = stdTypes[name];
|
|
149
249
|
compilerAssert(loadedType, `TypeSpec std type "${name}" should have been initalized before using array syntax.`);
|
|
@@ -157,17 +257,17 @@ export function createChecker(program, resolver) {
|
|
|
157
257
|
* @param type Type
|
|
158
258
|
* @param mapper Type mapper if in an template instantiation
|
|
159
259
|
*/
|
|
160
|
-
function linkType(links, type
|
|
161
|
-
if (mapper === undefined) {
|
|
260
|
+
function linkType(ctx, links, type) {
|
|
261
|
+
if (ctx.mapper === undefined) {
|
|
162
262
|
links.declaredType = type;
|
|
163
263
|
links.instantiations = new TypeInstantiationMap();
|
|
164
264
|
}
|
|
165
265
|
else if (links.instantiations) {
|
|
166
|
-
links.instantiations.set(mapper.args, type);
|
|
266
|
+
links.instantiations.set(ctx.mapper.args, type);
|
|
167
267
|
}
|
|
168
268
|
}
|
|
169
|
-
function linkMemberType(links, type
|
|
170
|
-
if (mapper === undefined) {
|
|
269
|
+
function linkMemberType(ctx, links, type) {
|
|
270
|
+
if (ctx.mapper === undefined) {
|
|
171
271
|
links.declaredType = type;
|
|
172
272
|
}
|
|
173
273
|
}
|
|
@@ -177,15 +277,15 @@ export function createChecker(program, resolver) {
|
|
|
177
277
|
* @param mapper Type mapper.
|
|
178
278
|
* @returns Checked type for the given member symbol.
|
|
179
279
|
*/
|
|
180
|
-
function checkMemberSym(
|
|
280
|
+
function checkMemberSym(ctx, sym) {
|
|
181
281
|
const symbolLinks = getSymbolLinks(sym);
|
|
182
|
-
const memberContainer = getTypeForNode(getSymNode(sym.parent),
|
|
282
|
+
const memberContainer = getTypeForNode(getSymNode(sym.parent), ctx);
|
|
183
283
|
const type = symbolLinks.declaredType ?? symbolLinks.type;
|
|
184
284
|
if (type) {
|
|
185
285
|
return type;
|
|
186
286
|
}
|
|
187
287
|
else {
|
|
188
|
-
return checkMember(getSymNode(sym),
|
|
288
|
+
return checkMember(ctx, getSymNode(sym), memberContainer);
|
|
189
289
|
}
|
|
190
290
|
}
|
|
191
291
|
/**
|
|
@@ -195,18 +295,18 @@ export function createChecker(program, resolver) {
|
|
|
195
295
|
* @param containerType Member node container type(Interface, Model, Union, etc.)
|
|
196
296
|
* @returns Checked member
|
|
197
297
|
*/
|
|
198
|
-
function checkMember(
|
|
298
|
+
function checkMember(ctx, node, containerType) {
|
|
199
299
|
switch (node.kind) {
|
|
200
300
|
case SyntaxKind.ModelProperty:
|
|
201
|
-
return checkModelProperty(
|
|
301
|
+
return checkModelProperty(ctx, node);
|
|
202
302
|
case SyntaxKind.EnumMember:
|
|
203
|
-
return checkEnumMember(
|
|
303
|
+
return checkEnumMember(ctx, node, containerType);
|
|
204
304
|
case SyntaxKind.OperationStatement:
|
|
205
|
-
return checkOperation(
|
|
305
|
+
return checkOperation(ctx, node, containerType);
|
|
206
306
|
case SyntaxKind.UnionVariant:
|
|
207
|
-
return checkUnionVariant(
|
|
307
|
+
return checkUnionVariant(ctx, node);
|
|
208
308
|
case SyntaxKind.ScalarConstructor:
|
|
209
|
-
return checkScalarConstructor(
|
|
309
|
+
return checkScalarConstructor(ctx, node, containerType);
|
|
210
310
|
}
|
|
211
311
|
}
|
|
212
312
|
function getTypeForTypeOrIndeterminate(entity) {
|
|
@@ -215,8 +315,9 @@ export function createChecker(program, resolver) {
|
|
|
215
315
|
}
|
|
216
316
|
return entity;
|
|
217
317
|
}
|
|
218
|
-
function getTypeForNode(node,
|
|
219
|
-
const
|
|
318
|
+
function getTypeForNode(node, mapperOrContext) {
|
|
319
|
+
const ctx = CheckContext.from(mapperOrContext);
|
|
320
|
+
const entity = checkNode(ctx, node);
|
|
220
321
|
if (entity === null) {
|
|
221
322
|
return errorType;
|
|
222
323
|
}
|
|
@@ -242,8 +343,9 @@ export function createChecker(program, resolver) {
|
|
|
242
343
|
}
|
|
243
344
|
return entity;
|
|
244
345
|
}
|
|
245
|
-
function getValueForNode(node,
|
|
246
|
-
const
|
|
346
|
+
function getValueForNode(node, mapperOrContext, constraint) {
|
|
347
|
+
const ctx = CheckContext.from(mapperOrContext);
|
|
348
|
+
const initial = checkNode(ctx, node, constraint);
|
|
247
349
|
if (initial === null) {
|
|
248
350
|
return null;
|
|
249
351
|
}
|
|
@@ -264,7 +366,9 @@ export function createChecker(program, resolver) {
|
|
|
264
366
|
if (entity.kind === "TemplateParameter" &&
|
|
265
367
|
entity.constraint?.valueType &&
|
|
266
368
|
entity.constraint.type === undefined &&
|
|
267
|
-
mapper === undefined) {
|
|
369
|
+
ctx.mapper === undefined) {
|
|
370
|
+
// We must also observe that the template parameter is used here.
|
|
371
|
+
// ctx.observeTemplateParameter(entity);
|
|
268
372
|
return createValue({
|
|
269
373
|
entityKind: "Value",
|
|
270
374
|
valueKind: "TemplateValue",
|
|
@@ -374,8 +478,9 @@ export function createChecker(program, resolver) {
|
|
|
374
478
|
* This means that if the constraint is `string | valueof string` passing `"abc"` will send the value `"abc"` and not the type `"abc"`.
|
|
375
479
|
*/
|
|
376
480
|
function getTypeOrValueForNode(node, mapper, constraint) {
|
|
481
|
+
const ctx = CheckContext.from(mapper);
|
|
377
482
|
const valueConstraint = extractValueOfConstraints(constraint);
|
|
378
|
-
const entity = checkNode(
|
|
483
|
+
const entity = checkNode(ctx, node, valueConstraint);
|
|
379
484
|
if (entity === null) {
|
|
380
485
|
return entity;
|
|
381
486
|
}
|
|
@@ -419,33 +524,33 @@ export function createChecker(program, resolver) {
|
|
|
419
524
|
* For nodes that can be both type or values(e.g. string literals), an indeterminate entity will be returned.
|
|
420
525
|
* It is the job of of the consumer to decide if it should be a type or a value depending on the context.
|
|
421
526
|
*/
|
|
422
|
-
function checkNode(
|
|
527
|
+
function checkNode(ctx, node, valueConstraint) {
|
|
423
528
|
switch (node.kind) {
|
|
424
529
|
case SyntaxKind.ModelExpression:
|
|
425
|
-
return checkModel(
|
|
530
|
+
return checkModel(ctx, node);
|
|
426
531
|
case SyntaxKind.ModelStatement:
|
|
427
|
-
return checkModel(
|
|
532
|
+
return checkModel(ctx, node);
|
|
428
533
|
case SyntaxKind.ModelProperty:
|
|
429
|
-
return checkModelProperty(
|
|
534
|
+
return checkModelProperty(ctx, node);
|
|
430
535
|
case SyntaxKind.ScalarStatement:
|
|
431
|
-
return checkScalar(
|
|
536
|
+
return checkScalar(ctx, node);
|
|
432
537
|
case SyntaxKind.AliasStatement:
|
|
433
|
-
return checkAlias(
|
|
538
|
+
return checkAlias(ctx, node);
|
|
434
539
|
case SyntaxKind.EnumStatement:
|
|
435
|
-
return checkEnum(
|
|
540
|
+
return checkEnum(ctx, node);
|
|
436
541
|
case SyntaxKind.EnumMember:
|
|
437
|
-
return checkEnumMember(
|
|
542
|
+
return checkEnumMember(ctx, node);
|
|
438
543
|
case SyntaxKind.InterfaceStatement:
|
|
439
|
-
return checkInterface(
|
|
544
|
+
return checkInterface(ctx, node);
|
|
440
545
|
case SyntaxKind.UnionStatement:
|
|
441
|
-
return checkUnion(
|
|
546
|
+
return checkUnion(ctx, node);
|
|
442
547
|
case SyntaxKind.UnionVariant:
|
|
443
|
-
return checkUnionVariant(
|
|
548
|
+
return checkUnionVariant(ctx, node);
|
|
444
549
|
case SyntaxKind.NamespaceStatement:
|
|
445
550
|
case SyntaxKind.JsNamespaceDeclaration:
|
|
446
|
-
return checkNamespace(node);
|
|
551
|
+
return checkNamespace(ctx, node);
|
|
447
552
|
case SyntaxKind.OperationStatement:
|
|
448
|
-
return checkOperation(
|
|
553
|
+
return checkOperation(ctx, node);
|
|
449
554
|
case SyntaxKind.NumericLiteral:
|
|
450
555
|
return checkNumericLiteral(node);
|
|
451
556
|
case SyntaxKind.BooleanLiteral:
|
|
@@ -453,25 +558,25 @@ export function createChecker(program, resolver) {
|
|
|
453
558
|
case SyntaxKind.StringLiteral:
|
|
454
559
|
return checkStringLiteral(node);
|
|
455
560
|
case SyntaxKind.TupleExpression:
|
|
456
|
-
return checkTupleExpression(
|
|
561
|
+
return checkTupleExpression(ctx, node);
|
|
457
562
|
case SyntaxKind.StringTemplateExpression:
|
|
458
|
-
return checkStringTemplateExpresion(
|
|
563
|
+
return checkStringTemplateExpresion(ctx, node);
|
|
459
564
|
case SyntaxKind.ArrayExpression:
|
|
460
|
-
return checkArrayExpression(
|
|
565
|
+
return checkArrayExpression(ctx, node);
|
|
461
566
|
case SyntaxKind.UnionExpression:
|
|
462
|
-
return checkUnionExpression(
|
|
567
|
+
return checkUnionExpression(ctx, node);
|
|
463
568
|
case SyntaxKind.IntersectionExpression:
|
|
464
|
-
return checkIntersectionExpression(
|
|
569
|
+
return checkIntersectionExpression(ctx, node);
|
|
465
570
|
case SyntaxKind.DecoratorDeclarationStatement:
|
|
466
|
-
return checkDecoratorDeclaration(
|
|
571
|
+
return checkDecoratorDeclaration(ctx, node);
|
|
467
572
|
case SyntaxKind.FunctionDeclarationStatement:
|
|
468
|
-
return checkFunctionDeclaration(
|
|
573
|
+
return checkFunctionDeclaration(ctx, node);
|
|
469
574
|
case SyntaxKind.TypeReference:
|
|
470
|
-
return checkTypeOrValueReference(
|
|
575
|
+
return checkTypeOrValueReference(ctx, node);
|
|
471
576
|
case SyntaxKind.TemplateArgument:
|
|
472
|
-
return checkTemplateArgument(
|
|
577
|
+
return checkTemplateArgument(ctx, node);
|
|
473
578
|
case SyntaxKind.TemplateParameterDeclaration:
|
|
474
|
-
return checkTemplateParameterDeclaration(
|
|
579
|
+
return checkTemplateParameterDeclaration(ctx, node);
|
|
475
580
|
case SyntaxKind.VoidKeyword:
|
|
476
581
|
return voidType;
|
|
477
582
|
case SyntaxKind.NeverKeyword:
|
|
@@ -479,19 +584,19 @@ export function createChecker(program, resolver) {
|
|
|
479
584
|
case SyntaxKind.UnknownKeyword:
|
|
480
585
|
return unknownType;
|
|
481
586
|
case SyntaxKind.ObjectLiteral:
|
|
482
|
-
return checkObjectValue(
|
|
587
|
+
return checkObjectValue(ctx, node, valueConstraint);
|
|
483
588
|
case SyntaxKind.ArrayLiteral:
|
|
484
|
-
return checkArrayValue(
|
|
589
|
+
return checkArrayValue(ctx, node, valueConstraint);
|
|
485
590
|
case SyntaxKind.ConstStatement:
|
|
486
591
|
return checkConst(node);
|
|
487
592
|
case SyntaxKind.CallExpression:
|
|
488
|
-
return checkCallExpression(
|
|
593
|
+
return checkCallExpression(ctx, node);
|
|
489
594
|
case SyntaxKind.TypeOfExpression:
|
|
490
|
-
return checkTypeOfExpression(
|
|
595
|
+
return checkTypeOfExpression(ctx, node);
|
|
491
596
|
case SyntaxKind.AugmentDecoratorStatement:
|
|
492
|
-
return checkAugmentDecorator(node);
|
|
597
|
+
return checkAugmentDecorator(ctx, node);
|
|
493
598
|
case SyntaxKind.UsingStatement:
|
|
494
|
-
return checkUsings(node);
|
|
599
|
+
return checkUsings(ctx, node);
|
|
495
600
|
default:
|
|
496
601
|
return errorType;
|
|
497
602
|
}
|
|
@@ -518,7 +623,7 @@ export function createChecker(program, resolver) {
|
|
|
518
623
|
function isInTypeSpecNamespace(type) {
|
|
519
624
|
return Boolean(type.namespace && isTypeSpecNamespace(type.namespace));
|
|
520
625
|
}
|
|
521
|
-
function checkTemplateParameterDeclaration(
|
|
626
|
+
function checkTemplateParameterDeclaration(ctx, node) {
|
|
522
627
|
const parentNode = node.parent;
|
|
523
628
|
const grandParentNode = parentNode.parent;
|
|
524
629
|
const links = getSymbolLinks(node.symbol);
|
|
@@ -526,7 +631,7 @@ export function createChecker(program, resolver) {
|
|
|
526
631
|
templateParameterUsageMap.set(node, false);
|
|
527
632
|
}
|
|
528
633
|
if (pendingResolutions.has(getNodeSym(node), ResolutionKind.Constraint)) {
|
|
529
|
-
if (mapper === undefined) {
|
|
634
|
+
if (ctx.mapper === undefined) {
|
|
530
635
|
reportCheckerDiagnostic(createDiagnostic({
|
|
531
636
|
code: "circular-constraint",
|
|
532
637
|
format: { typeName: node.id.sv },
|
|
@@ -553,18 +658,18 @@ export function createChecker(program, resolver) {
|
|
|
553
658
|
});
|
|
554
659
|
if (node.constraint) {
|
|
555
660
|
pendingResolutions.start(getNodeSym(node), ResolutionKind.Constraint);
|
|
556
|
-
type.constraint = getParamConstraintEntityForNode(node.constraint);
|
|
661
|
+
type.constraint = getParamConstraintEntityForNode(ctx, node.constraint);
|
|
557
662
|
pendingResolutions.finish(getNodeSym(node), ResolutionKind.Constraint);
|
|
558
663
|
}
|
|
559
664
|
if (node.default) {
|
|
560
665
|
// Set this to unknownType in case the default points back to the template itself causing failures
|
|
561
666
|
type.default = unknownType;
|
|
562
|
-
type.default = checkTemplateParameterDefault(node.default, parentNode.templateParameters, index, type.constraint);
|
|
667
|
+
type.default = checkTemplateParameterDefault(ctx, node.default, parentNode.templateParameters, index, type.constraint);
|
|
563
668
|
}
|
|
564
669
|
}
|
|
565
|
-
return mapper ? mapper.getMappedType(type) : type;
|
|
670
|
+
return ctx.mapper ? ctx.mapper.getMappedType(type) : type;
|
|
566
671
|
}
|
|
567
|
-
function getResolvedTypeParameterDefault(declaredType, node
|
|
672
|
+
function getResolvedTypeParameterDefault(ctx, declaredType, node) {
|
|
568
673
|
if (declaredType.default === undefined) {
|
|
569
674
|
return undefined;
|
|
570
675
|
}
|
|
@@ -572,11 +677,11 @@ export function createChecker(program, resolver) {
|
|
|
572
677
|
declaredType.default === null) {
|
|
573
678
|
return declaredType.default;
|
|
574
679
|
}
|
|
575
|
-
return checkNode(node.default
|
|
680
|
+
return checkNode(ctx, node.default);
|
|
576
681
|
}
|
|
577
|
-
function checkTemplateParameterDefault(nodeDefault, templateParameters, index, constraint) {
|
|
682
|
+
function checkTemplateParameterDefault(ctx, nodeDefault, templateParameters, index, constraint) {
|
|
578
683
|
function visit(node) {
|
|
579
|
-
const entity = checkNode(node);
|
|
684
|
+
const entity = checkNode(ctx, node);
|
|
580
685
|
let hasError = false;
|
|
581
686
|
if (entity !== null && "kind" in entity && entity.kind === "TemplateParameter") {
|
|
582
687
|
for (let i = index; i < templateParameters.length; i++) {
|
|
@@ -608,12 +713,12 @@ export function createChecker(program, resolver) {
|
|
|
608
713
|
* @param instantiateTemplate If templated type should be instantiated if they haven't yet.
|
|
609
714
|
* @returns Resolved type.
|
|
610
715
|
*/
|
|
611
|
-
function checkTypeReference(
|
|
612
|
-
const sym = resolveTypeReferenceSym(
|
|
716
|
+
function checkTypeReference(ctx, node, instantiateTemplate = true) {
|
|
717
|
+
const sym = resolveTypeReferenceSym(ctx, node);
|
|
613
718
|
if (!sym) {
|
|
614
719
|
return errorType;
|
|
615
720
|
}
|
|
616
|
-
const type = checkTypeReferenceSymbol(sym, node,
|
|
721
|
+
const type = checkTypeReferenceSymbol(ctx, sym, node, instantiateTemplate);
|
|
617
722
|
return type;
|
|
618
723
|
}
|
|
619
724
|
/**
|
|
@@ -623,21 +728,21 @@ export function createChecker(program, resolver) {
|
|
|
623
728
|
* @param instantiateTemplate If templated type should be instantiated if they haven't yet.
|
|
624
729
|
* @returns Resolved type.
|
|
625
730
|
*/
|
|
626
|
-
function checkTypeOrValueReference(
|
|
627
|
-
const sym = resolveTypeReferenceSym(
|
|
731
|
+
function checkTypeOrValueReference(ctx, node, instantiateTemplate = true) {
|
|
732
|
+
const sym = resolveTypeReferenceSym(ctx, node);
|
|
628
733
|
if (!sym) {
|
|
629
734
|
return errorType;
|
|
630
735
|
}
|
|
631
|
-
return checkTypeOrValueReferenceSymbol(sym, node,
|
|
736
|
+
return checkTypeOrValueReferenceSymbol(ctx, sym, node, instantiateTemplate) ?? errorType;
|
|
632
737
|
}
|
|
633
|
-
function checkTemplateArgument(
|
|
634
|
-
return checkNode(node.argument
|
|
738
|
+
function checkTemplateArgument(ctx, node) {
|
|
739
|
+
return checkNode(ctx, node.argument);
|
|
635
740
|
}
|
|
636
741
|
function resolveTypeOrValueReference(node) {
|
|
637
742
|
const oldDiagnosticHook = onCheckerDiagnostic;
|
|
638
743
|
const diagnostics = [];
|
|
639
744
|
onCheckerDiagnostic = (x) => diagnostics.push(x);
|
|
640
|
-
const entity = checkTypeOrValueReference(
|
|
745
|
+
const entity = checkTypeOrValueReference(CheckContext.DEFAULT, node, false);
|
|
641
746
|
onCheckerDiagnostic = oldDiagnosticHook;
|
|
642
747
|
return [entity === errorType ? undefined : entity, diagnostics];
|
|
643
748
|
}
|
|
@@ -645,7 +750,7 @@ export function createChecker(program, resolver) {
|
|
|
645
750
|
const oldDiagnosticHook = onCheckerDiagnostic;
|
|
646
751
|
const diagnostics = [];
|
|
647
752
|
onCheckerDiagnostic = (x) => diagnostics.push(x);
|
|
648
|
-
const type = checkTypeReference(
|
|
753
|
+
const type = checkTypeReference(CheckContext.DEFAULT, node, false);
|
|
649
754
|
onCheckerDiagnostic = oldDiagnosticHook;
|
|
650
755
|
return [type === errorType ? undefined : type, diagnostics];
|
|
651
756
|
}
|
|
@@ -702,11 +807,11 @@ export function createChecker(program, resolver) {
|
|
|
702
807
|
return false;
|
|
703
808
|
}
|
|
704
809
|
}
|
|
705
|
-
function checkTemplateInstantiationArgs(node, args, decls,
|
|
810
|
+
function checkTemplateInstantiationArgs(ctx, node, args, decls, parentMapper) {
|
|
706
811
|
const params = new Map();
|
|
707
812
|
const positional = [];
|
|
708
813
|
const initMap = new Map(decls.map((decl) => {
|
|
709
|
-
const declaredType = checkTemplateParameterDeclaration(
|
|
814
|
+
const declaredType = checkTemplateParameterDeclaration(CheckContext.DEFAULT, decl);
|
|
710
815
|
positional.push(declaredType);
|
|
711
816
|
params.set(decl.id.sv, declaredType);
|
|
712
817
|
return [
|
|
@@ -720,7 +825,7 @@ export function createChecker(program, resolver) {
|
|
|
720
825
|
let named = false;
|
|
721
826
|
for (const [arg, idx] of args.map((v, i) => [v, i])) {
|
|
722
827
|
function deferredCheck() {
|
|
723
|
-
return [arg, checkNode(arg.argument
|
|
828
|
+
return [arg, checkNode(ctx, arg.argument)];
|
|
724
829
|
}
|
|
725
830
|
if (arg.name) {
|
|
726
831
|
named = true;
|
|
@@ -780,8 +885,8 @@ export function createChecker(program, resolver) {
|
|
|
780
885
|
mapperArgs.push(type);
|
|
781
886
|
}
|
|
782
887
|
if (init === null) {
|
|
783
|
-
const argumentMapper = createTypeMapper(mapperParams, mapperArgs, { node, mapper }, parentMapper);
|
|
784
|
-
const defaultValue = getResolvedTypeParameterDefault(param, decl
|
|
888
|
+
const argumentMapper = createTypeMapper(mapperParams, mapperArgs, { node, mapper: ctx.mapper }, parentMapper);
|
|
889
|
+
const defaultValue = getResolvedTypeParameterDefault(ctx.withMapper(argumentMapper), param, decl);
|
|
785
890
|
if (defaultValue) {
|
|
786
891
|
commit(param, defaultValue);
|
|
787
892
|
}
|
|
@@ -850,8 +955,8 @@ export function createChecker(program, resolver) {
|
|
|
850
955
|
* @param instantiateTemplates If a templated type should be instantiated if not yet @default true
|
|
851
956
|
* @returns resolved type.
|
|
852
957
|
*/
|
|
853
|
-
function checkTypeReferenceSymbol(sym, node,
|
|
854
|
-
const result = checkTypeOrValueReferenceSymbol(sym, node,
|
|
958
|
+
function checkTypeReferenceSymbol(ctx, sym, node, instantiateTemplates = true) {
|
|
959
|
+
const result = checkTypeOrValueReferenceSymbol(ctx, sym, node, instantiateTemplates);
|
|
855
960
|
if (result === null || isValue(result)) {
|
|
856
961
|
reportCheckerDiagnostic(createDiagnostic({ code: "value-in-type", target: node }));
|
|
857
962
|
return errorType;
|
|
@@ -861,16 +966,17 @@ export function createChecker(program, resolver) {
|
|
|
861
966
|
}
|
|
862
967
|
return result;
|
|
863
968
|
}
|
|
864
|
-
function checkTypeOrValueReferenceSymbol(sym, node,
|
|
865
|
-
const entity = checkTypeOrValueReferenceSymbolWorker(sym, node,
|
|
969
|
+
function checkTypeOrValueReferenceSymbol(ctx, sym, node, instantiateTemplates = true) {
|
|
970
|
+
const entity = checkTypeOrValueReferenceSymbolWorker(ctx, sym, node, instantiateTemplates);
|
|
866
971
|
if (entity !== null && isType(entity) && entity.kind === "TemplateParameter") {
|
|
972
|
+
ctx.observeTemplateParameter(entity);
|
|
867
973
|
templateParameterUsageMap.set(entity.node, true);
|
|
868
974
|
}
|
|
869
975
|
return entity;
|
|
870
976
|
}
|
|
871
|
-
function checkTypeOrValueReferenceSymbolWorker(sym, node,
|
|
977
|
+
function checkTypeOrValueReferenceSymbolWorker(ctx, sym, node, instantiateTemplates = true) {
|
|
872
978
|
if (sym.flags & 131072 /* SymbolFlags.Const */) {
|
|
873
|
-
return getValueForNode(sym.declarations[0], mapper);
|
|
979
|
+
return getValueForNode(sym.declarations[0], ctx.mapper);
|
|
874
980
|
}
|
|
875
981
|
if (sym.flags & 512 /* SymbolFlags.Decorator */) {
|
|
876
982
|
reportCheckerDiagnostic(createDiagnostic({ code: "invalid-type-ref", messageId: "decorator", target: sym }));
|
|
@@ -893,6 +999,12 @@ export function createChecker(program, resolver) {
|
|
|
893
999
|
64 /* SymbolFlags.Union */)) {
|
|
894
1000
|
const decl = sym.declarations[0];
|
|
895
1001
|
if (!isTemplatedNode(decl)) {
|
|
1002
|
+
// Not a templated node, and we are moving through a typeref to a new declaration.
|
|
1003
|
+
// Therefore, we are no longer in a template declaration if we were before, and we are
|
|
1004
|
+
// visiting a new declaration, so we exit the active template observer scope, if any.
|
|
1005
|
+
const innerCtx = ctx
|
|
1006
|
+
.maskFlags(CheckFlags.InTemplateDeclaration)
|
|
1007
|
+
.exitTemplateObserverScope();
|
|
896
1008
|
if (argumentNodes.length > 0) {
|
|
897
1009
|
reportCheckerDiagnostic(createDiagnostic({
|
|
898
1010
|
code: "invalid-template-args",
|
|
@@ -908,17 +1020,26 @@ export function createChecker(program, resolver) {
|
|
|
908
1020
|
baseType = symbolLinks.declaredType;
|
|
909
1021
|
}
|
|
910
1022
|
else if (sym.flags & 65536 /* SymbolFlags.Member */) {
|
|
911
|
-
baseType = checkMemberSym(
|
|
1023
|
+
baseType = checkMemberSym(innerCtx, sym);
|
|
912
1024
|
}
|
|
913
1025
|
else {
|
|
914
|
-
|
|
1026
|
+
//
|
|
1027
|
+
baseType = checkDeclaredTypeOrIndeterminate(innerCtx, sym, decl);
|
|
915
1028
|
}
|
|
916
1029
|
}
|
|
917
1030
|
else {
|
|
918
|
-
|
|
1031
|
+
// Checking the declaration to ensure we have the template itself, so we don't need the mapper.
|
|
1032
|
+
const declaredType = getOrCheckDeclaredType(ctx.withMapper(undefined), sym, decl);
|
|
919
1033
|
const templateParameters = decl.templateParameters;
|
|
920
|
-
const
|
|
921
|
-
|
|
1034
|
+
const instantiationArgsCtx = ctx.enterTemplateObserverScope();
|
|
1035
|
+
const instantiation = checkTemplateInstantiationArgs(instantiationArgsCtx, node, argumentNodes, templateParameters, declaredType.templateMapper);
|
|
1036
|
+
// If we didn't see any template parameters during argument checking, then this type reference is "pure"
|
|
1037
|
+
// and we can mask the InTemplateDeclaration flag downstream. In either case, we are going to a new declaration
|
|
1038
|
+
// so we exit the active template observer scope, if any.
|
|
1039
|
+
const innerCtx = (instantiationArgsCtx.hasObservedTemplateParameters()
|
|
1040
|
+
? ctx
|
|
1041
|
+
: ctx.maskFlags(CheckFlags.InTemplateDeclaration)).exitTemplateObserverScope();
|
|
1042
|
+
baseType = getOrInstantiateTemplate(innerCtx, decl, [...instantiation.keys()], [...instantiation.values()], { node, mapper: ctx.mapper }, declaredType.templateMapper, instantiateTemplates);
|
|
922
1043
|
}
|
|
923
1044
|
}
|
|
924
1045
|
else {
|
|
@@ -936,7 +1057,7 @@ export function createChecker(program, resolver) {
|
|
|
936
1057
|
return sym.type;
|
|
937
1058
|
}
|
|
938
1059
|
else if (sym.flags & 1024 /* SymbolFlags.TemplateParameter */) {
|
|
939
|
-
const mapped = checkTemplateParameterDeclaration(
|
|
1060
|
+
const mapped = checkTemplateParameterDeclaration(ctx, symNode);
|
|
940
1061
|
baseType = mapped;
|
|
941
1062
|
}
|
|
942
1063
|
else if (symbolLinks.type) {
|
|
@@ -948,11 +1069,11 @@ export function createChecker(program, resolver) {
|
|
|
948
1069
|
}
|
|
949
1070
|
else {
|
|
950
1071
|
if (sym.flags & 65536 /* SymbolFlags.Member */) {
|
|
951
|
-
baseType = checkMemberSym(
|
|
1072
|
+
baseType = checkMemberSym(ctx, sym);
|
|
952
1073
|
}
|
|
953
1074
|
else {
|
|
954
1075
|
// don't have a cached type for this symbol, so go grab it and cache it
|
|
955
|
-
baseType = getTypeForNode(symNode,
|
|
1076
|
+
baseType = getTypeForNode(symNode, ctx);
|
|
956
1077
|
symbolLinks.type = baseType;
|
|
957
1078
|
}
|
|
958
1079
|
}
|
|
@@ -961,7 +1082,7 @@ export function createChecker(program, resolver) {
|
|
|
961
1082
|
// don't raise deprecation when the usage site is also a deprecated
|
|
962
1083
|
// declaration.
|
|
963
1084
|
const declarationNode = getSymNode(sym);
|
|
964
|
-
if (declarationNode && mapper === undefined && isType(baseType)) {
|
|
1085
|
+
if (declarationNode && ctx.mapper === undefined && isType(baseType)) {
|
|
965
1086
|
if (!isTypeReferenceContextDeprecated(node.parent)) {
|
|
966
1087
|
checkDeprecated(baseType, declarationNode, node);
|
|
967
1088
|
}
|
|
@@ -980,7 +1101,7 @@ export function createChecker(program, resolver) {
|
|
|
980
1101
|
* @param mapper Type mapper for template resolution
|
|
981
1102
|
* @returns The declared type for the given node.
|
|
982
1103
|
*/
|
|
983
|
-
function getOrCheckDeclaredType(sym, decl
|
|
1104
|
+
function getOrCheckDeclaredType(ctx, sym, decl) {
|
|
984
1105
|
const symbolLinks = getSymbolLinks(sym);
|
|
985
1106
|
if (symbolLinks.declaredType) {
|
|
986
1107
|
return symbolLinks.declaredType;
|
|
@@ -990,10 +1111,10 @@ export function createChecker(program, resolver) {
|
|
|
990
1111
|
return sym.type;
|
|
991
1112
|
}
|
|
992
1113
|
if (sym.flags & 65536 /* SymbolFlags.Member */) {
|
|
993
|
-
return checkMemberSym(
|
|
1114
|
+
return checkMemberSym(ctx, sym);
|
|
994
1115
|
}
|
|
995
1116
|
else {
|
|
996
|
-
return checkDeclaredType(sym, decl
|
|
1117
|
+
return checkDeclaredType(ctx, sym, decl);
|
|
997
1118
|
}
|
|
998
1119
|
}
|
|
999
1120
|
/**
|
|
@@ -1003,24 +1124,24 @@ export function createChecker(program, resolver) {
|
|
|
1003
1124
|
* @param mapper Type mapper for template resolution
|
|
1004
1125
|
* @returns The declared type for the given node.
|
|
1005
1126
|
*/
|
|
1006
|
-
function checkDeclaredTypeOrIndeterminate(sym, node
|
|
1127
|
+
function checkDeclaredTypeOrIndeterminate(ctx, sym, node) {
|
|
1007
1128
|
const type = sym.flags & 2 /* SymbolFlags.Model */
|
|
1008
|
-
? checkModelStatement(
|
|
1129
|
+
? checkModelStatement(ctx, node)
|
|
1009
1130
|
: sym.flags & 4 /* SymbolFlags.Scalar */
|
|
1010
|
-
? checkScalar(
|
|
1131
|
+
? checkScalar(ctx, node)
|
|
1011
1132
|
: sym.flags & 128 /* SymbolFlags.Alias */
|
|
1012
|
-
? checkAlias(
|
|
1133
|
+
? checkAlias(ctx, node)
|
|
1013
1134
|
: sym.flags & 32 /* SymbolFlags.Interface */
|
|
1014
|
-
? checkInterface(
|
|
1135
|
+
? checkInterface(ctx, node)
|
|
1015
1136
|
: sym.flags & 8 /* SymbolFlags.Operation */
|
|
1016
|
-
? checkOperation(
|
|
1017
|
-
: checkUnion(
|
|
1137
|
+
? checkOperation(ctx, node)
|
|
1138
|
+
: checkUnion(ctx, node);
|
|
1018
1139
|
return type;
|
|
1019
1140
|
}
|
|
1020
|
-
function checkDeclaredType(sym, node
|
|
1021
|
-
return getTypeForTypeOrIndeterminate(checkDeclaredTypeOrIndeterminate(sym, node
|
|
1141
|
+
function checkDeclaredType(ctx, sym, node) {
|
|
1142
|
+
return getTypeForTypeOrIndeterminate(checkDeclaredTypeOrIndeterminate(ctx, sym, node));
|
|
1022
1143
|
}
|
|
1023
|
-
function getOrInstantiateTemplate(templateNode, params, args, source, parentMapper, instantiateTempalates = true) {
|
|
1144
|
+
function getOrInstantiateTemplate(ctx, templateNode, params, args, source, parentMapper, instantiateTempalates = true) {
|
|
1024
1145
|
const symbolLinks = templateNode.kind === SyntaxKind.OperationStatement &&
|
|
1025
1146
|
templateNode.parent.kind === SyntaxKind.InterfaceStatement
|
|
1026
1147
|
? getSymbolLinksForMember(templateNode)
|
|
@@ -1041,7 +1162,7 @@ export function createChecker(program, resolver) {
|
|
|
1041
1162
|
return cached;
|
|
1042
1163
|
}
|
|
1043
1164
|
if (instantiateTempalates) {
|
|
1044
|
-
return instantiateTemplate(symbolLinks.instantiations, templateNode, params
|
|
1165
|
+
return instantiateTemplate(ctx.withMapper(mapper), symbolLinks.instantiations, templateNode, params);
|
|
1045
1166
|
}
|
|
1046
1167
|
else {
|
|
1047
1168
|
return errorType;
|
|
@@ -1056,10 +1177,10 @@ export function createChecker(program, resolver) {
|
|
|
1056
1177
|
* twice at the same time, or if template parameters from more than one template
|
|
1057
1178
|
* are ever in scope at once.
|
|
1058
1179
|
*/
|
|
1059
|
-
function instantiateTemplate(instantiations, templateNode, params
|
|
1060
|
-
const type = getTypeForNode(templateNode,
|
|
1061
|
-
if (!instantiations.get(mapper.args)) {
|
|
1062
|
-
instantiations.set(mapper.args, type);
|
|
1180
|
+
function instantiateTemplate(ctx, instantiations, templateNode, params) {
|
|
1181
|
+
const type = getTypeForNode(templateNode, ctx);
|
|
1182
|
+
if (!instantiations.get(ctx.mapper.args)) {
|
|
1183
|
+
instantiations.set(ctx.mapper.args, type);
|
|
1063
1184
|
}
|
|
1064
1185
|
if (type.kind === "Model") {
|
|
1065
1186
|
type.templateNode = templateNode;
|
|
@@ -1067,11 +1188,11 @@ export function createChecker(program, resolver) {
|
|
|
1067
1188
|
return type;
|
|
1068
1189
|
}
|
|
1069
1190
|
/** Check a union expresion used in a parameter constraint, those allow the use of `valueof` as a variant. */
|
|
1070
|
-
function checkMixedParameterConstraintUnion(
|
|
1191
|
+
function checkMixedParameterConstraintUnion(ctx, node) {
|
|
1071
1192
|
const values = [];
|
|
1072
1193
|
const types = [];
|
|
1073
1194
|
for (const option of node.options) {
|
|
1074
|
-
const [kind, type] = getTypeOrValueOfTypeForNode(
|
|
1195
|
+
const [kind, type] = getTypeOrValueOfTypeForNode(ctx, option);
|
|
1075
1196
|
if (kind === "value") {
|
|
1076
1197
|
values.push(type);
|
|
1077
1198
|
}
|
|
@@ -1117,7 +1238,7 @@ export function createChecker(program, resolver) {
|
|
|
1117
1238
|
}
|
|
1118
1239
|
return union;
|
|
1119
1240
|
}
|
|
1120
|
-
function checkUnionExpression(
|
|
1241
|
+
function checkUnionExpression(ctx, node) {
|
|
1121
1242
|
const unionType = createAndFinishType({
|
|
1122
1243
|
kind: "Union",
|
|
1123
1244
|
node,
|
|
@@ -1130,7 +1251,7 @@ export function createChecker(program, resolver) {
|
|
|
1130
1251
|
decorators: [],
|
|
1131
1252
|
});
|
|
1132
1253
|
for (const o of node.options) {
|
|
1133
|
-
const type = getTypeForNode(o,
|
|
1254
|
+
const type = getTypeForNode(o, ctx);
|
|
1134
1255
|
// The type `A | never` is just `A`
|
|
1135
1256
|
if (type === neverType) {
|
|
1136
1257
|
continue;
|
|
@@ -1152,7 +1273,7 @@ export function createChecker(program, resolver) {
|
|
|
1152
1273
|
unionType.variants.set(variant.name, variant);
|
|
1153
1274
|
}
|
|
1154
1275
|
}
|
|
1155
|
-
linkMapper(unionType, mapper);
|
|
1276
|
+
linkMapper(unionType, ctx.mapper);
|
|
1156
1277
|
return unionType;
|
|
1157
1278
|
}
|
|
1158
1279
|
/**
|
|
@@ -1160,17 +1281,17 @@ export function createChecker(program, resolver) {
|
|
|
1160
1281
|
* So this doesn't work if we don't have a known set of properties (e.g.
|
|
1161
1282
|
* with unions). The resulting model is anonymous.
|
|
1162
1283
|
*/
|
|
1163
|
-
function checkIntersectionExpression(
|
|
1284
|
+
function checkIntersectionExpression(ctx, node) {
|
|
1164
1285
|
const links = getSymbolLinks(node.symbol);
|
|
1165
|
-
if (links.declaredType && mapper === undefined) {
|
|
1286
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
1166
1287
|
// we're not instantiating this model and we've already checked it
|
|
1167
1288
|
return links.declaredType;
|
|
1168
1289
|
}
|
|
1169
1290
|
const intersection = initModel(node);
|
|
1170
|
-
const options = node.options.map((o) => [o, getTypeForNode(o,
|
|
1291
|
+
const options = node.options.map((o) => [o, getTypeForNode(o, ctx)]);
|
|
1171
1292
|
ensureResolved(options.map(([, type]) => type), intersection, () => {
|
|
1172
|
-
const type = mergeModelTypes(node.symbol, node, options,
|
|
1173
|
-
linkType(links, type
|
|
1293
|
+
const type = mergeModelTypes(ctx, node.symbol, node, options, intersection);
|
|
1294
|
+
linkType(ctx, links, type);
|
|
1174
1295
|
finishType(intersection);
|
|
1175
1296
|
});
|
|
1176
1297
|
return intersection;
|
|
@@ -1203,10 +1324,10 @@ export function createChecker(program, resolver) {
|
|
|
1203
1324
|
}
|
|
1204
1325
|
check();
|
|
1205
1326
|
}
|
|
1206
|
-
function checkDecoratorDeclaration(
|
|
1327
|
+
function checkDecoratorDeclaration(ctx, node) {
|
|
1207
1328
|
const symbol = getMergedSymbol(node.symbol);
|
|
1208
1329
|
const links = getSymbolLinks(symbol);
|
|
1209
|
-
if (links.declaredType && mapper === undefined) {
|
|
1330
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
1210
1331
|
// we're not instantiating this operation and we've already checked it
|
|
1211
1332
|
return links.declaredType;
|
|
1212
1333
|
}
|
|
@@ -1225,19 +1346,19 @@ export function createChecker(program, resolver) {
|
|
|
1225
1346
|
name: `@${name}`,
|
|
1226
1347
|
namespace,
|
|
1227
1348
|
node,
|
|
1228
|
-
target: checkFunctionParameter(node.target,
|
|
1229
|
-
parameters: node.parameters.map((
|
|
1349
|
+
target: checkFunctionParameter(ctx, node.target, true),
|
|
1350
|
+
parameters: node.parameters.map((param) => checkFunctionParameter(ctx, param, true)),
|
|
1230
1351
|
implementation: implementation ?? (() => { }),
|
|
1231
1352
|
});
|
|
1232
1353
|
namespace.decoratorDeclarations.set(name, decoratorType);
|
|
1233
|
-
linkType(links, decoratorType
|
|
1354
|
+
linkType(ctx, links, decoratorType);
|
|
1234
1355
|
return decoratorType;
|
|
1235
1356
|
}
|
|
1236
|
-
function checkFunctionDeclaration(
|
|
1357
|
+
function checkFunctionDeclaration(ctx, node) {
|
|
1237
1358
|
reportCheckerDiagnostic(createDiagnostic({ code: "function-unsupported", target: node }));
|
|
1238
1359
|
return errorType;
|
|
1239
1360
|
}
|
|
1240
|
-
function checkFunctionParameter(
|
|
1361
|
+
function checkFunctionParameter(ctx, node, mixed) {
|
|
1241
1362
|
const links = getSymbolLinks(node.symbol);
|
|
1242
1363
|
if (links.declaredType) {
|
|
1243
1364
|
return links.declaredType;
|
|
@@ -1260,7 +1381,7 @@ export function createChecker(program, resolver) {
|
|
|
1260
1381
|
let parameterType;
|
|
1261
1382
|
if (mixed) {
|
|
1262
1383
|
const type = node.type
|
|
1263
|
-
? getParamConstraintEntityForNode(node.type)
|
|
1384
|
+
? getParamConstraintEntityForNode(ctx, node.type)
|
|
1264
1385
|
: {
|
|
1265
1386
|
entityKind: "MixedParameterConstraint",
|
|
1266
1387
|
type: unknownType,
|
|
@@ -1280,24 +1401,24 @@ export function createChecker(program, resolver) {
|
|
|
1280
1401
|
implementation: node.symbol.value,
|
|
1281
1402
|
});
|
|
1282
1403
|
}
|
|
1283
|
-
linkType(links, parameterType
|
|
1404
|
+
linkType(ctx, links, parameterType);
|
|
1284
1405
|
return parameterType;
|
|
1285
1406
|
}
|
|
1286
|
-
function getTypeOrValueOfTypeForNode(
|
|
1407
|
+
function getTypeOrValueOfTypeForNode(ctx, node) {
|
|
1287
1408
|
switch (node.kind) {
|
|
1288
1409
|
case SyntaxKind.ValueOfExpression:
|
|
1289
|
-
const target = getTypeForNode(node.target,
|
|
1410
|
+
const target = getTypeForNode(node.target, ctx);
|
|
1290
1411
|
return ["value", target];
|
|
1291
1412
|
default:
|
|
1292
|
-
return ["type", getTypeForNode(node,
|
|
1413
|
+
return ["type", getTypeForNode(node, ctx)];
|
|
1293
1414
|
}
|
|
1294
1415
|
}
|
|
1295
|
-
function getParamConstraintEntityForNode(
|
|
1416
|
+
function getParamConstraintEntityForNode(ctx, node) {
|
|
1296
1417
|
switch (node.kind) {
|
|
1297
1418
|
case SyntaxKind.UnionExpression:
|
|
1298
|
-
return checkMixedParameterConstraintUnion(
|
|
1419
|
+
return checkMixedParameterConstraintUnion(ctx, node);
|
|
1299
1420
|
default:
|
|
1300
|
-
const [kind, entity] = getTypeOrValueOfTypeForNode(
|
|
1421
|
+
const [kind, entity] = getTypeOrValueOfTypeForNode(ctx, node);
|
|
1301
1422
|
return {
|
|
1302
1423
|
entityKind: "MixedParameterConstraint",
|
|
1303
1424
|
node: node,
|
|
@@ -1306,7 +1427,7 @@ export function createChecker(program, resolver) {
|
|
|
1306
1427
|
};
|
|
1307
1428
|
}
|
|
1308
1429
|
}
|
|
1309
|
-
function mergeModelTypes(parentModelSym, node, options,
|
|
1430
|
+
function mergeModelTypes(ctx, parentModelSym, node, options, intersection) {
|
|
1310
1431
|
const properties = intersection.properties;
|
|
1311
1432
|
const indexers = [];
|
|
1312
1433
|
const modelOptions = options.filter((entry) => {
|
|
@@ -1355,7 +1476,7 @@ export function createChecker(program, resolver) {
|
|
|
1355
1476
|
? cloneTypeForSymbol(memberSym, prop, overrides)
|
|
1356
1477
|
: cloneType(prop, overrides);
|
|
1357
1478
|
properties.set(prop.name, newPropType);
|
|
1358
|
-
linkIndirectMember(node, newPropType
|
|
1479
|
+
linkIndirectMember(ctx, node, newPropType);
|
|
1359
1480
|
for (const indexer of indexers.filter((x) => x !== option.indexer)) {
|
|
1360
1481
|
checkPropertyCompatibleWithIndexer(indexer, prop, node);
|
|
1361
1482
|
}
|
|
@@ -1367,20 +1488,24 @@ export function createChecker(program, resolver) {
|
|
|
1367
1488
|
else if (indexers.length > 1) {
|
|
1368
1489
|
intersection.indexer = {
|
|
1369
1490
|
key: indexers[0].key,
|
|
1370
|
-
value: mergeModelTypes(undefined, node, indexers.map((x) => [x.value.node, x.value]),
|
|
1491
|
+
value: mergeModelTypes(ctx, undefined, node, indexers.map((x) => [x.value.node, x.value]), initModel(node)),
|
|
1371
1492
|
};
|
|
1372
1493
|
}
|
|
1373
|
-
linkMapper(intersection, mapper);
|
|
1494
|
+
linkMapper(intersection, ctx.mapper);
|
|
1374
1495
|
return finishType(intersection);
|
|
1375
1496
|
}
|
|
1376
|
-
function checkArrayExpression(
|
|
1377
|
-
const
|
|
1497
|
+
function checkArrayExpression(ctx, node) {
|
|
1498
|
+
const elementCtx = ctx.enterTemplateObserverScope();
|
|
1499
|
+
const elementType = getTypeForNode(node.elementType, elementCtx);
|
|
1500
|
+
const instantiationCtx = elementCtx.hasObservedTemplateParameters()
|
|
1501
|
+
? ctx
|
|
1502
|
+
: ctx.maskFlags(CheckFlags.InTemplateDeclaration);
|
|
1378
1503
|
const arrayType = getStdType("Array");
|
|
1379
1504
|
const arrayNode = arrayType.node;
|
|
1380
1505
|
const param = getTypeForNode(arrayNode.templateParameters[0]);
|
|
1381
|
-
return getOrInstantiateTemplate(arrayNode, [param], [elementType], { node, mapper }, undefined);
|
|
1506
|
+
return getOrInstantiateTemplate(instantiationCtx, arrayNode, [param], [elementType], { node, mapper: ctx.mapper }, undefined);
|
|
1382
1507
|
}
|
|
1383
|
-
function checkNamespace(node) {
|
|
1508
|
+
function checkNamespace(ctx, node) {
|
|
1384
1509
|
const links = getSymbolLinks(getMergedSymbol(node.symbol));
|
|
1385
1510
|
let type = links.type;
|
|
1386
1511
|
if (!type) {
|
|
@@ -1388,10 +1513,10 @@ export function createChecker(program, resolver) {
|
|
|
1388
1513
|
}
|
|
1389
1514
|
if (node.kind === SyntaxKind.NamespaceStatement) {
|
|
1390
1515
|
if (isArray(node.statements)) {
|
|
1391
|
-
node.statements.forEach((x) => checkNode(x));
|
|
1516
|
+
node.statements.forEach((x) => checkNode(ctx, x));
|
|
1392
1517
|
}
|
|
1393
1518
|
else if (node.statements) {
|
|
1394
|
-
const subNs = checkNamespace(node.statements);
|
|
1519
|
+
const subNs = checkNamespace(ctx, node.statements);
|
|
1395
1520
|
type.namespaces.set(subNs.name, subNs);
|
|
1396
1521
|
}
|
|
1397
1522
|
}
|
|
@@ -1426,7 +1551,7 @@ export function createChecker(program, resolver) {
|
|
|
1426
1551
|
// namespaces created from TypeSpec scripts don't have decorators
|
|
1427
1552
|
if (sourceNode.kind !== SyntaxKind.NamespaceStatement)
|
|
1428
1553
|
continue;
|
|
1429
|
-
type.decorators = type.decorators.concat(checkDecorators(type, sourceNode
|
|
1554
|
+
type.decorators = type.decorators.concat(checkDecorators(CheckContext.DEFAULT, type, sourceNode));
|
|
1430
1555
|
}
|
|
1431
1556
|
finishType(type);
|
|
1432
1557
|
namespace?.namespaces.set(name, type);
|
|
@@ -1484,23 +1609,26 @@ export function createChecker(program, resolver) {
|
|
|
1484
1609
|
}
|
|
1485
1610
|
return symbolLinks.type;
|
|
1486
1611
|
}
|
|
1487
|
-
function checkOperation(
|
|
1612
|
+
function checkOperation(ctx, node, parentInterface) {
|
|
1488
1613
|
const inInterface = node.parent?.kind === SyntaxKind.InterfaceStatement;
|
|
1489
1614
|
const symbol = inInterface ? getSymbolForMember(node) : node.symbol;
|
|
1490
1615
|
const links = symbol && getSymbolLinks(symbol);
|
|
1491
1616
|
if (links) {
|
|
1492
|
-
if (links.declaredType && mapper === undefined) {
|
|
1617
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
1493
1618
|
// we're not instantiating this operation and we've already checked it
|
|
1494
1619
|
return links.declaredType;
|
|
1495
1620
|
}
|
|
1496
1621
|
}
|
|
1497
|
-
if (mapper === undefined && inInterface) {
|
|
1622
|
+
if (ctx.mapper === undefined && inInterface) {
|
|
1498
1623
|
compilerAssert(parentInterface, "Operation in interface should already have been checked.", node.parent);
|
|
1499
1624
|
}
|
|
1500
|
-
checkTemplateDeclaration(
|
|
1625
|
+
checkTemplateDeclaration(ctx, node);
|
|
1501
1626
|
// If we are instantating operation inside of interface
|
|
1502
|
-
if (isTemplatedNode(node) && mapper !== undefined && parentInterface) {
|
|
1503
|
-
|
|
1627
|
+
if (isTemplatedNode(node) && ctx.mapper !== undefined && parentInterface) {
|
|
1628
|
+
ctx = ctx.withMapper({ ...ctx.mapper, partial: true });
|
|
1629
|
+
}
|
|
1630
|
+
if ((ctx.mapper === undefined || ctx.mapper.partial) && node.templateParameters.length > 0) {
|
|
1631
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
1504
1632
|
}
|
|
1505
1633
|
const namespace = getParentNamespaceType(node);
|
|
1506
1634
|
const name = node.id.sv;
|
|
@@ -1526,21 +1654,20 @@ export function createChecker(program, resolver) {
|
|
|
1526
1654
|
interface: parentInterface,
|
|
1527
1655
|
});
|
|
1528
1656
|
if (links) {
|
|
1529
|
-
linkType(links, operationType
|
|
1657
|
+
linkType(ctx, links, operationType);
|
|
1530
1658
|
}
|
|
1531
1659
|
const parent = node.parent;
|
|
1532
1660
|
function finishOperation() {
|
|
1533
1661
|
operationType.parameters.namespace = namespace;
|
|
1534
|
-
operationType.decorators.push(...checkDecorators(operationType, node
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
return finishType(operationType, { skipDecorators: !runDecorators });
|
|
1662
|
+
operationType.decorators.push(...checkDecorators(ctx, operationType, node));
|
|
1663
|
+
return finishType(operationType, {
|
|
1664
|
+
skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
|
|
1665
|
+
});
|
|
1539
1666
|
}
|
|
1540
1667
|
// Is this a definition or reference?
|
|
1541
1668
|
if (node.signature.kind === SyntaxKind.OperationSignatureReference) {
|
|
1542
1669
|
// Attempt to resolve the operation
|
|
1543
|
-
const baseOperation = checkOperationIs(node, node.signature.baseOperation
|
|
1670
|
+
const baseOperation = checkOperationIs(ctx, node, node.signature.baseOperation);
|
|
1544
1671
|
if (baseOperation) {
|
|
1545
1672
|
ensureResolved([baseOperation], operationType, () => {
|
|
1546
1673
|
operationType.sourceOperation = baseOperation;
|
|
@@ -1570,19 +1697,19 @@ export function createChecker(program, resolver) {
|
|
|
1570
1697
|
}
|
|
1571
1698
|
}
|
|
1572
1699
|
else {
|
|
1573
|
-
operationType.parameters = getTypeForNode(node.signature.parameters,
|
|
1574
|
-
operationType.returnType = getTypeForNode(node.signature.returnType,
|
|
1700
|
+
operationType.parameters = getTypeForNode(node.signature.parameters, ctx);
|
|
1701
|
+
operationType.returnType = getTypeForNode(node.signature.returnType, ctx);
|
|
1575
1702
|
ensureResolved([operationType.parameters], operationType, () => {
|
|
1576
1703
|
finishOperation();
|
|
1577
1704
|
});
|
|
1578
1705
|
}
|
|
1579
|
-
linkMapper(operationType, mapper);
|
|
1580
|
-
if (parent.kind !== SyntaxKind.InterfaceStatement && mapper === undefined) {
|
|
1706
|
+
linkMapper(operationType, ctx.mapper);
|
|
1707
|
+
if (parent.kind !== SyntaxKind.InterfaceStatement && ctx.mapper === undefined) {
|
|
1581
1708
|
namespace?.operations.set(name, operationType);
|
|
1582
1709
|
}
|
|
1583
1710
|
return operationType;
|
|
1584
1711
|
}
|
|
1585
|
-
function checkOperationIs(operation, opReference
|
|
1712
|
+
function checkOperationIs(ctx, operation, opReference) {
|
|
1586
1713
|
if (!opReference)
|
|
1587
1714
|
return undefined;
|
|
1588
1715
|
// Ensure that we don't end up with a circular reference to the same operation
|
|
@@ -1593,7 +1720,7 @@ export function createChecker(program, resolver) {
|
|
|
1593
1720
|
const target = resolver.getNodeLinks(opReference).resolvedSymbol;
|
|
1594
1721
|
// Did we encounter a circular operation reference?
|
|
1595
1722
|
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
1596
|
-
if (mapper === undefined) {
|
|
1723
|
+
if (ctx.mapper === undefined) {
|
|
1597
1724
|
reportCheckerDiagnostic(createDiagnostic({
|
|
1598
1725
|
code: "circular-op-signature",
|
|
1599
1726
|
format: { typeName: target.name },
|
|
@@ -1603,7 +1730,7 @@ export function createChecker(program, resolver) {
|
|
|
1603
1730
|
return undefined;
|
|
1604
1731
|
}
|
|
1605
1732
|
// Resolve the base operation type
|
|
1606
|
-
const baseOperation = getTypeForNode(opReference,
|
|
1733
|
+
const baseOperation = getTypeForNode(opReference, ctx);
|
|
1607
1734
|
if (opSymId) {
|
|
1608
1735
|
pendingResolutions.finish(opSymId, ResolutionKind.BaseType);
|
|
1609
1736
|
}
|
|
@@ -1623,17 +1750,18 @@ export function createChecker(program, resolver) {
|
|
|
1623
1750
|
function getGlobalNamespaceNode() {
|
|
1624
1751
|
return resolver.symbols.global.declarations[0];
|
|
1625
1752
|
}
|
|
1626
|
-
function checkTupleExpression(
|
|
1753
|
+
function checkTupleExpression(ctx, node) {
|
|
1627
1754
|
return createAndFinishType({
|
|
1628
1755
|
kind: "Tuple",
|
|
1629
1756
|
node: node,
|
|
1630
|
-
values: node.values.map((v) => getTypeForNode(v,
|
|
1757
|
+
values: node.values.map((v) => getTypeForNode(v, ctx)),
|
|
1631
1758
|
});
|
|
1632
1759
|
}
|
|
1633
1760
|
function getSymbolLinks(s) {
|
|
1634
1761
|
return resolver.getSymbolLinks(s);
|
|
1635
1762
|
}
|
|
1636
1763
|
function resolveRelatedSymbols(id, mapper) {
|
|
1764
|
+
const ctx = CheckContext.from(mapper);
|
|
1637
1765
|
let sym;
|
|
1638
1766
|
const { node, kind } = getIdentifierContext(id);
|
|
1639
1767
|
switch (kind) {
|
|
@@ -1666,10 +1794,10 @@ export function createChecker(program, resolver) {
|
|
|
1666
1794
|
resolveDecorator = false;
|
|
1667
1795
|
}
|
|
1668
1796
|
}
|
|
1669
|
-
sym = resolveTypeReferenceSym(
|
|
1797
|
+
sym = resolveTypeReferenceSym(ctx, ref, resolveDecorator);
|
|
1670
1798
|
break;
|
|
1671
1799
|
case IdentifierKind.TemplateArgument:
|
|
1672
|
-
const templates = getTemplateDeclarationsForArgument(
|
|
1800
|
+
const templates = getTemplateDeclarationsForArgument(ctx, node);
|
|
1673
1801
|
const firstMatchingParameter = templates
|
|
1674
1802
|
.flatMap((t) => t.templateParameters)
|
|
1675
1803
|
.find((p) => p.id.sv === id.sv);
|
|
@@ -1691,14 +1819,14 @@ export function createChecker(program, resolver) {
|
|
|
1691
1819
|
}
|
|
1692
1820
|
return undefined; //sym?.symbolSource ?? sym;
|
|
1693
1821
|
}
|
|
1694
|
-
function getTemplateDeclarationsForArgument(
|
|
1822
|
+
function getTemplateDeclarationsForArgument(ctx, node) {
|
|
1695
1823
|
const ref = node.parent;
|
|
1696
|
-
let resolved = resolveTypeReferenceSym(
|
|
1824
|
+
let resolved = resolveTypeReferenceSym(ctx, ref, false);
|
|
1697
1825
|
// if the reference type can't be resolved and has parse error,
|
|
1698
1826
|
// it likely means the reference type hasn't been completed yet. i.e. Foo<string,
|
|
1699
1827
|
// so try to resolve it by it's target directly to see if we can find its sym
|
|
1700
1828
|
if (!resolved && hasParseError(ref) && ref.target !== undefined) {
|
|
1701
|
-
resolved = resolveTypeReferenceSym(ref.target,
|
|
1829
|
+
resolved = resolveTypeReferenceSym(ctx, ref.target, false);
|
|
1702
1830
|
}
|
|
1703
1831
|
return (resolved?.declarations.filter((n) => isTemplatedNode(n)) ?? []);
|
|
1704
1832
|
}
|
|
@@ -1819,9 +1947,9 @@ export function createChecker(program, resolver) {
|
|
|
1819
1947
|
node?.parent?.parent?.kind === SyntaxKind.TypeReference) {
|
|
1820
1948
|
const argNode = node.parent;
|
|
1821
1949
|
const refNode = node.parent.parent;
|
|
1822
|
-
const decl = getTemplateDeclarationsForArgument(
|
|
1950
|
+
const decl = getTemplateDeclarationsForArgument(
|
|
1823
1951
|
// We should be giving the argument so the mapper here should be undefined
|
|
1824
|
-
|
|
1952
|
+
CheckContext.DEFAULT, argNode);
|
|
1825
1953
|
const index = refNode.arguments.findIndex((n) => n === argNode);
|
|
1826
1954
|
if (decl.length > 0 && decl[0].templateParameters.length > index) {
|
|
1827
1955
|
templateParmaeterDeclNode = decl[0].templateParameters[index];
|
|
@@ -1850,7 +1978,7 @@ export function createChecker(program, resolver) {
|
|
|
1850
1978
|
if (callExpNode?.kind !== SyntaxKind.CallExpression) {
|
|
1851
1979
|
return undefined;
|
|
1852
1980
|
}
|
|
1853
|
-
const ctorType = checkCallExpressionTarget(
|
|
1981
|
+
const ctorType = checkCallExpressionTarget(CheckContext.DEFAULT, callExpNode);
|
|
1854
1982
|
if (ctorType?.kind !== "ScalarConstructor") {
|
|
1855
1983
|
return undefined;
|
|
1856
1984
|
}
|
|
@@ -1921,7 +2049,7 @@ export function createChecker(program, resolver) {
|
|
|
1921
2049
|
case IdentifierKind.Declaration:
|
|
1922
2050
|
return completions; // cannot complete, name can be chosen arbitrarily
|
|
1923
2051
|
case IdentifierKind.TemplateArgument: {
|
|
1924
|
-
const templates = getTemplateDeclarationsForArgument(
|
|
2052
|
+
const templates = getTemplateDeclarationsForArgument(CheckContext.DEFAULT, ancestor);
|
|
1925
2053
|
for (const template of templates) {
|
|
1926
2054
|
for (const param of template.templateParameters) {
|
|
1927
2055
|
addCompletion(param.id.sv, param.symbol);
|
|
@@ -1975,7 +2103,7 @@ export function createChecker(program, resolver) {
|
|
|
1975
2103
|
let base = resolver.getNodeLinks(identifier.parent.base).resolvedSymbol;
|
|
1976
2104
|
if (base) {
|
|
1977
2105
|
if (base.flags & 128 /* SymbolFlags.Alias */) {
|
|
1978
|
-
base = getAliasedSymbol(
|
|
2106
|
+
base = getAliasedSymbol(CheckContext.DEFAULT, base);
|
|
1979
2107
|
}
|
|
1980
2108
|
if (base) {
|
|
1981
2109
|
if (identifier.parent.selector === "::") {
|
|
@@ -2007,7 +2135,7 @@ export function createChecker(program, resolver) {
|
|
|
2007
2135
|
exprIsBareIdentifier(ancestor) &&
|
|
2008
2136
|
ancestor.parent?.kind === SyntaxKind.TemplateArgument &&
|
|
2009
2137
|
ancestor.parent.name === undefined) {
|
|
2010
|
-
const templates = getTemplateDeclarationsForArgument(ancestor.parent
|
|
2138
|
+
const templates = getTemplateDeclarationsForArgument(CheckContext.DEFAULT, ancestor.parent);
|
|
2011
2139
|
for (const template of templates) {
|
|
2012
2140
|
for (const param of template.templateParameters) {
|
|
2013
2141
|
addCompletion(param.id.sv, param.symbol, { suffix: " = " });
|
|
@@ -2102,34 +2230,34 @@ export function createChecker(program, resolver) {
|
|
|
2102
2230
|
return undefined;
|
|
2103
2231
|
}
|
|
2104
2232
|
}
|
|
2105
|
-
function resolveTypeReferenceSym(
|
|
2233
|
+
function resolveTypeReferenceSym(ctx, node, options) {
|
|
2106
2234
|
const resolvedOptions = typeof options === "boolean"
|
|
2107
2235
|
? { ...defaultSymbolResolutionOptions, resolveDecorators: options }
|
|
2108
2236
|
: { ...defaultSymbolResolutionOptions, ...(options ?? {}) };
|
|
2109
|
-
if (mapper === undefined &&
|
|
2237
|
+
if (ctx.mapper === undefined &&
|
|
2110
2238
|
!resolvedOptions.resolveDeclarationOfTemplate &&
|
|
2111
2239
|
referenceSymCache.has(node)) {
|
|
2112
2240
|
return referenceSymCache.get(node);
|
|
2113
2241
|
}
|
|
2114
|
-
const sym = resolveTypeReferenceSymInternal(
|
|
2242
|
+
const sym = resolveTypeReferenceSymInternal(ctx, node, resolvedOptions);
|
|
2115
2243
|
if (!resolvedOptions.resolveDeclarationOfTemplate) {
|
|
2116
2244
|
referenceSymCache.set(node, sym);
|
|
2117
2245
|
}
|
|
2118
2246
|
return sym;
|
|
2119
2247
|
}
|
|
2120
|
-
function resolveTypeReferenceSymInternal(
|
|
2248
|
+
function resolveTypeReferenceSymInternal(ctx, node, options) {
|
|
2121
2249
|
if (hasParseError(node)) {
|
|
2122
2250
|
// Don't report synthetic identifiers used for parser error recovery.
|
|
2123
2251
|
// The parse error is the root cause and will already have been logged.
|
|
2124
2252
|
return undefined;
|
|
2125
2253
|
}
|
|
2126
2254
|
if (node.kind === SyntaxKind.TypeReference) {
|
|
2127
|
-
return resolveTypeReferenceSym(node.target,
|
|
2255
|
+
return resolveTypeReferenceSym(ctx, node.target, options);
|
|
2128
2256
|
}
|
|
2129
2257
|
else if (node.kind === SyntaxKind.Identifier) {
|
|
2130
2258
|
const links = resolver.getNodeLinks(node);
|
|
2131
|
-
if (mapper === undefined && links.resolutionResult) {
|
|
2132
|
-
if (mapper === undefined && // do not report error when instantiating
|
|
2259
|
+
if (ctx.mapper === undefined && links.resolutionResult) {
|
|
2260
|
+
if (ctx.mapper === undefined && // do not report error when instantiating
|
|
2133
2261
|
links.resolutionResult & (ResolutionResultFlags.NotFound | ResolutionResultFlags.Unknown)) {
|
|
2134
2262
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2135
2263
|
code: "invalid-ref",
|
|
@@ -2147,7 +2275,7 @@ export function createChecker(program, resolver) {
|
|
|
2147
2275
|
return sym?.symbolSource ?? sym;
|
|
2148
2276
|
}
|
|
2149
2277
|
else if (node.kind === SyntaxKind.MemberExpression) {
|
|
2150
|
-
let base = resolveTypeReferenceSym(node.base,
|
|
2278
|
+
let base = resolveTypeReferenceSym(ctx, node.base, {
|
|
2151
2279
|
...options,
|
|
2152
2280
|
resolveDecorators: false, // when resolving decorator the base cannot also be one
|
|
2153
2281
|
});
|
|
@@ -2156,7 +2284,7 @@ export function createChecker(program, resolver) {
|
|
|
2156
2284
|
}
|
|
2157
2285
|
// when resolving a type reference based on an alias, unwrap the alias.
|
|
2158
2286
|
if (base.flags & 128 /* SymbolFlags.Alias */) {
|
|
2159
|
-
const aliasedSym = getAliasedSymbol(
|
|
2287
|
+
const aliasedSym = getAliasedSymbol(ctx, base);
|
|
2160
2288
|
if (!aliasedSym) {
|
|
2161
2289
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2162
2290
|
code: "invalid-ref",
|
|
@@ -2174,7 +2302,7 @@ export function createChecker(program, resolver) {
|
|
|
2174
2302
|
base = aliasedSym;
|
|
2175
2303
|
}
|
|
2176
2304
|
else if (!options.resolveDeclarationOfTemplate && isTemplatedNode(getSymNode(base))) {
|
|
2177
|
-
const baseSym = getContainerTemplateSymbol(base, node.base
|
|
2305
|
+
const baseSym = getContainerTemplateSymbol(ctx, base, node.base);
|
|
2178
2306
|
if (!baseSym) {
|
|
2179
2307
|
return undefined;
|
|
2180
2308
|
}
|
|
@@ -2270,14 +2398,14 @@ export function createChecker(program, resolver) {
|
|
|
2270
2398
|
* (i.e. they contain symbols we don't know until we've instantiated the type and the type is an
|
|
2271
2399
|
* instantiation) we late bind the container which creates the symbol that will hold its members.
|
|
2272
2400
|
*/
|
|
2273
|
-
function getAliasedSymbol(
|
|
2401
|
+
function getAliasedSymbol(ctx, aliasSymbol) {
|
|
2274
2402
|
const node = getSymNode(aliasSymbol);
|
|
2275
2403
|
const links = resolver.getSymbolLinks(aliasSymbol);
|
|
2276
2404
|
if (!links.aliasResolutionIsTemplate) {
|
|
2277
2405
|
return links.aliasedSymbol ?? resolver.getNodeLinks(node).resolvedSymbol;
|
|
2278
2406
|
}
|
|
2279
2407
|
// Otherwise for templates we need to get the type and retrieve the late bound symbol.
|
|
2280
|
-
const aliasType = getTypeForNode(node,
|
|
2408
|
+
const aliasType = getTypeForNode(node, ctx);
|
|
2281
2409
|
return lateBindContainer(aliasType, aliasSymbol);
|
|
2282
2410
|
}
|
|
2283
2411
|
/** Check case where a template type member is referenced like
|
|
@@ -2286,9 +2414,9 @@ export function createChecker(program, resolver) {
|
|
|
2286
2414
|
* model Test { t: Foo.t } // check `Foo` is correctly used as template
|
|
2287
2415
|
* ```
|
|
2288
2416
|
*/
|
|
2289
|
-
function getContainerTemplateSymbol(sym, node
|
|
2417
|
+
function getContainerTemplateSymbol(ctx, sym, node) {
|
|
2290
2418
|
if (pendingResolutions.has(sym, ResolutionKind.Type)) {
|
|
2291
|
-
if (mapper === undefined) {
|
|
2419
|
+
if (ctx.mapper === undefined) {
|
|
2292
2420
|
reportCheckerDiagnostic(createDiagnostic({
|
|
2293
2421
|
code: "circular-alias-type",
|
|
2294
2422
|
format: { typeName: sym.name },
|
|
@@ -2298,7 +2426,7 @@ export function createChecker(program, resolver) {
|
|
|
2298
2426
|
return undefined;
|
|
2299
2427
|
}
|
|
2300
2428
|
pendingResolutions.start(sym, ResolutionKind.Type);
|
|
2301
|
-
const type = checkTypeReferenceSymbol(sym, node
|
|
2429
|
+
const type = checkTypeReferenceSymbol(ctx, sym, node);
|
|
2302
2430
|
pendingResolutions.finish(sym, ResolutionKind.Type);
|
|
2303
2431
|
return lateBindContainer(type, sym);
|
|
2304
2432
|
}
|
|
@@ -2322,10 +2450,10 @@ export function createChecker(program, resolver) {
|
|
|
2322
2450
|
return getMergedSymbol(type.node.symbol) ?? sym;
|
|
2323
2451
|
}
|
|
2324
2452
|
}
|
|
2325
|
-
function checkStringTemplateExpresion(
|
|
2453
|
+
function checkStringTemplateExpresion(ctx, node) {
|
|
2326
2454
|
let hasType = false;
|
|
2327
2455
|
let hasValue = false;
|
|
2328
|
-
const spanTypeOrValues = node.spans.map((span) => [span, checkNode(span.expression
|
|
2456
|
+
const spanTypeOrValues = node.spans.map((span) => [span, checkNode(ctx, span.expression)]);
|
|
2329
2457
|
for (const [_, typeOrValue] of spanTypeOrValues) {
|
|
2330
2458
|
if (typeOrValue !== null) {
|
|
2331
2459
|
if (isValue(typeOrValue)) {
|
|
@@ -2538,7 +2666,7 @@ export function createChecker(program, resolver) {
|
|
|
2538
2666
|
}
|
|
2539
2667
|
function checkSourceFile(file) {
|
|
2540
2668
|
for (const statement of file.statements) {
|
|
2541
|
-
checkNode(statement, undefined);
|
|
2669
|
+
checkNode(CheckContext.DEFAULT, statement, undefined);
|
|
2542
2670
|
}
|
|
2543
2671
|
}
|
|
2544
2672
|
/**
|
|
@@ -2546,29 +2674,32 @@ export function createChecker(program, resolver) {
|
|
|
2546
2674
|
* @param node Node with template parameters
|
|
2547
2675
|
* @param mapper Type mapper, set if instantiating the template, undefined otherwise.
|
|
2548
2676
|
*/
|
|
2549
|
-
function checkTemplateDeclaration(
|
|
2677
|
+
function checkTemplateDeclaration(ctx, node) {
|
|
2550
2678
|
// If mapper is undefined it means we are checking the declaration of the template.
|
|
2551
|
-
if (mapper === undefined) {
|
|
2679
|
+
if (ctx.mapper === undefined) {
|
|
2552
2680
|
for (const templateParameter of node.templateParameters) {
|
|
2553
|
-
checkTemplateParameterDeclaration(
|
|
2681
|
+
checkTemplateParameterDeclaration(ctx, templateParameter);
|
|
2554
2682
|
}
|
|
2555
2683
|
}
|
|
2556
2684
|
}
|
|
2557
|
-
function checkModel(
|
|
2685
|
+
function checkModel(ctx, node) {
|
|
2558
2686
|
if (node.kind === SyntaxKind.ModelStatement) {
|
|
2559
|
-
return checkModelStatement(
|
|
2687
|
+
return checkModelStatement(ctx, node);
|
|
2560
2688
|
}
|
|
2561
2689
|
else {
|
|
2562
|
-
return checkModelExpression(
|
|
2690
|
+
return checkModelExpression(ctx, node);
|
|
2563
2691
|
}
|
|
2564
2692
|
}
|
|
2565
|
-
function checkModelStatement(
|
|
2693
|
+
function checkModelStatement(ctx, node) {
|
|
2566
2694
|
const links = getSymbolLinks(node.symbol);
|
|
2567
|
-
if (
|
|
2695
|
+
if (ctx.mapper === undefined && node.templateParameters.length > 0) {
|
|
2696
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
2697
|
+
}
|
|
2698
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
2568
2699
|
// we're not instantiating this model and we've already checked it
|
|
2569
2700
|
return links.declaredType;
|
|
2570
2701
|
}
|
|
2571
|
-
checkTemplateDeclaration(
|
|
2702
|
+
checkTemplateDeclaration(ctx, node);
|
|
2572
2703
|
const decorators = [];
|
|
2573
2704
|
const type = createType({
|
|
2574
2705
|
kind: "Model",
|
|
@@ -2580,7 +2711,7 @@ export function createChecker(program, resolver) {
|
|
|
2580
2711
|
sourceModels: [],
|
|
2581
2712
|
derivedModels: [],
|
|
2582
2713
|
});
|
|
2583
|
-
linkType(links, type
|
|
2714
|
+
linkType(ctx, links, type);
|
|
2584
2715
|
if (node.symbol.members) {
|
|
2585
2716
|
const members = resolver.getAugmentedSymbolTable(node.symbol.members);
|
|
2586
2717
|
const propDocs = extractPropDocs(node);
|
|
@@ -2591,12 +2722,12 @@ export function createChecker(program, resolver) {
|
|
|
2591
2722
|
}
|
|
2592
2723
|
}
|
|
2593
2724
|
}
|
|
2594
|
-
const isBase = checkModelIs(node, node.is
|
|
2725
|
+
const isBase = checkModelIs(ctx, node, node.is);
|
|
2595
2726
|
ensureResolved([
|
|
2596
2727
|
isBase,
|
|
2597
2728
|
...node.properties
|
|
2598
2729
|
.filter((x) => x.kind === SyntaxKind.ModelSpreadProperty)
|
|
2599
|
-
.map((x) => checkSpreadTarget(node, x.target
|
|
2730
|
+
.map((x) => checkSpreadTarget(ctx, node, x.target)),
|
|
2600
2731
|
], type, () => {
|
|
2601
2732
|
if (isBase) {
|
|
2602
2733
|
type.sourceModel = isBase;
|
|
@@ -2611,7 +2742,7 @@ export function createChecker(program, resolver) {
|
|
|
2611
2742
|
sourceProperty: prop,
|
|
2612
2743
|
model: type,
|
|
2613
2744
|
});
|
|
2614
|
-
linkIndirectMember(node, newProp
|
|
2745
|
+
linkIndirectMember(ctx, node, newProp);
|
|
2615
2746
|
type.properties.set(prop.name, newProp);
|
|
2616
2747
|
}
|
|
2617
2748
|
}
|
|
@@ -2619,7 +2750,7 @@ export function createChecker(program, resolver) {
|
|
|
2619
2750
|
type.baseModel = isBase.baseModel;
|
|
2620
2751
|
}
|
|
2621
2752
|
else if (node.extends) {
|
|
2622
|
-
type.baseModel = checkClassHeritage(node, node.extends
|
|
2753
|
+
type.baseModel = checkClassHeritage(ctx, node, node.extends);
|
|
2623
2754
|
if (type.baseModel) {
|
|
2624
2755
|
copyDeprecation(type.baseModel, type);
|
|
2625
2756
|
}
|
|
@@ -2629,14 +2760,14 @@ export function createChecker(program, resolver) {
|
|
|
2629
2760
|
}
|
|
2630
2761
|
// Hold on to the model type that's being defined so that it
|
|
2631
2762
|
// can be referenced
|
|
2632
|
-
if (mapper === undefined) {
|
|
2763
|
+
if (ctx.mapper === undefined) {
|
|
2633
2764
|
type.namespace?.models.set(type.name, type);
|
|
2634
2765
|
}
|
|
2635
2766
|
// Evaluate the properties after
|
|
2636
|
-
checkModelProperties(node, type.properties, type
|
|
2637
|
-
decorators.push(...checkDecorators(type, node
|
|
2638
|
-
linkMapper(type, mapper);
|
|
2639
|
-
finishType(type, { skipDecorators:
|
|
2767
|
+
checkModelProperties(ctx, node, type.properties, type);
|
|
2768
|
+
decorators.push(...checkDecorators(ctx, type, node));
|
|
2769
|
+
linkMapper(type, ctx.mapper);
|
|
2770
|
+
finishType(type, { skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration) });
|
|
2640
2771
|
lateBindMemberContainer(type);
|
|
2641
2772
|
lateBindMembers(type);
|
|
2642
2773
|
const indexer = getIndexer(program, type);
|
|
@@ -2652,34 +2783,21 @@ export function createChecker(program, resolver) {
|
|
|
2652
2783
|
});
|
|
2653
2784
|
return type;
|
|
2654
2785
|
}
|
|
2655
|
-
function
|
|
2656
|
-
// Node is not a template we should create the type.
|
|
2657
|
-
if (node.templateParameters.length === 0) {
|
|
2658
|
-
return true;
|
|
2659
|
-
}
|
|
2660
|
-
// There is no mapper so we shouldn't be instantiating the template.
|
|
2661
|
-
if (mapper === undefined) {
|
|
2662
|
-
return false;
|
|
2663
|
-
}
|
|
2664
|
-
// Some of the mapper args are still template parameter so we shouldn't create the type.
|
|
2665
|
-
return (!mapper.partial &&
|
|
2666
|
-
mapper.args.every((t) => isValue(t) || t.entityKind === "Indeterminate" || t.kind !== "TemplateParameter"));
|
|
2667
|
-
}
|
|
2668
|
-
function checkModelExpression(node, mapper) {
|
|
2786
|
+
function checkModelExpression(ctx, node) {
|
|
2669
2787
|
const links = getSymbolLinks(node.symbol);
|
|
2670
|
-
if (links.declaredType && mapper === undefined) {
|
|
2788
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
2671
2789
|
// we're not instantiating this model and we've already checked it
|
|
2672
2790
|
return links.declaredType;
|
|
2673
2791
|
}
|
|
2674
2792
|
const type = initModel(node);
|
|
2675
2793
|
const properties = type.properties;
|
|
2676
|
-
linkType(links, type
|
|
2677
|
-
linkMapper(type, mapper);
|
|
2794
|
+
linkType(ctx, links, type);
|
|
2795
|
+
linkMapper(type, ctx.mapper);
|
|
2678
2796
|
ensureResolved(node.properties
|
|
2679
2797
|
.filter((x) => x.kind === SyntaxKind.ModelSpreadProperty)
|
|
2680
|
-
.map((x) => checkSpreadTarget(node, x.target
|
|
2681
|
-
checkModelProperties(node, properties, type
|
|
2682
|
-
finishType(type);
|
|
2798
|
+
.map((x) => checkSpreadTarget(ctx, node, x.target)), type, () => {
|
|
2799
|
+
checkModelProperties(ctx, node, properties, type);
|
|
2800
|
+
finishType(type, { skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration) });
|
|
2683
2801
|
});
|
|
2684
2802
|
return type;
|
|
2685
2803
|
}
|
|
@@ -2721,18 +2839,18 @@ export function createChecker(program, resolver) {
|
|
|
2721
2839
|
: diagnosticTarget,
|
|
2722
2840
|
}));
|
|
2723
2841
|
}
|
|
2724
|
-
function checkModelProperties(node, properties, parentModel
|
|
2842
|
+
function checkModelProperties(ctx, node, properties, parentModel) {
|
|
2725
2843
|
let spreadIndexers;
|
|
2726
2844
|
for (const prop of node.properties) {
|
|
2727
2845
|
if ("id" in prop) {
|
|
2728
|
-
const newProp = checkModelProperty(
|
|
2846
|
+
const newProp = checkModelProperty(ctx, prop);
|
|
2729
2847
|
newProp.model = parentModel;
|
|
2730
2848
|
checkPropertyCompatibleWithModelIndexer(parentModel, newProp, prop);
|
|
2731
2849
|
defineProperty(properties, newProp);
|
|
2732
2850
|
}
|
|
2733
2851
|
else {
|
|
2734
2852
|
// spread property
|
|
2735
|
-
const [newProperties, additionalIndexer] = checkSpreadProperty(node.symbol, prop.target, parentModel
|
|
2853
|
+
const [newProperties, additionalIndexer] = checkSpreadProperty(ctx, node.symbol, prop.target, parentModel);
|
|
2736
2854
|
if (additionalIndexer) {
|
|
2737
2855
|
if (spreadIndexers) {
|
|
2738
2856
|
spreadIndexers.push(additionalIndexer);
|
|
@@ -2742,7 +2860,7 @@ export function createChecker(program, resolver) {
|
|
|
2742
2860
|
}
|
|
2743
2861
|
}
|
|
2744
2862
|
for (const newProp of newProperties) {
|
|
2745
|
-
linkIndirectMember(node, newProp
|
|
2863
|
+
linkIndirectMember(ctx, node, newProp);
|
|
2746
2864
|
checkPropertyCompatibleWithModelIndexer(parentModel, newProp, prop);
|
|
2747
2865
|
defineProperty(properties, newProp, prop);
|
|
2748
2866
|
}
|
|
@@ -2758,8 +2876,8 @@ export function createChecker(program, resolver) {
|
|
|
2758
2876
|
};
|
|
2759
2877
|
}
|
|
2760
2878
|
}
|
|
2761
|
-
function checkObjectValue(
|
|
2762
|
-
const properties = checkObjectLiteralProperties(
|
|
2879
|
+
function checkObjectValue(ctx, node, constraint) {
|
|
2880
|
+
const properties = checkObjectLiteralProperties(ctx, node);
|
|
2763
2881
|
if (properties === null) {
|
|
2764
2882
|
return null;
|
|
2765
2883
|
}
|
|
@@ -2801,12 +2919,12 @@ export function createChecker(program, resolver) {
|
|
|
2801
2919
|
decorators: [],
|
|
2802
2920
|
});
|
|
2803
2921
|
}
|
|
2804
|
-
function checkObjectLiteralProperties(
|
|
2922
|
+
function checkObjectLiteralProperties(ctx, node) {
|
|
2805
2923
|
const properties = new Map();
|
|
2806
2924
|
let hasError = false;
|
|
2807
2925
|
for (const prop of node.properties) {
|
|
2808
2926
|
if ("id" in prop) {
|
|
2809
|
-
const value = getValueForNode(prop.value, mapper);
|
|
2927
|
+
const value = getValueForNode(prop.value, ctx.mapper);
|
|
2810
2928
|
if (value === null) {
|
|
2811
2929
|
hasError = true;
|
|
2812
2930
|
}
|
|
@@ -2815,7 +2933,7 @@ export function createChecker(program, resolver) {
|
|
|
2815
2933
|
}
|
|
2816
2934
|
}
|
|
2817
2935
|
else {
|
|
2818
|
-
const targetType = checkObjectSpreadProperty(prop.target
|
|
2936
|
+
const targetType = checkObjectSpreadProperty(ctx, prop.target);
|
|
2819
2937
|
if (targetType) {
|
|
2820
2938
|
for (const [name, value] of targetType.properties) {
|
|
2821
2939
|
properties.set(name, { ...value });
|
|
@@ -2825,8 +2943,8 @@ export function createChecker(program, resolver) {
|
|
|
2825
2943
|
}
|
|
2826
2944
|
return hasError ? null : properties;
|
|
2827
2945
|
}
|
|
2828
|
-
function checkObjectSpreadProperty(
|
|
2829
|
-
const value = getValueForNode(targetNode, mapper);
|
|
2946
|
+
function checkObjectSpreadProperty(ctx, targetNode) {
|
|
2947
|
+
const value = getValueForNode(targetNode, ctx.mapper);
|
|
2830
2948
|
if (value === null) {
|
|
2831
2949
|
return null;
|
|
2832
2950
|
}
|
|
@@ -2836,10 +2954,10 @@ export function createChecker(program, resolver) {
|
|
|
2836
2954
|
}
|
|
2837
2955
|
return value;
|
|
2838
2956
|
}
|
|
2839
|
-
function checkArrayValue(
|
|
2957
|
+
function checkArrayValue(ctx, node, constraint) {
|
|
2840
2958
|
let hasError = false;
|
|
2841
2959
|
const values = node.values.map((itemNode) => {
|
|
2842
|
-
const value = getValueForNode(itemNode, mapper);
|
|
2960
|
+
const value = getValueForNode(itemNode, ctx.mapper);
|
|
2843
2961
|
if (value === null) {
|
|
2844
2962
|
hasError = true;
|
|
2845
2963
|
}
|
|
@@ -2990,8 +3108,8 @@ export function createChecker(program, resolver) {
|
|
|
2990
3108
|
value: literalType,
|
|
2991
3109
|
}, literalType);
|
|
2992
3110
|
}
|
|
2993
|
-
function checkCallExpressionTarget(
|
|
2994
|
-
const target = checkTypeReference(node.target
|
|
3111
|
+
function checkCallExpressionTarget(ctx, node) {
|
|
3112
|
+
const target = checkTypeReference(ctx, node.target);
|
|
2995
3113
|
if (target.kind === "Scalar" || target.kind === "ScalarConstructor") {
|
|
2996
3114
|
return target;
|
|
2997
3115
|
}
|
|
@@ -3032,7 +3150,7 @@ export function createChecker(program, resolver) {
|
|
|
3032
3150
|
}
|
|
3033
3151
|
return copyValue(value, { scalar, type: scalar });
|
|
3034
3152
|
}
|
|
3035
|
-
function createScalarValue(
|
|
3153
|
+
function createScalarValue(ctx, node, declaration) {
|
|
3036
3154
|
let hasError = false;
|
|
3037
3155
|
const minArgs = declaration.parameters.filter((x) => !x.optional && !x.rest).length ?? 0;
|
|
3038
3156
|
const maxArgs = declaration.parameters[declaration.parameters.length - 1]?.rest
|
|
@@ -3070,7 +3188,10 @@ export function createChecker(program, resolver) {
|
|
|
3070
3188
|
for (let i = index; i < node.arguments.length; i++) {
|
|
3071
3189
|
const argNode = node.arguments[i];
|
|
3072
3190
|
if (argNode) {
|
|
3073
|
-
const arg = getValueForNode(argNode, mapper, {
|
|
3191
|
+
const arg = getValueForNode(argNode, ctx.mapper, {
|
|
3192
|
+
kind: "argument",
|
|
3193
|
+
type: restType,
|
|
3194
|
+
});
|
|
3074
3195
|
if (arg === null) {
|
|
3075
3196
|
hasError = true;
|
|
3076
3197
|
continue;
|
|
@@ -3088,7 +3209,7 @@ export function createChecker(program, resolver) {
|
|
|
3088
3209
|
}
|
|
3089
3210
|
const argNode = node.arguments[index];
|
|
3090
3211
|
if (argNode) {
|
|
3091
|
-
const arg = getValueForNode(argNode, mapper, {
|
|
3212
|
+
const arg = getValueForNode(argNode, ctx.mapper, {
|
|
3092
3213
|
kind: "argument",
|
|
3093
3214
|
type: parameter.type,
|
|
3094
3215
|
});
|
|
@@ -3118,13 +3239,13 @@ export function createChecker(program, resolver) {
|
|
|
3118
3239
|
type: declaration.scalar,
|
|
3119
3240
|
};
|
|
3120
3241
|
}
|
|
3121
|
-
function checkCallExpression(
|
|
3122
|
-
const target = checkCallExpressionTarget(
|
|
3242
|
+
function checkCallExpression(ctx, node) {
|
|
3243
|
+
const target = checkCallExpressionTarget(ctx, node);
|
|
3123
3244
|
if (target === null) {
|
|
3124
3245
|
return null;
|
|
3125
3246
|
}
|
|
3126
3247
|
if (target.kind === "ScalarConstructor") {
|
|
3127
|
-
return createScalarValue(
|
|
3248
|
+
return createScalarValue(ctx, node, target);
|
|
3128
3249
|
}
|
|
3129
3250
|
if (relation.areScalarsRelated(target, getStdType("string"))) {
|
|
3130
3251
|
return checkPrimitiveArg(node, target, "StringValue");
|
|
@@ -3144,8 +3265,8 @@ export function createChecker(program, resolver) {
|
|
|
3144
3265
|
return null;
|
|
3145
3266
|
}
|
|
3146
3267
|
}
|
|
3147
|
-
function checkTypeOfExpression(
|
|
3148
|
-
const entity = checkNode(node.target,
|
|
3268
|
+
function checkTypeOfExpression(ctx, node) {
|
|
3269
|
+
const entity = checkNode(ctx, node.target, undefined);
|
|
3149
3270
|
if (entity === null) {
|
|
3150
3271
|
// Shouldn't need to emit error as we assume null value already emitted error when produced
|
|
3151
3272
|
return errorType;
|
|
@@ -3305,7 +3426,7 @@ export function createChecker(program, resolver) {
|
|
|
3305
3426
|
containerMembers.set(member.name, sym);
|
|
3306
3427
|
}
|
|
3307
3428
|
}
|
|
3308
|
-
function checkClassHeritage(model, heritageRef
|
|
3429
|
+
function checkClassHeritage(ctx, model, heritageRef) {
|
|
3309
3430
|
if (heritageRef.kind === SyntaxKind.ModelExpression) {
|
|
3310
3431
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3311
3432
|
code: "extend-model",
|
|
@@ -3326,7 +3447,7 @@ export function createChecker(program, resolver) {
|
|
|
3326
3447
|
pendingResolutions.start(modelSymId, ResolutionKind.BaseType);
|
|
3327
3448
|
const target = resolver.getNodeLinks(heritageRef).resolvedSymbol;
|
|
3328
3449
|
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
3329
|
-
if (mapper === undefined) {
|
|
3450
|
+
if (ctx.mapper === undefined) {
|
|
3330
3451
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3331
3452
|
code: "circular-base-type",
|
|
3332
3453
|
format: { typeName: target.name },
|
|
@@ -3335,7 +3456,7 @@ export function createChecker(program, resolver) {
|
|
|
3335
3456
|
}
|
|
3336
3457
|
return undefined;
|
|
3337
3458
|
}
|
|
3338
|
-
const heritageType = getTypeForNode(heritageRef,
|
|
3459
|
+
const heritageType = getTypeForNode(heritageRef, ctx);
|
|
3339
3460
|
pendingResolutions.finish(modelSymId, ResolutionKind.BaseType);
|
|
3340
3461
|
if (isErrorType(heritageType)) {
|
|
3341
3462
|
compilerAssert(program.hasError(), "Should already have reported an error.", heritageRef);
|
|
@@ -3354,7 +3475,7 @@ export function createChecker(program, resolver) {
|
|
|
3354
3475
|
}
|
|
3355
3476
|
return heritageType;
|
|
3356
3477
|
}
|
|
3357
|
-
function checkModelIs(model, isExpr
|
|
3478
|
+
function checkModelIs(ctx, model, isExpr) {
|
|
3358
3479
|
if (!isExpr)
|
|
3359
3480
|
return undefined;
|
|
3360
3481
|
const modelSymId = getNodeSym(model);
|
|
@@ -3369,12 +3490,12 @@ export function createChecker(program, resolver) {
|
|
|
3369
3490
|
return undefined;
|
|
3370
3491
|
}
|
|
3371
3492
|
else if (isExpr.kind === SyntaxKind.ArrayExpression) {
|
|
3372
|
-
isType = checkArrayExpression(
|
|
3493
|
+
isType = checkArrayExpression(ctx, isExpr);
|
|
3373
3494
|
}
|
|
3374
3495
|
else if (isExpr.kind === SyntaxKind.TypeReference) {
|
|
3375
3496
|
const target = resolver.getNodeLinks(isExpr).resolvedSymbol;
|
|
3376
3497
|
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
3377
|
-
if (mapper === undefined) {
|
|
3498
|
+
if (ctx.mapper === undefined) {
|
|
3378
3499
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3379
3500
|
code: "circular-base-type",
|
|
3380
3501
|
format: { typeName: target.name },
|
|
@@ -3383,7 +3504,7 @@ export function createChecker(program, resolver) {
|
|
|
3383
3504
|
}
|
|
3384
3505
|
return undefined;
|
|
3385
3506
|
}
|
|
3386
|
-
isType = getTypeForNode(isExpr,
|
|
3507
|
+
isType = getTypeForNode(isExpr, ctx);
|
|
3387
3508
|
}
|
|
3388
3509
|
else {
|
|
3389
3510
|
reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
|
|
@@ -3401,11 +3522,11 @@ export function createChecker(program, resolver) {
|
|
|
3401
3522
|
return isType;
|
|
3402
3523
|
}
|
|
3403
3524
|
/** Get the type for the spread target */
|
|
3404
|
-
function checkSpreadTarget(model, target
|
|
3525
|
+
function checkSpreadTarget(ctx, model, target) {
|
|
3405
3526
|
const modelSymId = getNodeSym(model);
|
|
3406
3527
|
const targetSym = resolver.getNodeLinks(target).resolvedSymbol;
|
|
3407
3528
|
if (targetSym === modelSymId) {
|
|
3408
|
-
if (mapper === undefined) {
|
|
3529
|
+
if (ctx.mapper === undefined) {
|
|
3409
3530
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3410
3531
|
code: "spread-model",
|
|
3411
3532
|
messageId: "selfSpread",
|
|
@@ -3414,20 +3535,20 @@ export function createChecker(program, resolver) {
|
|
|
3414
3535
|
}
|
|
3415
3536
|
return undefined;
|
|
3416
3537
|
}
|
|
3417
|
-
const type = getTypeForNode(target,
|
|
3538
|
+
const type = getTypeForNode(target, ctx);
|
|
3418
3539
|
return type;
|
|
3419
3540
|
}
|
|
3420
|
-
function checkSpreadProperty(parentModelSym, targetNode, parentModel
|
|
3421
|
-
const targetType = getTypeForNode(targetNode,
|
|
3541
|
+
function checkSpreadProperty(ctx, parentModelSym, targetNode, parentModel) {
|
|
3542
|
+
const targetType = getTypeForNode(targetNode, ctx);
|
|
3422
3543
|
if (targetType.kind === "TemplateParameter" || isErrorType(targetType)) {
|
|
3423
3544
|
return [[], undefined];
|
|
3424
3545
|
}
|
|
3425
3546
|
if (targetType.kind !== "Model") {
|
|
3426
|
-
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), mapper);
|
|
3547
|
+
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), ctx.mapper);
|
|
3427
3548
|
return [[], undefined];
|
|
3428
3549
|
}
|
|
3429
|
-
if (isArrayModelType(
|
|
3430
|
-
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), mapper);
|
|
3550
|
+
if (isArrayModelType(targetType)) {
|
|
3551
|
+
reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }), ctx.mapper);
|
|
3431
3552
|
return [[], undefined];
|
|
3432
3553
|
}
|
|
3433
3554
|
parentModel.sourceModels.push({ usage: "spread", model: targetType, node: targetNode });
|
|
@@ -3448,8 +3569,8 @@ export function createChecker(program, resolver) {
|
|
|
3448
3569
|
* @param member New Property
|
|
3449
3570
|
* @param mapper Type Mapper.
|
|
3450
3571
|
*/
|
|
3451
|
-
function linkIndirectMember(containerNode, member
|
|
3452
|
-
if (mapper !== undefined) {
|
|
3572
|
+
function linkIndirectMember(ctx, containerNode, member) {
|
|
3573
|
+
if (ctx.mapper !== undefined) {
|
|
3453
3574
|
return;
|
|
3454
3575
|
}
|
|
3455
3576
|
compilerAssert(typeof member.name === "string", "Cannot link unmapped unions");
|
|
@@ -3459,13 +3580,13 @@ export function createChecker(program, resolver) {
|
|
|
3459
3580
|
const memberSym = getMemberSymbol(containerNode.symbol, member.name);
|
|
3460
3581
|
if (memberSym) {
|
|
3461
3582
|
const links = resolver.getSymbolLinks(memberSym);
|
|
3462
|
-
linkMemberType(links, member
|
|
3583
|
+
linkMemberType(ctx, links, member);
|
|
3463
3584
|
}
|
|
3464
3585
|
}
|
|
3465
|
-
function checkModelProperty(
|
|
3586
|
+
function checkModelProperty(ctx, prop) {
|
|
3466
3587
|
const sym = getSymbolForMember(prop);
|
|
3467
3588
|
const links = getSymbolLinksForMember(prop);
|
|
3468
|
-
if (links && links.declaredType && mapper === undefined) {
|
|
3589
|
+
if (links && links.declaredType && ctx.mapper === undefined) {
|
|
3469
3590
|
return links.declaredType;
|
|
3470
3591
|
}
|
|
3471
3592
|
const name = prop.id.sv;
|
|
@@ -3477,7 +3598,7 @@ export function createChecker(program, resolver) {
|
|
|
3477
3598
|
type: undefined,
|
|
3478
3599
|
decorators: [],
|
|
3479
3600
|
});
|
|
3480
|
-
if (pendingResolutions.has(sym, ResolutionKind.Type) && mapper === undefined) {
|
|
3601
|
+
if (pendingResolutions.has(sym, ResolutionKind.Type) && ctx.mapper === undefined) {
|
|
3481
3602
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3482
3603
|
code: "circular-prop",
|
|
3483
3604
|
format: { propName: name },
|
|
@@ -3487,30 +3608,29 @@ export function createChecker(program, resolver) {
|
|
|
3487
3608
|
}
|
|
3488
3609
|
else {
|
|
3489
3610
|
pendingResolutions.start(sym, ResolutionKind.Type);
|
|
3490
|
-
type.type = getTypeForNode(prop.value,
|
|
3611
|
+
type.type = getTypeForNode(prop.value, ctx);
|
|
3491
3612
|
if (prop.default) {
|
|
3492
|
-
const defaultValue = checkDefaultValue(prop.default, type.type
|
|
3613
|
+
const defaultValue = checkDefaultValue(ctx, prop.default, type.type);
|
|
3493
3614
|
if (defaultValue !== null) {
|
|
3494
3615
|
type.defaultValue = defaultValue;
|
|
3495
3616
|
}
|
|
3496
3617
|
}
|
|
3497
3618
|
if (links) {
|
|
3498
|
-
linkType(links, type
|
|
3619
|
+
linkType(ctx, links, type);
|
|
3499
3620
|
}
|
|
3500
3621
|
}
|
|
3501
|
-
type.decorators = checkDecorators(type, prop
|
|
3622
|
+
type.decorators = checkDecorators(ctx, type, prop);
|
|
3502
3623
|
const parentTemplate = getParentTemplateNode(prop);
|
|
3503
|
-
linkMapper(type, mapper);
|
|
3504
|
-
|
|
3505
|
-
if (!parentTemplate || shouldRunDecorators
|
|
3624
|
+
linkMapper(type, ctx.mapper);
|
|
3625
|
+
const shouldRunDecorators = !ctx.hasFlags(CheckFlags.InTemplateDeclaration);
|
|
3626
|
+
if (!parentTemplate || shouldRunDecorators) {
|
|
3506
3627
|
const docComment = docFromCommentForSym.get(sym);
|
|
3507
3628
|
if (docComment) {
|
|
3508
3629
|
type.decorators.unshift(createDocFromCommentDecorator("self", docComment));
|
|
3509
3630
|
}
|
|
3510
|
-
runDecorators = true;
|
|
3511
3631
|
}
|
|
3512
3632
|
pendingResolutions.finish(sym, ResolutionKind.Type);
|
|
3513
|
-
return finishType(type, { skipDecorators: !
|
|
3633
|
+
return finishType(type, { skipDecorators: !shouldRunDecorators });
|
|
3514
3634
|
}
|
|
3515
3635
|
function createDocFromCommentDecorator(key, doc) {
|
|
3516
3636
|
return {
|
|
@@ -3521,12 +3641,12 @@ export function createChecker(program, resolver) {
|
|
|
3521
3641
|
],
|
|
3522
3642
|
};
|
|
3523
3643
|
}
|
|
3524
|
-
function checkDefaultValue(defaultNode, type
|
|
3644
|
+
function checkDefaultValue(ctx, defaultNode, type) {
|
|
3525
3645
|
if (isErrorType(type)) {
|
|
3526
3646
|
// if the prop type is an error we don't need to validate again.
|
|
3527
3647
|
return null;
|
|
3528
3648
|
}
|
|
3529
|
-
const defaultValue = getValueForNode(defaultNode, mapper, {
|
|
3649
|
+
const defaultValue = getValueForNode(defaultNode, ctx.mapper, {
|
|
3530
3650
|
kind: "assignment",
|
|
3531
3651
|
type,
|
|
3532
3652
|
});
|
|
@@ -3547,8 +3667,8 @@ export function createChecker(program, resolver) {
|
|
|
3547
3667
|
return { ...defaultValue, type };
|
|
3548
3668
|
}
|
|
3549
3669
|
}
|
|
3550
|
-
function checkDecoratorApplication(targetType, decNode
|
|
3551
|
-
const sym = resolveTypeReferenceSym(decNode.target,
|
|
3670
|
+
function checkDecoratorApplication(ctx, targetType, decNode) {
|
|
3671
|
+
const sym = resolveTypeReferenceSym(ctx.withMapper(undefined), decNode.target, true);
|
|
3552
3672
|
if (!sym) {
|
|
3553
3673
|
// Error should already have been reported above
|
|
3554
3674
|
return undefined;
|
|
@@ -3566,7 +3686,7 @@ export function createChecker(program, resolver) {
|
|
|
3566
3686
|
if (symbolLinks.declaredType === undefined) {
|
|
3567
3687
|
const decoratorDeclNode = sym.declarations.find((x) => x.kind === SyntaxKind.DecoratorDeclarationStatement);
|
|
3568
3688
|
if (decoratorDeclNode) {
|
|
3569
|
-
checkDecoratorDeclaration(
|
|
3689
|
+
checkDecoratorDeclaration(ctx.withMapper(undefined), decoratorDeclNode);
|
|
3570
3690
|
}
|
|
3571
3691
|
}
|
|
3572
3692
|
if (symbolLinks.declaredType) {
|
|
@@ -3575,7 +3695,7 @@ export function createChecker(program, resolver) {
|
|
|
3575
3695
|
hasError = true;
|
|
3576
3696
|
}
|
|
3577
3697
|
}
|
|
3578
|
-
const [argsHaveError, args] = checkDecoratorArguments(
|
|
3698
|
+
const [argsHaveError, args] = checkDecoratorArguments(ctx, decNode, symbolLinks.declaredType);
|
|
3579
3699
|
if (hasError || argsHaveError) {
|
|
3580
3700
|
return undefined;
|
|
3581
3701
|
}
|
|
@@ -3603,13 +3723,13 @@ export function createChecker(program, resolver) {
|
|
|
3603
3723
|
}
|
|
3604
3724
|
return targetValid;
|
|
3605
3725
|
}
|
|
3606
|
-
function checkDecoratorArguments(
|
|
3726
|
+
function checkDecoratorArguments(ctx, node, declaration) {
|
|
3607
3727
|
// if we don't have a declaration we can just return the types or values if
|
|
3608
3728
|
if (declaration === undefined) {
|
|
3609
3729
|
return [
|
|
3610
3730
|
false,
|
|
3611
3731
|
node.arguments.map((argNode) => {
|
|
3612
|
-
let type = checkNode(
|
|
3732
|
+
let type = checkNode(ctx, argNode) ?? errorType;
|
|
3613
3733
|
if (type.entityKind === "Indeterminate") {
|
|
3614
3734
|
type = type.type;
|
|
3615
3735
|
}
|
|
@@ -3652,7 +3772,7 @@ export function createChecker(program, resolver) {
|
|
|
3652
3772
|
}
|
|
3653
3773
|
const resolvedArgs = [];
|
|
3654
3774
|
function resolveArg(argNode, perParamType) {
|
|
3655
|
-
const arg = getTypeOrValueForNode(argNode, mapper, {
|
|
3775
|
+
const arg = getTypeOrValueForNode(argNode, ctx.mapper, {
|
|
3656
3776
|
kind: "argument",
|
|
3657
3777
|
constraint: perParamType,
|
|
3658
3778
|
});
|
|
@@ -3709,8 +3829,7 @@ export function createChecker(program, resolver) {
|
|
|
3709
3829
|
let valueType;
|
|
3710
3830
|
let type;
|
|
3711
3831
|
if (constraint.valueType) {
|
|
3712
|
-
if (constraint.valueType.kind === "Model" &&
|
|
3713
|
-
isArrayModelType(program, constraint.valueType)) {
|
|
3832
|
+
if (constraint.valueType.kind === "Model" && isArrayModelType(constraint.valueType)) {
|
|
3714
3833
|
valueType = constraint.valueType.indexer.value;
|
|
3715
3834
|
}
|
|
3716
3835
|
else {
|
|
@@ -3718,7 +3837,7 @@ export function createChecker(program, resolver) {
|
|
|
3718
3837
|
}
|
|
3719
3838
|
}
|
|
3720
3839
|
if (constraint.type) {
|
|
3721
|
-
if (constraint.type.kind === "Model" && isArrayModelType(
|
|
3840
|
+
if (constraint.type.kind === "Model" && isArrayModelType(constraint.type)) {
|
|
3722
3841
|
type = constraint.type.indexer.value;
|
|
3723
3842
|
}
|
|
3724
3843
|
else {
|
|
@@ -3759,11 +3878,11 @@ export function createChecker(program, resolver) {
|
|
|
3759
3878
|
}
|
|
3760
3879
|
return valid;
|
|
3761
3880
|
}
|
|
3762
|
-
function checkAugmentDecorators(sym, targetType
|
|
3881
|
+
function checkAugmentDecorators(ctx, sym, targetType) {
|
|
3763
3882
|
const augmentDecoratorNodes = resolver.getAugmentDecoratorsForSym(sym);
|
|
3764
3883
|
const decorators = [];
|
|
3765
3884
|
for (const decNode of augmentDecoratorNodes) {
|
|
3766
|
-
const decorator = checkDecoratorApplication(targetType, decNode
|
|
3885
|
+
const decorator = checkDecoratorApplication(ctx, targetType, decNode);
|
|
3767
3886
|
if (decorator) {
|
|
3768
3887
|
decorators.unshift(decorator);
|
|
3769
3888
|
}
|
|
@@ -3773,9 +3892,11 @@ export function createChecker(program, resolver) {
|
|
|
3773
3892
|
/**
|
|
3774
3893
|
* Check that augment decorator are targeting valid symbols.
|
|
3775
3894
|
*/
|
|
3776
|
-
function checkAugmentDecorator(node) {
|
|
3895
|
+
function checkAugmentDecorator(ctx, node) {
|
|
3777
3896
|
// This will validate the target type is pointing to a valid ref.
|
|
3778
|
-
resolveTypeReferenceSym(node.targetType,
|
|
3897
|
+
resolveTypeReferenceSym(ctx.withMapper(undefined), node.targetType, {
|
|
3898
|
+
resolveDeclarationOfTemplate: true,
|
|
3899
|
+
});
|
|
3779
3900
|
const links = resolver.getNodeLinks(node.targetType);
|
|
3780
3901
|
if (links.isTemplateInstantiation) {
|
|
3781
3902
|
program.reportDiagnostic(createDiagnostic({
|
|
@@ -3811,8 +3932,8 @@ export function createChecker(program, resolver) {
|
|
|
3811
3932
|
/**
|
|
3812
3933
|
* Check that using statements are targeting valid symbols.
|
|
3813
3934
|
*/
|
|
3814
|
-
function checkUsings(node) {
|
|
3815
|
-
const usedSym = resolveTypeReferenceSym(node.name
|
|
3935
|
+
function checkUsings(ctx, node) {
|
|
3936
|
+
const usedSym = resolveTypeReferenceSym(ctx.withMapper(undefined), node.name);
|
|
3816
3937
|
if (usedSym) {
|
|
3817
3938
|
if (~usedSym.flags & 256 /* SymbolFlags.Namespace */) {
|
|
3818
3939
|
reportCheckerDiagnostic(createDiagnostic({ code: "using-invalid-ref", target: node.name }));
|
|
@@ -3821,7 +3942,7 @@ export function createChecker(program, resolver) {
|
|
|
3821
3942
|
// If this was used to get a type this is invalid, only used for validation.
|
|
3822
3943
|
return errorType;
|
|
3823
3944
|
}
|
|
3824
|
-
function checkDecorators(targetType, node
|
|
3945
|
+
function checkDecorators(ctx, targetType, node) {
|
|
3825
3946
|
const sym = isMemberNode(node)
|
|
3826
3947
|
? (getSymbolForMember(node) ?? node.symbol)
|
|
3827
3948
|
: getMergedSymbol(node.symbol);
|
|
@@ -3832,7 +3953,7 @@ export function createChecker(program, resolver) {
|
|
|
3832
3953
|
...node.decorators,
|
|
3833
3954
|
];
|
|
3834
3955
|
for (const decNode of decoratorNodes) {
|
|
3835
|
-
const decorator = checkDecoratorApplication(targetType, decNode
|
|
3956
|
+
const decorator = checkDecoratorApplication(ctx, targetType, decNode);
|
|
3836
3957
|
if (decorator) {
|
|
3837
3958
|
decorators.unshift(decorator);
|
|
3838
3959
|
}
|
|
@@ -3855,13 +3976,17 @@ export function createChecker(program, resolver) {
|
|
|
3855
3976
|
}
|
|
3856
3977
|
return decorators;
|
|
3857
3978
|
}
|
|
3858
|
-
function checkScalar(
|
|
3979
|
+
function checkScalar(ctx, node) {
|
|
3859
3980
|
const links = getSymbolLinks(node.symbol);
|
|
3860
|
-
if (
|
|
3981
|
+
if (ctx.mapper === undefined && node.templateParameters.length > 0) {
|
|
3982
|
+
// This is a templated declaration and we are not instantiating it, so we need to update the flags.
|
|
3983
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
3984
|
+
}
|
|
3985
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
3861
3986
|
// we're not instantiating this model and we've already checked it
|
|
3862
3987
|
return links.declaredType;
|
|
3863
3988
|
}
|
|
3864
|
-
checkTemplateDeclaration(
|
|
3989
|
+
checkTemplateDeclaration(ctx, node);
|
|
3865
3990
|
const decorators = [];
|
|
3866
3991
|
const type = createType({
|
|
3867
3992
|
kind: "Scalar",
|
|
@@ -3872,31 +3997,31 @@ export function createChecker(program, resolver) {
|
|
|
3872
3997
|
decorators,
|
|
3873
3998
|
derivedScalars: [],
|
|
3874
3999
|
});
|
|
3875
|
-
linkType(links, type
|
|
4000
|
+
linkType(ctx, links, type);
|
|
3876
4001
|
if (node.extends) {
|
|
3877
|
-
type.baseScalar = checkScalarExtends(node, node.extends
|
|
4002
|
+
type.baseScalar = checkScalarExtends(ctx, node, node.extends);
|
|
3878
4003
|
if (type.baseScalar) {
|
|
3879
4004
|
copyDeprecation(type.baseScalar, type);
|
|
3880
4005
|
type.baseScalar.derivedScalars.push(type);
|
|
3881
4006
|
}
|
|
3882
4007
|
}
|
|
3883
|
-
checkScalarConstructors(type, node, type.constructors
|
|
3884
|
-
decorators.push(...checkDecorators(type, node
|
|
3885
|
-
if (mapper === undefined) {
|
|
4008
|
+
checkScalarConstructors(ctx, type, node, type.constructors);
|
|
4009
|
+
decorators.push(...checkDecorators(ctx, type, node));
|
|
4010
|
+
if (ctx.mapper === undefined) {
|
|
3886
4011
|
type.namespace?.scalars.set(type.name, type);
|
|
3887
4012
|
}
|
|
3888
|
-
linkMapper(type, mapper);
|
|
4013
|
+
linkMapper(type, ctx.mapper);
|
|
3889
4014
|
if (isInTypeSpecNamespace(type)) {
|
|
3890
4015
|
stdTypes[type.name] = type;
|
|
3891
4016
|
}
|
|
3892
|
-
return finishType(type, { skipDecorators:
|
|
4017
|
+
return finishType(type, { skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration) });
|
|
3893
4018
|
}
|
|
3894
|
-
function checkScalarExtends(scalar, extendsRef
|
|
4019
|
+
function checkScalarExtends(ctx, scalar, extendsRef) {
|
|
3895
4020
|
const symId = getNodeSym(scalar);
|
|
3896
4021
|
pendingResolutions.start(symId, ResolutionKind.BaseType);
|
|
3897
4022
|
const target = resolver.getNodeLinks(extendsRef).resolvedSymbol;
|
|
3898
4023
|
if (target && pendingResolutions.has(target, ResolutionKind.BaseType)) {
|
|
3899
|
-
if (mapper === undefined) {
|
|
4024
|
+
if (ctx.mapper === undefined) {
|
|
3900
4025
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3901
4026
|
code: "circular-base-type",
|
|
3902
4027
|
format: { typeName: target.declarations[0].id.sv },
|
|
@@ -3905,7 +4030,7 @@ export function createChecker(program, resolver) {
|
|
|
3905
4030
|
}
|
|
3906
4031
|
return undefined;
|
|
3907
4032
|
}
|
|
3908
|
-
const extendsType = getTypeForNode(extendsRef,
|
|
4033
|
+
const extendsType = getTypeForNode(extendsRef, ctx);
|
|
3909
4034
|
pendingResolutions.finish(symId, ResolutionKind.BaseType);
|
|
3910
4035
|
if (isErrorType(extendsType)) {
|
|
3911
4036
|
compilerAssert(program.hasError(), "Should already have reported an error.", extendsRef);
|
|
@@ -3917,19 +4042,19 @@ export function createChecker(program, resolver) {
|
|
|
3917
4042
|
}
|
|
3918
4043
|
return extendsType;
|
|
3919
4044
|
}
|
|
3920
|
-
function checkScalarConstructors(parentScalar, node, constructors
|
|
4045
|
+
function checkScalarConstructors(ctx, parentScalar, node, constructors) {
|
|
3921
4046
|
if (parentScalar.baseScalar) {
|
|
3922
4047
|
for (const member of parentScalar.baseScalar.constructors.values()) {
|
|
3923
4048
|
const newConstructor = cloneTypeForSymbol(getMemberSymbol(node.symbol, member.name), {
|
|
3924
4049
|
...member,
|
|
3925
4050
|
scalar: parentScalar,
|
|
3926
4051
|
});
|
|
3927
|
-
linkIndirectMember(node, newConstructor
|
|
4052
|
+
linkIndirectMember(ctx, node, newConstructor);
|
|
3928
4053
|
constructors.set(member.name, newConstructor);
|
|
3929
4054
|
}
|
|
3930
4055
|
}
|
|
3931
4056
|
for (const member of node.members) {
|
|
3932
|
-
const constructor = checkScalarConstructor(
|
|
4057
|
+
const constructor = checkScalarConstructor(ctx, member, parentScalar);
|
|
3933
4058
|
if (constructors.has(constructor.name)) {
|
|
3934
4059
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3935
4060
|
code: "constructor-duplicate",
|
|
@@ -3941,10 +4066,10 @@ export function createChecker(program, resolver) {
|
|
|
3941
4066
|
constructors.set(constructor.name, constructor);
|
|
3942
4067
|
}
|
|
3943
4068
|
}
|
|
3944
|
-
function checkScalarConstructor(
|
|
4069
|
+
function checkScalarConstructor(ctx, node, parentScalar) {
|
|
3945
4070
|
const name = node.id.sv;
|
|
3946
4071
|
const links = getSymbolLinksForMember(node);
|
|
3947
|
-
if (links && links.declaredType && mapper === undefined) {
|
|
4072
|
+
if (links && links.declaredType && ctx.mapper === undefined) {
|
|
3948
4073
|
// we're not instantiating this scalar constructor and we've already checked it
|
|
3949
4074
|
return links.declaredType;
|
|
3950
4075
|
}
|
|
@@ -3953,25 +4078,29 @@ export function createChecker(program, resolver) {
|
|
|
3953
4078
|
scalar: parentScalar,
|
|
3954
4079
|
name,
|
|
3955
4080
|
node,
|
|
3956
|
-
parameters: node.parameters.map((x) => checkFunctionParameter(
|
|
4081
|
+
parameters: node.parameters.map((x) => checkFunctionParameter(ctx, x, false)),
|
|
3957
4082
|
});
|
|
3958
|
-
linkMapper(member, mapper);
|
|
4083
|
+
linkMapper(member, ctx.mapper);
|
|
3959
4084
|
if (links) {
|
|
3960
|
-
linkType(links, member
|
|
4085
|
+
linkType(ctx, links, member);
|
|
3961
4086
|
}
|
|
3962
4087
|
return finishType(member, {
|
|
3963
|
-
skipDecorators:
|
|
4088
|
+
skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
|
|
3964
4089
|
});
|
|
3965
4090
|
}
|
|
3966
|
-
function checkAlias(
|
|
4091
|
+
function checkAlias(ctx, node) {
|
|
3967
4092
|
const links = getSymbolLinks(node.symbol);
|
|
3968
|
-
if (
|
|
4093
|
+
if (ctx.mapper === undefined && node.templateParameters.length > 0) {
|
|
4094
|
+
// This is a templated declaration and we are not instantiating it, so we need to update the flags.
|
|
4095
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
4096
|
+
}
|
|
4097
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
3969
4098
|
return links.declaredType;
|
|
3970
4099
|
}
|
|
3971
|
-
checkTemplateDeclaration(
|
|
4100
|
+
checkTemplateDeclaration(ctx, node);
|
|
3972
4101
|
const aliasSymId = getNodeSym(node);
|
|
3973
4102
|
if (pendingResolutions.has(aliasSymId, ResolutionKind.Type)) {
|
|
3974
|
-
if (mapper === undefined) {
|
|
4103
|
+
if (ctx.mapper === undefined) {
|
|
3975
4104
|
reportCheckerDiagnostic(createDiagnostic({
|
|
3976
4105
|
code: "circular-alias-type",
|
|
3977
4106
|
format: { typeName: node.id.sv },
|
|
@@ -3982,7 +4111,7 @@ export function createChecker(program, resolver) {
|
|
|
3982
4111
|
return errorType;
|
|
3983
4112
|
}
|
|
3984
4113
|
pendingResolutions.start(aliasSymId, ResolutionKind.Type);
|
|
3985
|
-
const type = checkNode(node.value
|
|
4114
|
+
const type = checkNode(ctx, node.value);
|
|
3986
4115
|
if (type === null) {
|
|
3987
4116
|
links.declaredType = errorType;
|
|
3988
4117
|
return errorType;
|
|
@@ -3992,7 +4121,7 @@ export function createChecker(program, resolver) {
|
|
|
3992
4121
|
links.declaredType = errorType;
|
|
3993
4122
|
return errorType;
|
|
3994
4123
|
}
|
|
3995
|
-
linkType(links, type
|
|
4124
|
+
linkType(ctx, links, type);
|
|
3996
4125
|
pendingResolutions.finish(aliasSymId, ResolutionKind.Type);
|
|
3997
4126
|
return type;
|
|
3998
4127
|
}
|
|
@@ -4038,7 +4167,7 @@ export function createChecker(program, resolver) {
|
|
|
4038
4167
|
return value;
|
|
4039
4168
|
}
|
|
4040
4169
|
}
|
|
4041
|
-
function checkEnum(
|
|
4170
|
+
function checkEnum(ctx, node) {
|
|
4042
4171
|
const links = getSymbolLinks(node.symbol);
|
|
4043
4172
|
if (!links.type) {
|
|
4044
4173
|
const enumType = (links.type = createType({
|
|
@@ -4051,7 +4180,7 @@ export function createChecker(program, resolver) {
|
|
|
4051
4180
|
const memberNames = new Set();
|
|
4052
4181
|
for (const member of node.members) {
|
|
4053
4182
|
if (member.kind === SyntaxKind.EnumMember) {
|
|
4054
|
-
const memberType = checkEnumMember(
|
|
4183
|
+
const memberType = checkEnumMember(ctx, member, enumType);
|
|
4055
4184
|
if (memberNames.has(memberType.name)) {
|
|
4056
4185
|
reportCheckerDiagnostic(createDiagnostic({
|
|
4057
4186
|
code: "enum-member-duplicate",
|
|
@@ -4064,9 +4193,9 @@ export function createChecker(program, resolver) {
|
|
|
4064
4193
|
enumType.members.set(memberType.name, memberType);
|
|
4065
4194
|
}
|
|
4066
4195
|
else {
|
|
4067
|
-
const members = checkEnumSpreadMember(node.symbol, enumType, member.target,
|
|
4196
|
+
const members = checkEnumSpreadMember(ctx, node.symbol, enumType, member.target, memberNames);
|
|
4068
4197
|
for (const memberType of members) {
|
|
4069
|
-
linkIndirectMember(node, memberType
|
|
4198
|
+
linkIndirectMember(ctx, node, memberType);
|
|
4070
4199
|
enumType.members.set(memberType.name, memberType);
|
|
4071
4200
|
}
|
|
4072
4201
|
}
|
|
@@ -4074,19 +4203,23 @@ export function createChecker(program, resolver) {
|
|
|
4074
4203
|
const namespace = getParentNamespaceType(node);
|
|
4075
4204
|
enumType.namespace = namespace;
|
|
4076
4205
|
enumType.namespace?.enums.set(enumType.name, enumType);
|
|
4077
|
-
enumType.decorators = checkDecorators(enumType, node
|
|
4078
|
-
linkMapper(enumType, mapper);
|
|
4206
|
+
enumType.decorators = checkDecorators(ctx, enumType, node);
|
|
4207
|
+
linkMapper(enumType, ctx.mapper);
|
|
4079
4208
|
finishType(enumType);
|
|
4080
4209
|
}
|
|
4081
4210
|
return links.type;
|
|
4082
4211
|
}
|
|
4083
|
-
function checkInterface(
|
|
4212
|
+
function checkInterface(ctx, node) {
|
|
4084
4213
|
const links = getSymbolLinks(node.symbol);
|
|
4085
|
-
if (
|
|
4214
|
+
if (ctx.mapper === undefined && node.templateParameters.length > 0) {
|
|
4215
|
+
// This is a templated declaration and we are not instantiating it, so we need to update the flags.
|
|
4216
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
4217
|
+
}
|
|
4218
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
4086
4219
|
// we're not instantiating this interface and we've already checked it
|
|
4087
4220
|
return links.declaredType;
|
|
4088
4221
|
}
|
|
4089
|
-
checkTemplateDeclaration(
|
|
4222
|
+
checkTemplateDeclaration(ctx, node);
|
|
4090
4223
|
const interfaceType = createType({
|
|
4091
4224
|
kind: "Interface",
|
|
4092
4225
|
decorators: [],
|
|
@@ -4096,11 +4229,11 @@ export function createChecker(program, resolver) {
|
|
|
4096
4229
|
operations: createRekeyableMap(),
|
|
4097
4230
|
name: node.id.sv,
|
|
4098
4231
|
});
|
|
4099
|
-
linkType(links, interfaceType
|
|
4100
|
-
interfaceType.decorators = checkDecorators(interfaceType, node
|
|
4101
|
-
const ownMembers = checkInterfaceMembers(
|
|
4232
|
+
linkType(ctx, links, interfaceType);
|
|
4233
|
+
interfaceType.decorators = checkDecorators(ctx, interfaceType, node);
|
|
4234
|
+
const ownMembers = checkInterfaceMembers(ctx, node, interfaceType);
|
|
4102
4235
|
for (const extendsNode of node.extends) {
|
|
4103
|
-
const extendsType = getTypeForNode(extendsNode,
|
|
4236
|
+
const extendsType = getTypeForNode(extendsNode, ctx);
|
|
4104
4237
|
if (extendsType.kind !== "Interface") {
|
|
4105
4238
|
reportCheckerDiagnostic(createDiagnostic({ code: "extends-interface", target: extendsNode }));
|
|
4106
4239
|
continue;
|
|
@@ -4118,7 +4251,7 @@ export function createChecker(program, resolver) {
|
|
|
4118
4251
|
});
|
|
4119
4252
|
// Don't link it it is overritten
|
|
4120
4253
|
if (!ownMembers.has(member.name)) {
|
|
4121
|
-
linkIndirectMember(node, newMember
|
|
4254
|
+
linkIndirectMember(ctx, node, newMember);
|
|
4122
4255
|
}
|
|
4123
4256
|
// Clone deprecation information
|
|
4124
4257
|
copyDeprecation(member, newMember);
|
|
@@ -4129,17 +4262,17 @@ export function createChecker(program, resolver) {
|
|
|
4129
4262
|
for (const [key, value] of ownMembers) {
|
|
4130
4263
|
interfaceType.operations.set(key, value);
|
|
4131
4264
|
}
|
|
4132
|
-
linkMapper(interfaceType, mapper);
|
|
4133
|
-
if (mapper === undefined) {
|
|
4265
|
+
linkMapper(interfaceType, ctx.mapper);
|
|
4266
|
+
if (ctx.mapper === undefined) {
|
|
4134
4267
|
interfaceType.namespace?.interfaces.set(interfaceType.name, interfaceType);
|
|
4135
4268
|
}
|
|
4136
4269
|
lateBindMemberContainer(interfaceType);
|
|
4137
4270
|
lateBindMembers(interfaceType);
|
|
4138
4271
|
return finishType(interfaceType, {
|
|
4139
|
-
skipDecorators:
|
|
4272
|
+
skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
|
|
4140
4273
|
});
|
|
4141
4274
|
}
|
|
4142
|
-
function checkInterfaceMembers(
|
|
4275
|
+
function checkInterfaceMembers(ctx, node, interfaceType) {
|
|
4143
4276
|
const ownMembers = new Map();
|
|
4144
4277
|
// Preregister each operation sym links instantiation to make sure there is no race condition when instantiating templated interface
|
|
4145
4278
|
for (const opNode of node.operations) {
|
|
@@ -4150,7 +4283,7 @@ export function createChecker(program, resolver) {
|
|
|
4150
4283
|
}
|
|
4151
4284
|
}
|
|
4152
4285
|
for (const opNode of node.operations) {
|
|
4153
|
-
const opType = checkOperation(
|
|
4286
|
+
const opType = checkOperation(ctx, opNode, interfaceType);
|
|
4154
4287
|
if (ownMembers.has(opType.name)) {
|
|
4155
4288
|
reportCheckerDiagnostic(createDiagnostic({
|
|
4156
4289
|
code: "interface-duplicate",
|
|
@@ -4163,13 +4296,16 @@ export function createChecker(program, resolver) {
|
|
|
4163
4296
|
}
|
|
4164
4297
|
return ownMembers;
|
|
4165
4298
|
}
|
|
4166
|
-
function checkUnion(
|
|
4299
|
+
function checkUnion(ctx, node) {
|
|
4167
4300
|
const links = getSymbolLinks(node.symbol);
|
|
4168
|
-
if (
|
|
4301
|
+
if (ctx.mapper === undefined && node.templateParameters.length > 0) {
|
|
4302
|
+
ctx = ctx.withFlags(CheckFlags.InTemplateDeclaration);
|
|
4303
|
+
}
|
|
4304
|
+
if (links.declaredType && ctx.mapper === undefined) {
|
|
4169
4305
|
// we're not instantiating this union and we've already checked it
|
|
4170
4306
|
return links.declaredType;
|
|
4171
4307
|
}
|
|
4172
|
-
checkTemplateDeclaration(
|
|
4308
|
+
checkTemplateDeclaration(ctx, node);
|
|
4173
4309
|
const variants = createRekeyableMap();
|
|
4174
4310
|
const unionType = createType({
|
|
4175
4311
|
kind: "Union",
|
|
@@ -4183,20 +4319,22 @@ export function createChecker(program, resolver) {
|
|
|
4183
4319
|
},
|
|
4184
4320
|
expression: false,
|
|
4185
4321
|
});
|
|
4186
|
-
linkType(links, unionType
|
|
4187
|
-
unionType.decorators = checkDecorators(unionType, node
|
|
4188
|
-
checkUnionVariants(unionType, node, variants
|
|
4189
|
-
linkMapper(unionType, mapper);
|
|
4190
|
-
if (mapper === undefined) {
|
|
4322
|
+
linkType(ctx, links, unionType);
|
|
4323
|
+
unionType.decorators = checkDecorators(ctx, unionType, node);
|
|
4324
|
+
checkUnionVariants(ctx, unionType, node, variants);
|
|
4325
|
+
linkMapper(unionType, ctx.mapper);
|
|
4326
|
+
if (ctx.mapper === undefined) {
|
|
4191
4327
|
unionType.namespace?.unions.set(unionType.name, unionType);
|
|
4192
4328
|
}
|
|
4193
4329
|
lateBindMemberContainer(unionType);
|
|
4194
4330
|
lateBindMembers(unionType);
|
|
4195
|
-
return finishType(unionType, {
|
|
4331
|
+
return finishType(unionType, {
|
|
4332
|
+
skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
|
|
4333
|
+
});
|
|
4196
4334
|
}
|
|
4197
|
-
function checkUnionVariants(parentUnion, node, variants
|
|
4335
|
+
function checkUnionVariants(ctx, parentUnion, node, variants) {
|
|
4198
4336
|
for (const variantNode of node.options) {
|
|
4199
|
-
const variantType = checkUnionVariant(
|
|
4337
|
+
const variantType = checkUnionVariant(ctx, variantNode);
|
|
4200
4338
|
variantType.union = parentUnion;
|
|
4201
4339
|
if (variants.has(variantType.name)) {
|
|
4202
4340
|
reportCheckerDiagnostic(createDiagnostic({
|
|
@@ -4209,14 +4347,14 @@ export function createChecker(program, resolver) {
|
|
|
4209
4347
|
variants.set(variantType.name, variantType);
|
|
4210
4348
|
}
|
|
4211
4349
|
}
|
|
4212
|
-
function checkUnionVariant(
|
|
4350
|
+
function checkUnionVariant(ctx, variantNode) {
|
|
4213
4351
|
const links = getSymbolLinksForMember(variantNode);
|
|
4214
|
-
if (links && links.declaredType && mapper === undefined) {
|
|
4352
|
+
if (links && links.declaredType && ctx.mapper === undefined) {
|
|
4215
4353
|
// we're not instantiating this union variant and we've already checked it
|
|
4216
4354
|
return links.declaredType;
|
|
4217
4355
|
}
|
|
4218
4356
|
const name = variantNode.id ? variantNode.id.sv : Symbol("name");
|
|
4219
|
-
const type = getTypeForNode(variantNode.value,
|
|
4357
|
+
const type = getTypeForNode(variantNode.value, ctx);
|
|
4220
4358
|
const variantType = createType({
|
|
4221
4359
|
kind: "UnionVariant",
|
|
4222
4360
|
name,
|
|
@@ -4225,13 +4363,13 @@ export function createChecker(program, resolver) {
|
|
|
4225
4363
|
type,
|
|
4226
4364
|
union: undefined,
|
|
4227
4365
|
});
|
|
4228
|
-
variantType.decorators = checkDecorators(variantType, variantNode
|
|
4229
|
-
linkMapper(variantType, mapper);
|
|
4366
|
+
variantType.decorators = checkDecorators(ctx, variantType, variantNode);
|
|
4367
|
+
linkMapper(variantType, ctx.mapper);
|
|
4230
4368
|
if (links) {
|
|
4231
|
-
linkType(links, variantType
|
|
4369
|
+
linkType(ctx, links, variantType);
|
|
4232
4370
|
}
|
|
4233
4371
|
return finishType(variantType, {
|
|
4234
|
-
skipDecorators:
|
|
4372
|
+
skipDecorators: ctx.hasFlags(CheckFlags.InTemplateDeclaration),
|
|
4235
4373
|
});
|
|
4236
4374
|
}
|
|
4237
4375
|
function isMemberNode(node) {
|
|
@@ -4252,7 +4390,7 @@ export function createChecker(program, resolver) {
|
|
|
4252
4390
|
const sym = getSymbolForMember(node);
|
|
4253
4391
|
return sym ? (getSymNode(sym) === node ? getSymbolLinks(sym) : undefined) : undefined;
|
|
4254
4392
|
}
|
|
4255
|
-
function checkEnumMember(
|
|
4393
|
+
function checkEnumMember(ctx, node, parentEnum) {
|
|
4256
4394
|
const name = node.id.sv;
|
|
4257
4395
|
const links = getSymbolLinksForMember(node);
|
|
4258
4396
|
if (links?.type) {
|
|
@@ -4271,12 +4409,12 @@ export function createChecker(program, resolver) {
|
|
|
4271
4409
|
if (links) {
|
|
4272
4410
|
links.type = member;
|
|
4273
4411
|
}
|
|
4274
|
-
member.decorators = checkDecorators(member, node
|
|
4412
|
+
member.decorators = checkDecorators(ctx, member, node);
|
|
4275
4413
|
return finishType(member);
|
|
4276
4414
|
}
|
|
4277
|
-
function checkEnumSpreadMember(parentEnumSym, parentEnum, targetNode,
|
|
4415
|
+
function checkEnumSpreadMember(ctx, parentEnumSym, parentEnum, targetNode, existingMemberNames) {
|
|
4278
4416
|
const members = [];
|
|
4279
|
-
const targetType = getTypeForNode(targetNode,
|
|
4417
|
+
const targetType = getTypeForNode(targetNode, ctx);
|
|
4280
4418
|
if (!isErrorType(targetType)) {
|
|
4281
4419
|
if (targetType.kind !== "Enum") {
|
|
4282
4420
|
reportCheckerDiagnostic(createDiagnostic({ code: "spread-enum", target: targetNode }));
|
|
@@ -4446,7 +4584,7 @@ export function createChecker(program, resolver) {
|
|
|
4446
4584
|
decorators: [],
|
|
4447
4585
|
});
|
|
4448
4586
|
getSymbolLinks(sym).type = type;
|
|
4449
|
-
type.decorators = checkAugmentDecorators(sym, type
|
|
4587
|
+
type.decorators = checkAugmentDecorators(CheckContext.DEFAULT, sym, type);
|
|
4450
4588
|
return finishType(type);
|
|
4451
4589
|
}
|
|
4452
4590
|
function initializeClone(type, additionalProps) {
|
|
@@ -4559,7 +4697,7 @@ export function createChecker(program, resolver) {
|
|
|
4559
4697
|
if (docComment) {
|
|
4560
4698
|
clone.decorators.push(createDocFromCommentDecorator("self", docComment));
|
|
4561
4699
|
}
|
|
4562
|
-
for (const dec of checkAugmentDecorators(sym, clone
|
|
4700
|
+
for (const dec of checkAugmentDecorators(CheckContext.DEFAULT, sym, clone)) {
|
|
4563
4701
|
clone.decorators.push(dec);
|
|
4564
4702
|
}
|
|
4565
4703
|
}
|