Skip to content

Commit 90b7d94

Browse files
committed
Merge branch 'main' into intl-numberformat
2 parents a6261f9 + be20dbb commit 90b7d94

File tree

82 files changed

+1341
-384
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1341
-384
lines changed

package-lock.json

Lines changed: 288 additions & 288 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler/checker.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19107,6 +19107,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1910719107
}
1910819108

1910919109
function getESSymbolLikeTypeForNode(node: Node) {
19110+
if (isInJSFile(node) && isJSDocTypeExpression(node)) {
19111+
const host = getJSDocHost(node);
19112+
if (host) {
19113+
node = getSingleVariableOfVariableStatement(host) || host;
19114+
}
19115+
}
1911019116
if (isValidESSymbolDeclaration(node)) {
1911119117
const symbol = isCommonJsExportPropertyAssignment(node) ? getSymbolOfNode((node as BinaryExpression).left) : getSymbolOfNode(node);
1911219118
if (symbol) {
@@ -22313,7 +22319,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2231322319
// This is a carve-out in comparability to essentially forbid comparing a type parameter
2231422320
// with another type parameter unless one extends the other. (Remember: comparability is mostly bidirectional!)
2231522321
let constraint = getConstraintOfTypeParameter(source);
22316-
if (constraint && hasNonCircularBaseConstraint(source)) {
22322+
if (constraint) {
2231722323
while (constraint && someType(constraint, c => !!(c.flags & TypeFlags.TypeParameter))) {
2231822324
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false)) {
2231922325
return result;
@@ -25538,6 +25544,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2553825544
}
2553925545
else {
2554025546
source = getReducedType(source);
25547+
if (isGenericMappedType(source) && isGenericMappedType(target)) {
25548+
invokeOnce(source, target, inferFromGenericMappedTypes);
25549+
}
2554125550
if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) {
2554225551
const apparentSource = getApparentType(source);
2554325552
// getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
@@ -25575,6 +25584,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2557525584
priority = savePriority;
2557625585
}
2557725586

25587+
// Ensure an inference action is performed only once for the given source and target types.
25588+
// This includes two things:
25589+
// Avoiding inferring between the same pair of source and target types,
25590+
// and avoiding circularly inferring between source and target types.
25591+
// For an example of the last, consider if we are inferring between source type
25592+
// `type Deep<T> = { next: Deep<Deep<T>> }` and target type `type Loop<U> = { next: Loop<U> }`.
25593+
// We would then infer between the types of the `next` property: `Deep<Deep<T>>` = `{ next: Deep<Deep<Deep<T>>> }` and `Loop<U>` = `{ next: Loop<U> }`.
25594+
// We will then infer again between the types of the `next` property:
25595+
// `Deep<Deep<Deep<T>>>` and `Loop<U>`, and so on, such that we would be forever inferring
25596+
// between instantiations of the same types `Deep` and `Loop`.
25597+
// In particular, we would be inferring from increasingly deep instantiations of `Deep` to `Loop`,
25598+
// such that we would go on inferring forever, even though we would never infer
25599+
// between the same pair of types.
2557825600
function invokeOnce<Source extends Type, Target extends Type>(source: Source, target: Target, action: (source: Source, target: Target) => void) {
2557925601
const key = source.id + "," + target.id;
2558025602
const status = visited && visited.get(key);
@@ -25882,6 +25904,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2588225904
}
2588325905
}
2588425906

25907+
function inferFromGenericMappedTypes(source: MappedType, target: MappedType) {
25908+
// The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
25909+
// from S to T and from X to Y.
25910+
inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
25911+
inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
25912+
const sourceNameType = getNameTypeFromMappedType(source);
25913+
const targetNameType = getNameTypeFromMappedType(target);
25914+
if (sourceNameType && targetNameType) inferFromTypes(sourceNameType, targetNameType);
25915+
}
25916+
2588525917
function inferFromObjectTypes(source: Type, target: Type) {
2588625918
if (
2588725919
getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (
@@ -25893,13 +25925,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2589325925
return;
2589425926
}
2589525927
if (isGenericMappedType(source) && isGenericMappedType(target)) {
25896-
// The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
25897-
// from S to T and from X to Y.
25898-
inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
25899-
inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
25900-
const sourceNameType = getNameTypeFromMappedType(source);
25901-
const targetNameType = getNameTypeFromMappedType(target);
25902-
if (sourceNameType && targetNameType) inferFromTypes(sourceNameType, targetNameType);
25928+
inferFromGenericMappedTypes(source, target);
2590325929
}
2590425930
if (getObjectFlags(target) & ObjectFlags.Mapped && !(target as MappedType).declaration.nameType) {
2590525931
const constraintType = getConstraintTypeFromMappedType(target as MappedType);

src/compiler/commandLineParser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,11 @@ const libEntries: [string, string][] = [
162162
// Host only
163163
["dom", "lib.dom.d.ts"],
164164
["dom.iterable", "lib.dom.iterable.d.ts"],
165+
["dom.asynciterable", "lib.dom.asynciterable.d.ts"],
165166
["webworker", "lib.webworker.d.ts"],
166167
["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
167168
["webworker.iterable", "lib.webworker.iterable.d.ts"],
169+
["webworker.asynciterable", "lib.webworker.asynciterable.d.ts"],
168170
["scripthost", "lib.scripthost.d.ts"],
169171
// ES2015 Or ESNext By-feature options
170172
["es2015.core", "lib.es2015.core.d.ts"],
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/////////////////////////////
2+
/// Window Async Iterable APIs
3+
/////////////////////////////
4+
5+
interface FileSystemDirectoryHandle {
6+
[Symbol.asyncIterator](): AsyncIterableIterator<[string, FileSystemHandle]>;
7+
entries(): AsyncIterableIterator<[string, FileSystemHandle]>;
8+
keys(): AsyncIterableIterator<string>;
9+
values(): AsyncIterableIterator<FileSystemHandle>;
10+
}

src/lib/es2018.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/es2019.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/es2020.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/es2021.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/es2022.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/es2023.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/esnext.full.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference lib="webworker.importscripts" />
44
/// <reference lib="scripthost" />
55
/// <reference lib="dom.iterable" />
6+
/// <reference lib="dom.asynciterable" />

src/lib/libs.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
// Host only
1616
"dom.generated",
1717
"dom.iterable.generated",
18+
"dom.asynciterable.generated",
1819
"webworker.generated",
1920
"webworker.importscripts",
2021
"webworker.iterable.generated",
22+
"webworker.asynciterable.generated",
2123
"scripthost",
2224
// By-feature options
2325
"es2015.core",
@@ -91,8 +93,10 @@
9193
"paths": {
9294
"dom.generated": "lib.dom.d.ts",
9395
"dom.iterable.generated": "lib.dom.iterable.d.ts",
96+
"dom.asynciterable.generated": "lib.dom.asynciterable.d.ts",
9497
"webworker.generated": "lib.webworker.d.ts",
9598
"webworker.iterable.generated": "lib.webworker.iterable.d.ts",
99+
"webworker.asynciterable.generated": "lib.webworker.asynciterable.d.ts",
96100
"es5.full": "lib.d.ts",
97101
"es2015.full": "lib.es6.d.ts"
98102
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/////////////////////////////
2+
/// Worker Async Iterable APIs
3+
/////////////////////////////
4+
5+
interface FileSystemDirectoryHandle {
6+
[Symbol.asyncIterator](): AsyncIterableIterator<[string, FileSystemHandle]>;
7+
entries(): AsyncIterableIterator<[string, FileSystemHandle]>;
8+
keys(): AsyncIterableIterator<string>;
9+
values(): AsyncIterableIterator<FileSystemHandle>;
10+
}

src/services/callHierarchy.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import {
9191
ParameterDeclaration,
9292
Program,
9393
PropertyAccessExpression,
94+
PropertyDeclaration,
9495
SatisfiesExpression,
9596
SetAccessorDeclaration,
9697
skipTrivia,
@@ -117,18 +118,27 @@ function isNamedExpression(node: Node): node is NamedExpression {
117118
}
118119

119120
/** @internal */
120-
export type ConstNamedExpression =
121-
| ClassExpression & { name: undefined; parent: VariableDeclaration & { name: Identifier; }; }
122-
| FunctionExpression & { name: undefined; parent: VariableDeclaration & { name: Identifier; }; }
123-
| ArrowFunction & { name: undefined; parent: VariableDeclaration & { name: Identifier; }; };
121+
export type VariableLike =
122+
| VariableDeclaration
123+
| PropertyDeclaration;
124124

125-
/** Indicates whether a node is a function, arrow, or class expression assigned to a constant variable. */
126-
function isConstNamedExpression(node: Node): node is ConstNamedExpression {
125+
function isVariableLike(node: Node): node is VariableLike {
126+
return isPropertyDeclaration(node) || isVariableDeclaration(node);
127+
}
128+
129+
/** @internal */
130+
export type AssignedExpression =
131+
| ClassExpression & { name: undefined; parent: VariableLike & { name: Identifier; }; }
132+
| FunctionExpression & { name: undefined; parent: VariableLike & { name: Identifier; }; }
133+
| ArrowFunction & { name: undefined; parent: VariableLike & { name: Identifier; }; };
134+
135+
/** Indicates whether a node is a function, arrow, or class expression assigned to a constant variable or class property. */
136+
function isAssignedExpression(node: Node): node is AssignedExpression {
127137
return (isFunctionExpression(node) || isArrowFunction(node) || isClassExpression(node))
128-
&& isVariableDeclaration(node.parent)
138+
&& isVariableLike(node.parent)
129139
&& node === node.parent.initializer
130140
&& isIdentifier(node.parent.name)
131-
&& !!(getCombinedNodeFlags(node.parent) & NodeFlags.Const);
141+
&& (!!(getCombinedNodeFlags(node.parent) & NodeFlags.Const) || isPropertyDeclaration(node.parent));
132142
}
133143

134144
/** @internal */
@@ -142,7 +152,7 @@ export type CallHierarchyDeclaration =
142152
| GetAccessorDeclaration
143153
| SetAccessorDeclaration
144154
| NamedExpression
145-
| ConstNamedExpression;
155+
| AssignedExpression;
146156

147157
/**
148158
* Indicates whether a node could possibly be a call hierarchy declaration.
@@ -179,14 +189,14 @@ function isValidCallHierarchyDeclaration(node: Node): node is CallHierarchyDecla
179189
|| isGetAccessorDeclaration(node)
180190
|| isSetAccessorDeclaration(node)
181191
|| isNamedExpression(node)
182-
|| isConstNamedExpression(node);
192+
|| isAssignedExpression(node);
183193
}
184194

185195
/** Gets the node that can be used as a reference to a call hierarchy declaration. */
186196
function getCallHierarchyDeclarationReferenceNode(node: Exclude<CallHierarchyDeclaration, ClassStaticBlockDeclaration>) {
187197
if (isSourceFile(node)) return node;
188198
if (isNamedDeclaration(node)) return node.name;
189-
if (isConstNamedExpression(node)) return node.parent.name;
199+
if (isAssignedExpression(node)) return node.parent.name;
190200
return Debug.checkDefined(node.modifiers && find(node.modifiers, isDefaultModifier));
191201
}
192202

@@ -223,7 +233,7 @@ function getCallHierarchyItemName(program: Program, node: CallHierarchyDeclarati
223233
return { text: `${prefix}static {}`, pos, end };
224234
}
225235

226-
const declName = isConstNamedExpression(node) ? node.parent.name :
236+
const declName = isAssignedExpression(node) ? node.parent.name :
227237
Debug.checkDefined(getNameOfDeclaration(node), "Expected call hierarchy item to have a name");
228238

229239
let text = isIdentifier(declName) ? idText(declName) :
@@ -248,7 +258,10 @@ function getCallHierarchyItemName(program: Program, node: CallHierarchyDeclarati
248258
}
249259

250260
function getCallHierarchItemContainerName(node: CallHierarchyDeclaration): string | undefined {
251-
if (isConstNamedExpression(node)) {
261+
if (isAssignedExpression(node)) {
262+
if (isPropertyDeclaration(node.parent) && isClassLike(node.parent.parent)) {
263+
return isClassExpression(node.parent.parent) ? getAssignedName(node.parent.parent)?.getText() : node.parent.parent.name?.getText();
264+
}
252265
if (isModuleBlock(node.parent.parent.parent.parent) && isIdentifier(node.parent.parent.parent.parent.parent.name)) {
253266
return node.parent.parent.parent.parent.parent.name.getText();
254267
}
@@ -364,7 +377,7 @@ export function resolveCallHierarchyDeclaration(program: Program, location: Node
364377
const ancestor = findAncestor(location.parent, isValidCallHierarchyDeclaration);
365378
return ancestor && findImplementationOrAllInitialDeclarations(typeChecker, ancestor);
366379
}
367-
if (isVariableDeclaration(location.parent) && location.parent.initializer && isConstNamedExpression(location.parent.initializer)) {
380+
if (isVariableLike(location.parent) && location.parent.initializer && isAssignedExpression(location.parent.initializer)) {
368381
return location.parent.initializer;
369382
}
370383
return undefined;
@@ -380,7 +393,7 @@ export function resolveCallHierarchyDeclaration(program: Program, location: Node
380393
continue;
381394
}
382395
// #39453
383-
if (isVariableDeclaration(location) && location.initializer && isConstNamedExpression(location.initializer)) {
396+
if (isVariableDeclaration(location) && location.initializer && isAssignedExpression(location.initializer)) {
384397
return location.initializer;
385398
}
386399
if (!followingSymbol) {

src/services/codefixes/fixAddMissingMember.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import {
7272
isTypeLiteralNode,
7373
JsxOpeningLikeElement,
7474
LanguageVariant,
75+
lastOrUndefined,
7576
length,
7677
map,
7778
MethodDeclaration,
@@ -584,22 +585,15 @@ function addEnumMemberDeclaration(changes: textChanges.ChangeTracker, checker: T
584585
const type = checker.getTypeAtLocation(member);
585586
return !!(type && type.flags & TypeFlags.StringLike);
586587
});
587-
588+
const sourceFile = parentDeclaration.getSourceFile();
588589
const enumMember = factory.createEnumMember(token, hasStringInitializer ? factory.createStringLiteral(token.text) : undefined);
589-
changes.replaceNode(
590-
parentDeclaration.getSourceFile(),
591-
parentDeclaration,
592-
factory.updateEnumDeclaration(
593-
parentDeclaration,
594-
parentDeclaration.modifiers,
595-
parentDeclaration.name,
596-
concatenate(parentDeclaration.members, singleElementArray(enumMember)),
597-
),
598-
{
599-
leadingTriviaOption: textChanges.LeadingTriviaOption.IncludeAll,
600-
trailingTriviaOption: textChanges.TrailingTriviaOption.Exclude,
601-
},
602-
);
590+
const last = lastOrUndefined(parentDeclaration.members);
591+
if (last) {
592+
changes.insertNodeInListAfter(sourceFile, last, enumMember, parentDeclaration.members);
593+
}
594+
else {
595+
changes.insertMemberAtStart(sourceFile, parentDeclaration, enumMember);
596+
}
603597
}
604598

605599
function addFunctionDeclaration(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: FunctionInfo | SignatureInfo) {
@@ -674,7 +668,7 @@ function tryGetValueFromType(context: CodeFixContextBase, checker: TypeChecker,
674668
}
675669
if (type.flags & TypeFlags.EnumLike) {
676670
const enumMember = type.symbol.exports ? firstOrUndefinedIterator(type.symbol.exports.values()) : type.symbol;
677-
const name = checker.symbolToExpression(type.symbol.parent ? type.symbol.parent : type.symbol, SymbolFlags.Value, /*enclosingDeclaration*/ undefined, /*flags*/ undefined);
671+
const name = checker.symbolToExpression(type.symbol.parent ? type.symbol.parent : type.symbol, SymbolFlags.Value, /*enclosingDeclaration*/ undefined, /*flags*/ NodeBuilderFlags.UseFullyQualifiedType);
678672
return enumMember === undefined || name === undefined ? factory.createNumericLiteral(0) : factory.createPropertyAccessExpression(name, checker.symbolToString(enumMember));
679673
}
680674
if (type.flags & TypeFlags.NumberLiteral) {

0 commit comments

Comments
 (0)