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.
- package/dist/api/compiler/ast.d.ts +57 -18
- package/dist/api/compiler/ast.js +134 -39
- package/dist/api/compiler/binder-utilities.js +2 -2
- package/dist/api/compiler/binder.js +6 -6
- package/dist/api/compiler/checker-calls.js +4 -4
- package/dist/api/compiler/checker-contextual.js +1 -1
- package/dist/api/compiler/checker-emit-helpers.d.ts +2 -1
- package/dist/api/compiler/checker-emit-helpers.js +5 -4
- package/dist/api/compiler/checker-grammar.js +5 -5
- package/dist/api/compiler/checker-inference.d.ts +20 -10
- package/dist/api/compiler/checker-inference.js +48 -25
- package/dist/api/compiler/checker-members.d.ts +27 -0
- package/dist/api/compiler/checker-members.js +165 -0
- package/dist/api/compiler/checker-modules.d.ts +14 -0
- package/dist/api/compiler/checker-modules.js +73 -1
- package/dist/api/compiler/checker.d.ts +16 -0
- package/dist/api/compiler/checker.js +17 -0
- package/dist/api/compiler/diagnostics.js +9 -5
- package/dist/api/compiler/parallel-parse.js +3 -1
- package/dist/api/compiler/parser.js +33 -23
- package/dist/api/compiler/printer/factory-base.js +8 -8
- package/dist/api/compiler/printer/factory.js +4 -4
- package/dist/api/compiler/printer/printer.js +6 -6
- package/dist/api/compiler/program-checker.d.ts +5 -0
- package/dist/api/compiler/program-checker.js +11 -1
- package/dist/api/compiler/relations.js +8 -3
- package/dist/api/compiler/reparser.js +13 -5
- package/dist/api/compiler/transformers/class-fields.js +3 -3
- package/dist/api/compiler/transformers/commonjs-module.js +3 -3
- package/dist/api/compiler/transformers/declarations-pseudo.js +2 -2
- package/dist/api/compiler/transformers/module.js +2 -2
- package/dist/api/compiler/transformers/optional-chain.js +3 -3
- package/dist/api/compiler/transformers/subtree-facts.js +2 -2
- package/dist/api/compiler/transformers/tagged-template.js +2 -2
- package/dist/api/compiler/transformers/type-eraser.js +2 -2
- package/dist/api/compiler/transformers/visitor-base.js +3 -3
- package/dist/api/compiler/tsconfig.js +2 -2
- package/package.json +8 -8
- package/src/compiler/ast.ts +184 -59
- package/src/compiler/binder-utilities.ts +2 -1
- package/src/compiler/binder.ts +11 -5
- package/src/compiler/checker-calls.ts +5 -3
- package/src/compiler/checker-contextual.ts +1 -1
- package/src/compiler/checker-emit-helpers.ts +5 -4
- package/src/compiler/checker-grammar.ts +5 -3
- package/src/compiler/checker-inference.ts +49 -25
- package/src/compiler/checker-members.ts +164 -0
- package/src/compiler/checker-modules.ts +92 -1
- package/src/compiler/checker.ts +19 -0
- package/src/compiler/decoder.ts +5 -4
- package/src/compiler/diagnostics.ts +10 -5
- package/src/compiler/encoder.ts +10 -5
- package/src/compiler/parallel-parse.ts +3 -1
- package/src/compiler/parser.ts +53 -23
- package/src/compiler/printer/factory-base.ts +14 -7
- package/src/compiler/printer/factory.ts +5 -3
- package/src/compiler/printer/printer.ts +8 -6
- package/src/compiler/program-checker.ts +10 -1
- package/src/compiler/relations.ts +10 -2
- package/src/compiler/reparser.ts +14 -4
- package/src/compiler/transformers/class-fields.ts +12 -2
- package/src/compiler/transformers/commonjs-module.ts +3 -2
- package/src/compiler/transformers/declarations-pseudo.ts +2 -1
- package/src/compiler/transformers/declarations.ts +1 -1
- package/src/compiler/transformers/module.ts +2 -1
- package/src/compiler/transformers/optional-chain.ts +5 -2
- package/src/compiler/transformers/subtree-facts.ts +2 -1
- package/src/compiler/transformers/tagged-template.ts +2 -2
- package/src/compiler/transformers/type-eraser.ts +2 -1
- package/src/compiler/transformers/visitor-base.ts +10 -5
- 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
|
-
|
|
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
|
-
/**
|
|
66
|
-
|
|
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
|
-
|
|
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
|
|
76
|
-
export declare class
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
71
|
-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.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.
|
|
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 (
|
|
109
|
+
if (!inference.isFixed) {
|
|
105
110
|
// Infer from intra-expression sites before committing to an inference.
|
|
106
|
-
inferFromIntraExpressionSites(this.c, this
|
|
111
|
+
inferFromIntraExpressionSites(this.c, this);
|
|
107
112
|
clearCachedInferences(inferences);
|
|
108
113
|
inference.isFixed = true;
|
|
109
114
|
}
|
|
110
|
-
return getInferredType(this.c, this
|
|
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
|
-
|
|
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.
|
|
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) ||
|
|
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 =
|
|
200
|
-
const 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
|
-
|
|
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;
|