tsc-ts 0.0.6 → 0.0.7

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 (71) hide show
  1. package/dist/api/compiler/ast.d.ts +57 -18
  2. package/dist/api/compiler/ast.js +134 -39
  3. package/dist/api/compiler/binder-utilities.js +2 -2
  4. package/dist/api/compiler/binder.js +6 -6
  5. package/dist/api/compiler/checker-calls.js +4 -4
  6. package/dist/api/compiler/checker-contextual.js +1 -1
  7. package/dist/api/compiler/checker-emit-helpers.d.ts +2 -1
  8. package/dist/api/compiler/checker-emit-helpers.js +5 -4
  9. package/dist/api/compiler/checker-grammar.js +5 -5
  10. package/dist/api/compiler/checker-inference.d.ts +20 -10
  11. package/dist/api/compiler/checker-inference.js +48 -25
  12. package/dist/api/compiler/checker-members.d.ts +27 -0
  13. package/dist/api/compiler/checker-members.js +165 -0
  14. package/dist/api/compiler/checker-modules.d.ts +14 -0
  15. package/dist/api/compiler/checker-modules.js +73 -1
  16. package/dist/api/compiler/checker.d.ts +16 -0
  17. package/dist/api/compiler/checker.js +17 -0
  18. package/dist/api/compiler/diagnostics.js +9 -5
  19. package/dist/api/compiler/parallel-parse.js +3 -1
  20. package/dist/api/compiler/parser.js +33 -23
  21. package/dist/api/compiler/printer/factory-base.js +8 -8
  22. package/dist/api/compiler/printer/factory.js +4 -4
  23. package/dist/api/compiler/printer/printer.js +6 -6
  24. package/dist/api/compiler/program-checker.d.ts +5 -0
  25. package/dist/api/compiler/program-checker.js +11 -1
  26. package/dist/api/compiler/relations.js +8 -3
  27. package/dist/api/compiler/reparser.js +13 -5
  28. package/dist/api/compiler/transformers/class-fields.js +3 -3
  29. package/dist/api/compiler/transformers/commonjs-module.js +3 -3
  30. package/dist/api/compiler/transformers/declarations-pseudo.js +2 -2
  31. package/dist/api/compiler/transformers/module.js +2 -2
  32. package/dist/api/compiler/transformers/optional-chain.js +3 -3
  33. package/dist/api/compiler/transformers/subtree-facts.js +2 -2
  34. package/dist/api/compiler/transformers/tagged-template.js +2 -2
  35. package/dist/api/compiler/transformers/type-eraser.js +2 -2
  36. package/dist/api/compiler/transformers/visitor-base.js +3 -3
  37. package/dist/api/compiler/tsconfig.js +2 -2
  38. package/package.json +8 -8
  39. package/src/compiler/ast.ts +184 -59
  40. package/src/compiler/binder-utilities.ts +2 -1
  41. package/src/compiler/binder.ts +11 -5
  42. package/src/compiler/checker-calls.ts +5 -3
  43. package/src/compiler/checker-contextual.ts +1 -1
  44. package/src/compiler/checker-emit-helpers.ts +5 -4
  45. package/src/compiler/checker-grammar.ts +5 -3
  46. package/src/compiler/checker-inference.ts +49 -25
  47. package/src/compiler/checker-members.ts +164 -0
  48. package/src/compiler/checker-modules.ts +92 -1
  49. package/src/compiler/checker.ts +19 -0
  50. package/src/compiler/decoder.ts +5 -4
  51. package/src/compiler/diagnostics.ts +10 -5
  52. package/src/compiler/encoder.ts +10 -5
  53. package/src/compiler/parallel-parse.ts +3 -1
  54. package/src/compiler/parser.ts +53 -23
  55. package/src/compiler/printer/factory-base.ts +14 -7
  56. package/src/compiler/printer/factory.ts +5 -3
  57. package/src/compiler/printer/printer.ts +8 -6
  58. package/src/compiler/program-checker.ts +10 -1
  59. package/src/compiler/relations.ts +10 -2
  60. package/src/compiler/reparser.ts +14 -4
  61. package/src/compiler/transformers/class-fields.ts +12 -2
  62. package/src/compiler/transformers/commonjs-module.ts +3 -2
  63. package/src/compiler/transformers/declarations-pseudo.ts +2 -1
  64. package/src/compiler/transformers/declarations.ts +1 -1
  65. package/src/compiler/transformers/module.ts +2 -1
  66. package/src/compiler/transformers/optional-chain.ts +5 -2
  67. package/src/compiler/transformers/subtree-facts.ts +2 -1
  68. package/src/compiler/transformers/tagged-template.ts +2 -2
  69. package/src/compiler/transformers/type-eraser.ts +2 -1
  70. package/src/compiler/transformers/visitor-base.ts +10 -5
  71. package/src/compiler/tsconfig.ts +2 -1
@@ -56,28 +56,38 @@ export declare class IntraExpressionInferenceSite {
56
56
  readonly type: Type;
57
57
  constructor(node: Node, type: Type);
58
58
  }
