@typespec/compiler 0.62.0-dev.8 → 0.62.0

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