59
- export declare class InferenceContext {
59
+ /**
60
+ * The inferences for a set of type parameters. The context is its own fixing mapper (`mapper`), and
61
+ * each read of `nonFixingMapper` returns a new mapper that reads the context: no mapper the context
62
+ * holds refers back to it, so a context whose inference is done is freed by reference counting
63
+ * rather than by the cycle collector.
64
+ */
65
+ export declare class InferenceContext extends TypeMapper {
66
+ readonly c: Checker;
60
67
  inferences: InferenceInfo[];
61
68
  /** The generic signature inferences are made for, if any. */
62
69
  readonly signature: Signature | undefined;
63
70
  flags: InferenceFlags;
64
71
  readonly compareTypes: TypeComparer;
65
- /** Fixes inferences. */
66
- mapper: TypeMapper;
67
- nonFixingMapper: TypeMapper;
72
+ /** Combined after the non-fixing mapper (conditional types' `infer` constraints), if any. */
73
+ nonFixingOuter: TypeMapper | undefined;
68
74
  /** Maps to inferences from the return type, if any. */
69
75
  returnMapper: TypeMapper | undefined;
70
76
  outerReturnMapper: TypeMapper | undefined;
71
77
  inferredTypeParameters: Type[] | undefined;
72
- intraExpressionInferenceSites: IntraExpressionInferenceSite[];
78
+ /** Created on the first site; most contexts get none. */
79
+ intraExpressionInferenceSites: IntraExpressionInferenceSite[] | undefined;
73
80
  constructor(c: Checker, inferences: InferenceInfo[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer);
81
+ /** Fixes inferences. */
82
+ get mapper(): TypeMapper;
83
+ /** Maps to the current inferences without fixing them. */
84
+ get nonFixingMapper(): TypeMapper;
85
+ map(type: Type): Type;
74
86
  }
75
- /** Maps a context's type parameters to their inferred types, optionally fixing them. */
76
- export declare class InferenceTypeMapper extends TypeMapper {
77
- readonly c: Checker;
87
+ /** Maps a context's type parameters to their inferred types without fixing them. */
88
+ export declare class NonFixingInferenceMapper extends TypeMapper {
78
89
  readonly context: InferenceContext;
79
- readonly fixing: boolean;
80
- constructor(c: Checker, context: InferenceContext, fixing: boolean);
90
+ constructor(context: InferenceContext);
81
91
  map(type: Type): Type;
82
92
  }
83
93
  export declare function createInferenceContext(c: Checker, typeParameters: readonly Type[], signature: Signature | undefined, flags: InferenceFlags, compareTypes: TypeComparer | undefined): InferenceContext;
@@ -61,57 +61,78 @@ export class IntraExpressionInferenceSite {
61
61
  this.type = type;
62
62
  }
63
63
  }
64
- export class InferenceContext {
64
+ /**
65
+ * The inferences for a set of type parameters. The context is its own fixing mapper (`mapper`), and
66
+ * each read of `nonFixingMapper` returns a new mapper that reads the context: no mapper the context
67
+ * holds refers back to it, so a context whose inference is done is freed by reference counting
68
+ * rather than by the cycle collector.
69
+ */
70
+ export class InferenceContext extends TypeMapper {
71
+ c;
65
72
  inferences;
66
73
  /** The generic signature inferences are made for, if any. */
67
74
  signature;
68
75
  flags;
69
76
  compareTypes;
70
- /** Fixes inferences. */
71
- mapper;
72
- nonFixingMapper;
77
+ /** Combined after the non-fixing mapper (conditional types' `infer` constraints), if any. */
78
+ nonFixingOuter = undefined;
73
79
  /** Maps to inferences from the return type, if any. */
74
80
  returnMapper = undefined;
75
81
  outerReturnMapper = undefined;
76
82
  inferredTypeParameters = undefined;
77
- intraExpressionInferenceSites = [];
83
+ /** Created on the first site; most contexts get none. */
84
+ intraExpressionInferenceSites = undefined;
78
85
  constructor(c, inferences, signature, flags, compareTypes) {
86
+ super();
87
+ this.c = c;
79
88
  this.inferences = inferences;
80
89
  this.signature = signature;
81
90
  this.flags = flags;
82
91
  this.compareTypes = compareTypes;
83
- this.mapper = new InferenceTypeMapper(c, this, true);
84
- this.nonFixingMapper = new InferenceTypeMapper(c, this, false);
85
92
  }
86
- }
87
- /** Maps a context's type parameters to their inferred types, optionally fixing them. */
88
- export class InferenceTypeMapper extends TypeMapper {
89
- c;
90
- context;
91
- fixing;
92
- constructor(c, context, fixing) {
93
- super();
94
- this.c = c;
95
- this.context = context;
96
- this.fixing = fixing;
93
+ /** Fixes inferences. */
94
+ get mapper() {
95
+ return this;
96
+ }
97
+ /** Maps to the current inferences without fixing them. */
98
+ get nonFixingMapper() {
99
+ const mapper = new NonFixingInferenceMapper(this);
100
+ const outer = this.nonFixingOuter;
101
+ return outer !== undefined ? combineTypeMappers(this.c, mapper, outer) : mapper;
97
102
  }
98
103
  map(type) {
99
- const inferences = this.context.inferences;
104
+ const inferences = this.inferences;
100
105
  for (let i = 0; i < inferences.length; i++) {
101
106
  const inference = inferences[i];
102
107
  if (type !== inference.typeParameter)
103
108
  continue;
104
- if (this.fixing && !inference.isFixed) {
109
+ if (!inference.isFixed) {
105
110
  // Infer from intra-expression sites before committing to an inference.
106
- inferFromIntraExpressionSites(this.c, this.context);
111
+ inferFromIntraExpressionSites(this.c, this);
107
112
  clearCachedInferences(inferences);
108
113
  inference.isFixed = true;
109
114
  }
110
- return getInferredType(this.c, this.context, i);
115
+ return getInferredType(this.c, this, i);
111
116
  }
112
117
  return type;
113
118
  }
114
119
  }
120
+ /** Maps a context's type parameters to their inferred types without fixing them. */
121
+ export class NonFixingInferenceMapper extends TypeMapper {
122
+ context;
123
+ constructor(context) {
124
+ super();
125
+ this.context = context;
126
+ }
127
+ map(type) {
128
+ const context = this.context;
129
+ const inferences = context.inferences;
130
+ for (let i = 0; i < inferences.length; i++)
131
+ if (type === inferences[i].typeParameter)
132
+ return getInferredType(context.c, context, i);
133
+ return type;
134
+ }
135
+ }
115
136
  export function createInferenceContext(c, typeParameters, signature, flags, compareTypes) {
116
137
  const inferences = [];
117
138
  for (const tp of typeParameters)
@@ -144,7 +165,7 @@ export function createOuterReturnMapper(c, context) {
144
165
  return context.outerReturnMapper;
145
166
  }
146
167
  export function addIntraExpressionInferenceSite(context, node, type) {
147
- context.intraExpressionInferenceSites.push(new IntraExpressionInferenceSite(node, type));
168
+ (context.intraExpressionInferenceSites ??= []).push(new IntraExpressionInferenceSite(node, type));
148
169
  }
149
170
  export function clearCachedInferences(inferences) {
150
171
  for (const inference of inferences)
@@ -1678,7 +1699,9 @@ export function instantiateReverseMappedType(c, t, mapper) {
1678
1699
  /** Infers early from intra-expression sites (context-sensitive elements of object and array literals). */
1679
1700
  export function inferFromIntraExpressionSites(c, context) {
1680
1701
  const sites = context.intraExpressionInferenceSites;
1681
- context.intraExpressionInferenceSites = [];
1702
+ if (sites === undefined)
1703
+ return;
1704
+ context.intraExpressionInferenceSites = undefined;
1682
1705
  for (const site of sites) {
1683
1706
  const contextualType = getContextualTypeForInference(c, site.node);
1684
1707
  if (contextualType !== undefined)
@@ -1940,7 +1963,7 @@ export function inferTypesForConditional(c, root, checkType, extendsType, mapper
1940
1963
  // so the non-fixing mapper combines with `mapper`.
1941
1964
  const context = createInferenceContext(c, root.inferTypeParameters, undefined, 0 /* InferenceFlags.None */, undefined);
1942
1965
  if (mapper !== undefined)
1943
- context.nonFixingMapper = combineTypeMappers(c, context.nonFixingMapper, mapper);
1966
+ context.nonFixingOuter = mapper;
1944
1967
  // Inferences from constraints could eagerly resolve what should defer; contravariance is always strict.
1945
1968
  if (!checkTypeDeferred)
1946
1969
  inferTypes(c, context.inferences, checkType, extendsType, 512 /* InferencePriority.NoConstraints */ | 1024 /* InferencePriority.AlwaysStrict */, false);
@@ -142,6 +142,33 @@ export declare function getPropertyOfType(c: Checker, t: Type, name: string): Sy
142
142
  * primitives and type parameters, and falls back to Object and Function members.
143
143
  */
144
144
  export declare function getPropertyOfTypeEx(c: Checker, t: Type, name: string, skipObjectFunctionPropertyAugment: boolean, includeTypeOnlyMembers: boolean): Symbol | undefined;
145
+ /**
146
+ * A long property list that `propertiesRelatedTo` walks: the position of each name, and the positions of
147
+ * the static private properties, which `getUnmatchedProperty` never reports, and of the required ones.
148
+ */
149
+ export declare class PropertyListIndex {
150
+ readonly positions: Map<string, number>;
151
+ readonly staticPrivate: number[];
152
+ readonly required: number[];
153
+ constructor(positions: Map<string, number>, staticPrivate: number[], required: number[]);
154
+ }
155
+ /**
156
+ * `getUnmatchedProperty(c, source, target, requireOptionalProperties, false)` where `targetProperties` are
157
+ * the target's properties and `found` the positions of the names the source has
158
+ * (`positionsOfNamesFoundInSource`): the first property that is not static private, and is required unless
159
+ * `requireOptionalProperties`, at a position not in `found`.
160
+ */
161
+ export declare function firstUnmatchedProperty(c: Checker, targetProperties: Symbol[], found: number[], requireOptionalProperties: boolean): Symbol | undefined;
162
+ /**
163
+ * The positions in `targetProperties`, the properties of `target`, ascending, of the names
164
+ * `getPropertyOfType(c, source, name)` finds: the names of the source's properties and of the Function and
165
+ * Object members its lookups fall back to. `getPropertyOfType` answers undefined for the names at every
166
+ * other position. Undefined where the answer cannot be read from resolved property lists without resolving
167
+ * anything (not an object type, an apparent type, members not resolved or not instantiated yet, a module),
168
+ * where the target list is too short or the source list too long to save lookups, and where the target
169
+ * list has no index (yet: `propertyListIndex`).
170
+ */
171
+ export declare function positionsOfNamesFoundInSource(c: Checker, source: Type, target: Type, targetProperties: Symbol[]): number[] | undefined;
145
172
  export declare function getPropertyOfObjectType(c: Checker, t: Type, name: string): Symbol | undefined;
146
173
  export declare function getTypeOfPropertyOfType(c: Checker, t: Type, name: string): Type | undefined;
147
174
  export declare function getPropertyOfUnionOrIntersectionType(c: Checker, t: UnionOrIntersectionType, name: string, skipObjectFunctionPropertyAugment: boolean): Symbol | undefined;
@@ -1305,6 +1305,171 @@ export function getPropertyOfTypeEx(c, t, name, skipObjectFunctionPropertyAugmen
1305
1305
  return getPropertyOfUnionOrIntersectionType(c, t, name, skipObjectFunctionPropertyAugment);
1306
1306
  return undefined;
1307
1307
  }
1308
+ /**
1309
+ * A long property list that `propertiesRelatedTo` walks: the position of each name, and the positions of
1310
+ * the static private properties, which `getUnmatchedProperty` never reports, and of the required ones.
1311
+ */
1312
+ export class PropertyListIndex {
1313
+ positions;
1314
+ staticPrivate;
1315
+ required;
1316
+ constructor(positions, staticPrivate, required) {
1317
+ this.positions = positions;
1318
+ this.staticPrivate = staticPrivate;
1319
+ this.required = required;
1320
+ }
1321
+ }
1322
+ /** The uses of a long property list after which `propertyListIndex` indexes it by a table of its own. */
1323
+ const propertyListUsesBeforeIndex = 3;
1324
+ /**
1325
+ * The index of `properties`, the properties of `target`. Where the members of `target` are properties
1326
+ * with shared names (`PropertyMembers` with `MemberNames`), the index reads the positions of those names.
1327
+ * Other lists get a positions table of their own on the use after the first `propertyListUsesBeforeIndex`:
1328
+ * most long lists are related only a few times, and the lists related many times hold most of the lookups
1329
+ * the index saves. Undefined before that, and where the list repeats a name.
1330
+ */
1331
+ function propertyListIndex(c, target, properties) {
1332
+ const known = c.propertyListIndexes.get(properties);
1333
+ if (known instanceof PropertyListIndex)
1334
+ return known;
1335
+ if (known === null)
1336
+ return undefined;
1337
+ let positions;
1338
+ const pending = (target.flags & 1048576 /* TypeFlags.Object */) !== 0 ? membersHolder(c, target).pendingMembers : undefined;
1339
+ if (pending instanceof PropertyMembers &&
1340
+ pending.materializedProperties === properties &&
1341
+ pending.names !== undefined) {
1342
+ // The names are the names of the properties, in order (hasMemberNames).
1343
+ positions = pending.names.positions;
1344
+ if (positions.size !== properties.length) {
1345
+ c.propertyListIndexes.set(properties, null);
1346
+ return undefined;
1347
+ }
1348
+ }
1349
+ else {
1350
+ const uses = known ?? 0;
1351
+ if (uses < propertyListUsesBeforeIndex) {
1352
+ c.propertyListIndexes.set(properties, uses + 1);
1353
+ return undefined;
1354
+ }
1355
+ }
1356
+ const own = positions === undefined ? new Map() : undefined;
1357
+ const staticPrivate = [];
1358
+ const required = [];
1359
+ for (let i = 0; i < properties.length; i++) {
1360
+ const p = properties[i];
1361
+ if (own !== undefined) {
1362
+ if (own.has(p.name)) {
1363
+ c.propertyListIndexes.set(properties, null);
1364
+ return undefined;
1365
+ }
1366
+ own.set(p.name, i);
1367
+ }
1368
+ if (isStaticPrivateIdentifierProperty(p))
1369
+ staticPrivate.push(i);
1370
+ else if ((p.flags & 16777216 /* SymbolFlags.Optional */) === 0 && (p.checkFlags & 48 /* CheckFlags.Partial */) === 0)
1371
+ required.push(i);
1372
+ }
1373
+ const index = new PropertyListIndex((positions ?? own), staticPrivate, required);
1374
+ c.propertyListIndexes.set(properties, index);
1375
+ return index;
1376
+ }
1377
+ /**
1378
+ * `getUnmatchedProperty(c, source, target, requireOptionalProperties, false)` where `targetProperties` are
1379
+ * the target's properties and `found` the positions of the names the source has
1380
+ * (`positionsOfNamesFoundInSource`): the first property that is not static private, and is required unless
1381
+ * `requireOptionalProperties`, at a position not in `found`.
1382
+ */
1383
+ export function firstUnmatchedProperty(c, targetProperties, found, requireOptionalProperties) {
1384
+ const index = c.propertyListIndexes.get(targetProperties);
1385
+ let next = 0;
1386
+ if (!requireOptionalProperties) {
1387
+ for (const position of index.required) {
1388
+ while (next < found.length && found[next] < position)
1389
+ next++;
1390
+ if (next === found.length || found[next] !== position)
1391
+ return targetProperties[position];
1392
+ }
1393
+ return undefined;
1394
+ }
1395
+ const staticPrivate = index.staticPrivate;
1396
+ let nextPrivate = 0;
1397
+ for (let position = 0; position < targetProperties.length; position++) {
1398
+ // A position can be both found and static private: both lists move past it.
1399
+ const isFound = next < found.length && found[next] === position;
1400
+ if (isFound)
1401
+ next++;
1402
+ const isStaticPrivate = nextPrivate < staticPrivate.length && staticPrivate[nextPrivate] === position;
1403
+ if (isStaticPrivate)
1404
+ nextPrivate++;
1405
+ if (!isFound && !isStaticPrivate)
1406
+ return targetProperties[position];
1407
+ }
1408
+ return undefined;
1409
+ }
1410
+ /** The shortest target property list that `positionsOfNamesFoundInSource` indexes. */
1411
+ const indexedTargetPropertiesMinimum = 32;
1412
+ /** The properties of `t` where its members are resolved and instantiated, else undefined. */
1413
+ function resolvedPropertiesIfAny(c, t) {
1414
+ const holder = (t.objectFlags & 2097152 /* ObjectFlags.MembersResolved */) !== 0 ? t : membersHolder(c, t);
1415
+ if ((holder.objectFlags & 2097152 /* ObjectFlags.MembersResolved */) === 0)
1416
+ return undefined;
1417
+ const pending = holder.pendingMembers;
1418
+ return pending === undefined || pending.materializedProperties !== undefined ? holder.properties : undefined;
1419
+ }
1420
+ /**
1421
+ * The positions in `targetProperties`, the properties of `target`, ascending, of the names
1422
+ * `getPropertyOfType(c, source, name)` finds: the names of the source's properties and of the Function and
1423
+ * Object members its lookups fall back to. `getPropertyOfType` answers undefined for the names at every
1424
+ * other position. Undefined where the answer cannot be read from resolved property lists without resolving
1425
+ * anything (not an object type, an apparent type, members not resolved or not instantiated yet, a module),
1426
+ * where the target list is too short or the source list too long to save lookups, and where the target
1427
+ * list has no index (yet: `propertyListIndex`).
1428
+ */
1429
+ export function positionsOfNamesFoundInSource(c, source, target, targetProperties) {
1430
+ if (targetProperties.length < indexedTargetPropertiesMinimum)
1431
+ return undefined;
1432
+ if ((source.flags & 1048576 /* TypeFlags.Object */) === 0 || !isOwnReducedApparentType(source))
1433
+ return undefined;
1434
+ // A module's member that only an `export type *` declaration exports is not found.
1435
+ if (source.symbol !== undefined && (source.symbol.flags & 512 /* SymbolFlags.ValueModule */) !== 0)
1436
+ return undefined;
1437
+ const sourceProperties = resolvedPropertiesIfAny(c, source);
1438
+ if (sourceProperties === undefined)
1439
+ return undefined;
1440
+ const resolved = membersHolder(c, source);
1441
+ let functionType;
1442
+ if (source === c.anyFunctionType)
1443
+ functionType = c.globalFunctionType;
1444
+ else if (resolved.callSignatures.length !== 0)
1445
+ functionType = c.globalCallableFunctionType;
1446
+ else if (resolved.constructSignatures.length !== 0)
1447
+ functionType = c.globalNewableFunctionType;
1448
+ let functionProperties = emptySymbols;
1449
+ if (functionType !== undefined && (functionType.flags & 1048576 /* TypeFlags.Object */) !== 0) {
1450
+ const properties = resolvedPropertiesIfAny(c, functionType);
1451
+ if (properties === undefined)
1452
+ return undefined;
1453
+ functionProperties = properties;
1454
+ }
1455
+ const objectProperties = (c.globalObjectType.flags & 1048576 /* TypeFlags.Object */) !== 0 ? resolvedPropertiesIfAny(c, c.globalObjectType) : emptySymbols;
1456
+ if (objectProperties === undefined)
1457
+ return undefined;
1458
+ if ((sourceProperties.length + functionProperties.length + objectProperties.length) * 4 > targetProperties.length)
1459
+ return undefined;
1460
+ const index = propertyListIndex(c, target, targetProperties);
1461
+ if (index === undefined)
1462
+ return undefined;
1463
+ const positions = index.positions;
1464
+ const found = [];
1465
+ for (const list of [sourceProperties, functionProperties, objectProperties])
1466
+ for (const p of list) {
1467
+ const position = positions.get(p.name);
1468
+ if (position !== undefined && !found.includes(position))
1469
+ found.push(position);
1470
+ }
1471
+ return found.sort((a, b) => a - b);
1472
+ }
1308
1473
  export function getPropertyOfObjectType(c, t, name) {
1309
1474
  if ((t.flags & 1048576 /* TypeFlags.Object */) === 0)
1310
1475
  return undefined;
@@ -7,6 +7,20 @@ import { type Symbol, SymbolFlags, type SymbolTable } from './symbol.js';
7
7
  /** The module symbol `moduleReference` names, reporting it when it isn't found unless `ignoreErrors`. */
8
8
  export declare function resolveExternalModuleName(c: Checker, location: Node, moduleReference: Node | undefined, ignoreErrors: boolean): Symbol | undefined;
9
9
  export declare function resolveExternalModuleNameWorker(c: Checker, location: Node, moduleReference: Node | undefined, moduleNotFoundError: DiagnosticMessage | undefined, ignoreErrors: boolean, isForAugmentation: boolean): Symbol | undefined;
10
+ /** A `resolveExternalModule` result that reported nothing, and the arguments it was computed for. */
11
+ export declare class ModuleResolution {
12
+ readonly moduleReference: string;
13
+ readonly moduleNotFoundError: DiagnosticMessage | undefined;
14
+ readonly isForAugmentation: boolean;
15
+ readonly symbol: Symbol | undefined;
16
+ constructor(moduleReference: string, moduleNotFoundError: DiagnosticMessage | undefined, isForAugmentation: boolean, symbol: Symbol | undefined);
17
+ }
18
+ /**
19
+ * The module symbol `moduleReference` resolves to from `location`, reporting resolution errors at
20
+ * `errorNode`. Each name an import or export declaration lists resolves its module specifier again,
21
+ * with the same result and the same diagnostics: a result that reported nothing is kept for the
22
+ * specifier and returned to later calls from the same declaration (`sharesSpecifierContext`).
23
+ */
10
24
  export declare function resolveExternalModule(c: Checker, location: Node, moduleReference: string, moduleNotFoundError: DiagnosticMessage | undefined, errorNode: Node | undefined, isForAugmentation: boolean): Symbol | undefined;
11
25
  /** A message with its arguments, the elaboration of a diagnostic before it has a location. */
12
26
  export declare class DiagnosticDetails {
@@ -57,7 +57,78 @@ export function resolveExternalModuleNameWorker(c, location, moduleReference, mo
57
57
  return undefined;
58
58
  return resolveExternalModule(c, location, getText(moduleReference), moduleNotFoundError, ignoreErrors ? undefined : moduleReference, isForAugmentation);
59
59
  }
60
+ /** A `resolveExternalModule` result that reported nothing, and the arguments it was computed for. */
61
+ export class ModuleResolution {
62
+ moduleReference;
63
+ moduleNotFoundError;
64
+ isForAugmentation;
65
+ symbol;
66
+ constructor(moduleReference, moduleNotFoundError, isForAugmentation, symbol) {
67
+ this.moduleReference = moduleReference;
68
+ this.moduleNotFoundError = moduleNotFoundError;
69
+ this.isForAugmentation = isForAugmentation;
70
+ this.symbol = symbol;
71
+ }
72
+ }
73
+ /**
74
+ * The module symbol `moduleReference` resolves to from `location`, reporting resolution errors at
75
+ * `errorNode`. Each name an import or export declaration lists resolves its module specifier again,
76
+ * with the same result and the same diagnostics: a result that reported nothing is kept for the
77
+ * specifier and returned to later calls from the same declaration (`sharesSpecifierContext`).
78
+ */
60
79
  export function resolveExternalModule(c, location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
80
+ // An augmentation merged later can give the resolved module a new merged symbol, so results are
81
+ // kept only once every augmentation is merged.
82
+ const shared = c.modulesMerged && errorNode !== undefined && sharesSpecifierContext(location, errorNode);
83
+ if (shared) {
84
+ const known = c.moduleResolutions.get(errorNode);
85
+ if (known !== undefined &&
86
+ known.moduleReference === moduleReference &&
87
+ known.moduleNotFoundError === moduleNotFoundError &&
88
+ known.isForAugmentation === isForAugmentation)
89
+ return known.symbol;
90
+ }
91
+ const reports = c.reports;
92
+ const symbol = resolveExternalModuleWorker(c, location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation);
93
+ if (shared && c.reports === reports)
94
+ c.moduleResolutions.set(errorNode, new ModuleResolution(moduleReference, moduleNotFoundError, isForAugmentation, symbol));
95
+ return symbol;
96
+ }
97
+ /**
98
+ * Whether a resolution from `location` with errors at `errorNode` depends on `location` only through
99
+ * the declaration that `errorNode` is the module specifier of: `location` is that declaration, a
100
+ * clause or specifier inside it, or the specifier itself. The resolution mode, the emittability of
101
+ * the import and its resolution-mode attributes then all come from that declaration.
102
+ */
103
+ function sharesSpecifierContext(location, errorNode) {
104
+ const declaration = errorNode.parent;
105
+ if (declaration === undefined ||
106
+ (declaration.kind !== 273 /* SyntaxKind.ImportDeclaration */ &&
107
+ declaration.kind !== 346 /* SyntaxKind.JSImportDeclaration */ &&
108
+ declaration.kind !== 279 /* SyntaxKind.ExportDeclaration */) ||
109
+ getModuleSpecifier(declaration) !== errorNode)
110
+ return false;
111
+ for (let current = location; current !== undefined; current = current.parent)
112
+ switch (current.kind) {
113
+ case 273 /* SyntaxKind.ImportDeclaration */:
114
+ case 346 /* SyntaxKind.JSImportDeclaration */:
115
+ case 279 /* SyntaxKind.ExportDeclaration */:
116
+ return current === declaration;
117
+ case 274 /* SyntaxKind.ImportClause */:
118
+ case 276 /* SyntaxKind.NamedImports */:
119
+ case 275 /* SyntaxKind.NamespaceImport */:
120
+ case 277 /* SyntaxKind.ImportSpecifier */:
121
+ case 280 /* SyntaxKind.NamedExports */:
122
+ case 281 /* SyntaxKind.NamespaceExport */:
123
+ case 282 /* SyntaxKind.ExportSpecifier */:
124
+ break;
125
+ default:
126
+ if (current !== errorNode)
127
+ return false;
128
+ }
129
+ return false;
130
+ }
131
+ function resolveExternalModuleWorker(c, location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
61
132
  if (errorNode !== undefined && moduleReference.startsWith('@types/'))
62
133
  c.error(errorNode, 1302 /* Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1 */, moduleReference.substring(7), moduleReference);
63
134
  const ambient = tryFindAmbientModule(c, moduleReference, true);
@@ -490,7 +561,8 @@ function isOnlyImportableAsDefault(c, usage, resolvedModule) {
490
561
  const moduleSymbol = resolvedModule ?? resolveExternalModuleName(c, usage, usage, true);
491
562
  const targetFile = moduleSymbol !== undefined ? getSourceFileOfModuleSymbol(moduleSymbol) : undefined;
492
563
  return (targetFile !== undefined &&
493
- (isJsonSourceFile(targetFile) || getDeclarationFileExtension(targetFile.fileName) === '.d.json.ts'));
564
+ (isJsonSourceFile(targetFile) ||
565
+ (targetFile.fileName.endsWith('.d.json.ts') && getDeclarationFileExtension(targetFile.fileName) === '.d.json.ts')));
494
566
  }
495
567
  /** The source file that declares a module: its value declaration, or its first declaration that is not an augmentation. */
496
568
  function getSourceFileOfModuleSymbol(symbol) {
@@ -6,6 +6,7 @@ import { Diagnostic, type DiagnosticMessage, Diagnostics } from './diagnostics.j
6
6
  import { type CompilerOptions, ModuleKind, ScriptTarget } from './options.js';
7
7
  import { CheckFlags, Symbol, SymbolFlags, type SymbolTable } from './symbol.js';
8
8
  import { IndexInfo, IntrinsicType, LiteralType, MemberNames, NodeLinks, ObjectFlags, ObjectType, Signature, SignatureFlags, SymbolLinks, type Type, TypeFlags, TypeMapper, TypeParameter, TypePredicate, VarianceFlags, TypeListCache, TypeListTable, type ConditionalType, type InterfaceType, type TypeChecking } from './checker-types.js';
9
+ import type { ModuleResolution } from './checker-modules.js';
9
10
  import { CheckerNameResolver, type LibGlobals, type MergedGlobals, TableChanges, SuggestionNameResolver } from './checker-symbols.js';
10
11
  import { Relation, RelationKey, type InternedRelationKey, type Relater, TypeComparer } from './relations.js';
11
12
  import { TypeNodeVisitor } from './checker-source-file.js';
@@ -19,6 +20,7 @@ import { SourceFileMetadata } from './program-utilities.js';
19
20
  import type { GrammarChecker } from './checker-grammar.js';
20
21
  import type { ResolvedModule } from './module-resolution-types.js';
21
22
  import type { ModuleSpecifierHost } from './module-specifiers.js';
23
+ import type { PropertyListIndex } from './checker-members.js';
22
24
  /** What the checker needs from a program. */
23
25
  export declare abstract class CheckerHost {
24
26
  abstract getCompilerOptions(): CompilerOptions;
@@ -151,6 +153,15 @@ export declare class Checker implements TypeChecking {
151
153
  currentNode: Node | undefined;
152
154
  readonly diagnostics: DiagnosticCollection;
153
155
  readonly suggestionDiagnostics: DiagnosticCollection;
156
+ /** Diagnostics and suggestions reported so far, whether kept or not (`resolveExternalModule`'s cache). */
157
+ reports: number;
158
+ /** `resolveExternalModule` results that reported nothing, by module specifier (checker-modules.ts). */
159
+ readonly moduleResolutions: Map<Node, ModuleResolution>;
160
+ /**
161
+ * Whether ambient modules and module augmentations are merged. Merging can give a module a new
162
+ * merged symbol, so `resolveExternalModule` keeps results only from then on.
163
+ */
164
+ modulesMerged: boolean;
154
165
  /** Module specifiers of `import("…")` types, by module symbol id, importing file path and resolution mode. */
155
166
  readonly moduleSpecifiers: Map<string, string>;
156
167
  /** Specifier generation for hosts without a program. */
@@ -161,6 +172,11 @@ export declare class Checker implements TypeChecking {
161
172
  readonly sideHolders: LinkTable<Type>;
162
173
  /** The same for signatures with side state (`signatureSideOf`), by signature id. */
163
174
  readonly signatureSideHolders: LinkTable<Signature>;
175
+ /**
176
+ * The indexes of long property lists that `propertiesRelatedTo` walks; before a list is indexed, its uses
177
+ * so far; null where a list repeats a name.
178
+ */
179
+ readonly propertyListIndexes: Map<Symbol[], number | PropertyListIndex | null>;
164
180
  /** The type of a value symbol. */
165
181
  readonly symbolTypes: LinkTable<Type>;
166
182
  /** For instantiated and synthetic symbols, the symbol they come from. */
@@ -230,6 +230,15 @@ export class Checker {
230
230
  currentNode = undefined;
231
231
  diagnostics = new DiagnosticCollection();
232
232
  suggestionDiagnostics = new DiagnosticCollection();
233
+ /** Diagnostics and suggestions reported so far, whether kept or not (`resolveExternalModule`'s cache). */
234
+ reports = 0;
235
+ /** `resolveExternalModule` results that reported nothing, by module specifier (checker-modules.ts). */
236
+ moduleResolutions = new Map();
237
+ /**
238
+ * Whether ambient modules and module augmentations are merged. Merging can give a module a new
239
+ * merged symbol, so `resolveExternalModule` keeps results only from then on.
240
+ */
241
+ modulesMerged = false;
233
242
  /** Module specifiers of `import("…")` types, by module symbol id, importing file path and resolution mode. */
234
243
  moduleSpecifiers = new Map();
235
244
  /** Specifier generation for hosts without a program. */
@@ -243,6 +252,11 @@ export class Checker {
243
252
  sideHolders = new LinkTable();
244
253
  /** The same for signatures with side state (`signatureSideOf`), by signature id. */
245
254
  signatureSideHolders = new LinkTable();
255
+ /**
256
+ * The indexes of long property lists that `propertiesRelatedTo` walks; before a list is indexed, its uses
257
+ * so far; null where a list repeats a name.
258
+ */
259
+ propertyListIndexes = new Map();
246
260
  /** The type of a value symbol. */
247
261
  symbolTypes = new LinkTable();
248
262
  /** For instantiated and synthetic symbols, the symbol they come from. */
@@ -740,6 +754,7 @@ export class Checker {
740
754
  this.diagnostics.startLog();
741
755
  this.suggestionDiagnostics.startLog();
742
756
  mergeAmbientModulesAndAugmentations(this);
757
+ this.modulesMerged = true;
743
758
  this.mergeDiagnostics.push(this.diagnostics.takeLog(), this.suggestionDiagnostics.takeLog());
744
759
  }
745
760
  // ---- Public API
@@ -830,11 +845,13 @@ export class Checker {
830
845
  return diagnostic;
831
846
  }
832
847
  addDiagnostic(diagnostic) {
848
+ this.reports++;
833
849
  // Discard diagnostics created while at the maximum number of nested typeToString calls.
834
850
  if (this.serializationLevel < maxSerializationLevel)
835
851
  this.diagnostics.add(diagnostic);
836
852
  }
837
853
  addSuggestion(diagnostic) {
854
+ this.reports++;
838
855
  this.suggestionDiagnostics.add(diagnostic);
839
856
  }
840
857
  /** Reports an error, or a suggestion when `isError` is false. */
@@ -152,12 +152,14 @@ function threadCopyOf(file) {
152
152
  }
153
153
  return copy;
154
154
  }
155
+ /** The empty value of a file's position tables until they are computed. */
156
+ const noNumbers = [];
155
157
  /** The text of a file diagnostics point into. */
156
158
  export class DiagnosticFile {
157
159
  fileName;
158
160
  text;
159
161
  // Computed on first use; never empty once computed.
160
- lineStarts = [];
162
+ lineStarts = noNumbers;
161
163
  /** Whether this is a thread's copy of a possibly shared file (`threadCopyOf`). */
162
164
  isThreadCopy = false;
163
165
  constructor(fileName, text) {
@@ -186,8 +188,8 @@ export class DiagnosticFile {
186
188
  // The non-ASCII characters, in order: their UTF-16 offsets, UTF-8 lengths, and the UTF-8 bytes
187
189
  // beyond one per UTF-16 code unit of the text up to and including each. Unset until first used.
188
190
  nonASCIIStarts = undefined;
189
- nonASCIILengths = [];
190
- extraBytes = [];
191
+ nonASCIILengths = noNumbers;
192
+ extraBytes = noNumbers;
191
193
  getNonASCIIStarts() {
192
194
  let starts = this.nonASCIIStarts;
193
195
  if (starts === undefined) {
@@ -196,8 +198,8 @@ export class DiagnosticFile {
196
198
  if (Buffer.byteLength(text, 'utf8') !== text.length) {
197
199
  // Scanning the UTF-8 encoding is faster than reading each code unit.
198
200
  const bytes = Buffer.from(text, 'utf8');
199
- const lengths = this.nonASCIILengths;
200
- const extraBytes = this.extraBytes;
201
+ const lengths = [];
202
+ const extraBytes = [];
201
203
  let extra = 0;
202
204
  for (let i = 0; i < bytes.length; i++) {
203
205
  const b = bytes[i];
@@ -211,6 +213,8 @@ export class DiagnosticFile {
211
213
  extraBytes.push(extra);
212
214
  i += length - 1;
213
215
  }
216
+ this.nonASCIILengths = lengths;
217
+ this.extraBytes = extraBytes;
214
218
  }
215
219
  this.nonASCIIStarts = starts;
216
220
  }
@@ -445,7 +445,9 @@ export class ParseSession {
445
445
  this.onIdle(batch);
446
446
  }
447
447
  post(i, chunk) {
448
- this.workers[i].postMessage(chunk);
448
+ // Published, the chunk reaches the thread by pointer: copying its names into the message took the
449
+ // main thread 25-45 us per chunk, which during config read delays the matching of root files.
450
+ this.workers[i].postMessage(publish(chunk));
449
451
  this.outstanding[i] = this.outstanding[i] + 1;
450
452
  if (chunk.kinds[0] === 2 /* LoadKind.Library */ && largeLibraries.has(chunk.names[0]))
451
453
  this.blocked[i] = true;