Skip to content

Commit d1008eb

Browse files
committed
Merge branch 'main' into fix-exact-optional-unassignable-properties
2 parents 664d749 + c17fd8c commit d1008eb

File tree

70 files changed

+8253
-96
lines changed

Some content is hidden

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

70 files changed

+8253
-96
lines changed

package-lock.json

Lines changed: 12 additions & 12 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: 123 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ namespace ts {
960960
const potentialThisCollisions: Node[] = [];
961961
const potentialNewTargetCollisions: Node[] = [];
962962
const potentialWeakMapSetCollisions: Node[] = [];
963+
const potentialReflectCollisions: Node[] = [];
963964
const awaitedTypeStack: number[] = [];
964965

965966
const diagnostics = createDiagnosticCollection();
@@ -24888,6 +24889,18 @@ namespace ts {
2488824889

2488924890
if (isStatic(container) || isCallExpression) {
2489024891
nodeCheckFlag = NodeCheckFlags.SuperStatic;
24892+
if (!isCallExpression &&
24893+
languageVersion >= ScriptTarget.ES2015 && languageVersion <= ScriptTarget.ES2021 &&
24894+
(isPropertyDeclaration(container) || isClassStaticBlockDeclaration(container))) {
24895+
// for `super.x` or `super[x]` in a static initializer, mark all enclosing
24896+
// block scope containers so that we can report potential collisions with
24897+
// `Reflect`.
24898+
forEachEnclosingBlockScopeContainer(node.parent, current => {
24899+
if (!isSourceFile(current) || isExternalOrCommonJsModule(current)) {
24900+
getNodeLinks(current).flags |= NodeCheckFlags.ContainsSuperPropertyInStaticInitializer;
24901+
}
24902+
});
24903+
}
2489124904
}
2489224905
else {
2489324906
nodeCheckFlag = NodeCheckFlags.SuperInstance;
@@ -31174,6 +31187,10 @@ namespace ts {
3117431187
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
3117531188
checkNodeDeferred(node);
3117631189

31190+
if (isFunctionExpression(node)) {
31191+
checkCollisionsForDeclarationName(node, node.name);
31192+
}
31193+
3117731194
// The identityMapper object is used to indicate that function expressions are wildcards
3117831195
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
3117931196
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
@@ -34961,8 +34978,7 @@ namespace ts {
3496134978
if (produceDiagnostics) {
3496234979
checkFunctionOrMethodDeclaration(node);
3496334980
checkGrammarForGenerator(node);
34964-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name!);
34965-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name!);
34981+
checkCollisionsForDeclarationName(node, node.name);
3496634982
}
3496734983
}
3496834984

@@ -35485,8 +35501,13 @@ namespace ts {
3548535501
});
3548635502
}
3548735503

35504+
/**
35505+
* Checks whether an {@link Identifier}, in the context of another {@link Node}, would collide with a runtime value
35506+
* of {@link name} in an outer scope. This is used to check for collisions for downlevel transformations that
35507+
* require names like `Object`, `Promise`, `Reflect`, `require`, `exports`, etc.
35508+
*/
3548835509
function needCollisionCheckForIdentifier(node: Node, identifier: Identifier | undefined, name: string): boolean {
35489-
if (!(identifier && identifier.escapedText === name)) {
35510+
if (identifier?.escapedText !== name) {
3549035511
return false;
3549135512
}
3549235513

@@ -35495,8 +35516,9 @@ namespace ts {
3549535516
node.kind === SyntaxKind.MethodDeclaration ||
3549635517
node.kind === SyntaxKind.MethodSignature ||
3549735518
node.kind === SyntaxKind.GetAccessor ||
35498-
node.kind === SyntaxKind.SetAccessor) {
35499-
// it is ok to have member named '_super' or '_this' - member access is always qualified
35519+
node.kind === SyntaxKind.SetAccessor ||
35520+
node.kind === SyntaxKind.PropertyAssignment) {
35521+
// it is ok to have member named '_super', '_this', `Promise`, etc. - member access is always qualified
3550035522
return false;
3550135523
}
3550235524

@@ -35505,8 +35527,15 @@ namespace ts {
3550535527
return false;
3550635528
}
3550735529

35530+
if (isImportClause(node) || isImportEqualsDeclaration(node) || isImportSpecifier(node)) {
35531+
// type-only imports do not require collision checks against runtime values.
35532+
if (isTypeOnlyImportOrExportDeclaration(node)) {
35533+
return false;
35534+
}
35535+
}
35536+
3550835537
const root = getRootDeclaration(node);
35509-
if (root.kind === SyntaxKind.Parameter && nodeIsMissing((root.parent as FunctionLikeDeclaration).body)) {
35538+
if (isParameter(root) && nodeIsMissing((root.parent as FunctionLikeDeclaration).body)) {
3551035539
// just an overload - no codegen impact
3551135540
return false;
3551235541
}
@@ -35547,21 +35576,13 @@ namespace ts {
3554735576
});
3554835577
}
3554935578

35550-
function checkWeakMapSetCollision(node: Node) {
35551-
const enclosingBlockScope = getEnclosingBlockScopeContainer(node);
35552-
if (getNodeCheckFlags(enclosingBlockScope) & NodeCheckFlags.ContainsClassWithPrivateIdentifiers) {
35553-
Debug.assert(isNamedDeclaration(node) && isIdentifier(node.name) && typeof node.name.escapedText === "string", "The target of a WeakMap/WeakSet collision check should be an identifier");
35554-
errorSkippedOn("noEmit", node, Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, node.name.escapedText);
35555-
}
35556-
}
35557-
35558-
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) {
35579+
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier | undefined) {
3555935580
// No need to check for require or exports for ES6 modules and later
3556035581
if (moduleKind >= ModuleKind.ES2015) {
3556135582
return;
3556235583
}
3556335584

35564-
if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
35585+
if (!name || !needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
3556535586
return;
3556635587
}
3556735588

@@ -35579,8 +35600,8 @@ namespace ts {
3557935600
}
3558035601
}
3558135602

35582-
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
35583-
if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
35603+
function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier | undefined): void {
35604+
if (!name || languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) {
3558435605
return;
3558535606
}
3558635607

@@ -35598,6 +35619,76 @@ namespace ts {
3559835619
}
3559935620
}
3560035621

35622+
function recordPotentialCollisionWithWeakMapSetInGeneratedCode(node: Node, name: Identifier): void {
35623+
if (languageVersion <= ScriptTarget.ES2021
35624+
&& (needCollisionCheckForIdentifier(node, name, "WeakMap") || needCollisionCheckForIdentifier(node, name, "WeakSet"))) {
35625+
potentialWeakMapSetCollisions.push(node);
35626+
}
35627+
}
35628+
35629+
function checkWeakMapSetCollision(node: Node) {
35630+
const enclosingBlockScope = getEnclosingBlockScopeContainer(node);
35631+
if (getNodeCheckFlags(enclosingBlockScope) & NodeCheckFlags.ContainsClassWithPrivateIdentifiers) {
35632+
Debug.assert(isNamedDeclaration(node) && isIdentifier(node.name) && typeof node.name.escapedText === "string", "The target of a WeakMap/WeakSet collision check should be an identifier");
35633+
errorSkippedOn("noEmit", node, Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, node.name.escapedText);
35634+
}
35635+
}
35636+
35637+
function recordPotentialCollisionWithReflectInGeneratedCode(node: Node, name: Identifier | undefined): void {
35638+
if (name && languageVersion >= ScriptTarget.ES2015 && languageVersion <= ScriptTarget.ES2021
35639+
&& needCollisionCheckForIdentifier(node, name, "Reflect")) {
35640+
potentialReflectCollisions.push(node);
35641+
}
35642+
}
35643+
35644+
function checkReflectCollision(node: Node) {
35645+
let hasCollision = false;
35646+
if (isClassExpression(node)) {
35647+
// ClassExpression names don't contribute to their containers, but do matter for any of their block-scoped members.
35648+
for (const member of node.members) {
35649+
if (getNodeCheckFlags(member) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) {
35650+
hasCollision = true;
35651+
break;
35652+
}
35653+
}
35654+
}
35655+
else if (isFunctionExpression(node)) {
35656+
// FunctionExpression names don't contribute to their containers, but do matter for their contents
35657+
if (getNodeCheckFlags(node) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) {
35658+
hasCollision = true;
35659+
}
35660+
}
35661+
else {
35662+
const container = getEnclosingBlockScopeContainer(node);
35663+
if (container && getNodeCheckFlags(container) & NodeCheckFlags.ContainsSuperPropertyInStaticInitializer) {
35664+
hasCollision = true;
35665+
}
35666+
}
35667+
if (hasCollision) {
35668+
Debug.assert(isNamedDeclaration(node) && isIdentifier(node.name), "The target of a Reflect collision check should be an identifier");
35669+
errorSkippedOn("noEmit", node, Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_when_emitting_super_references_in_static_initializers,
35670+
declarationNameToString(node.name),
35671+
"Reflect");
35672+
}
35673+
}
35674+
35675+
function checkCollisionsForDeclarationName(node: Node, name: Identifier | undefined) {
35676+
if (!name) return;
35677+
checkCollisionWithRequireExportsInGeneratedCode(node, name);
35678+
checkCollisionWithGlobalPromiseInGeneratedCode(node, name);
35679+
recordPotentialCollisionWithWeakMapSetInGeneratedCode(node, name);
35680+
recordPotentialCollisionWithReflectInGeneratedCode(node, name);
35681+
if (isClassLike(node)) {
35682+
checkTypeNameIsReserved(name, Diagnostics.Class_name_cannot_be_0);
35683+
if (!(node.flags & NodeFlags.Ambient)) {
35684+
checkClassNameCollisionWithObject(name);
35685+
}
35686+
}
35687+
else if (isEnumDeclaration(node)) {
35688+
checkTypeNameIsReserved(name, Diagnostics.Enum_name_cannot_be_0);
35689+
}
35690+
}
35691+
3560135692
function checkVarDeclaredNamesNotShadowed(node: VariableDeclaration | BindingElement) {
3560235693
// - ScriptBody : StatementList
3560335694
// It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
@@ -35816,12 +35907,7 @@ namespace ts {
3581635907
if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) {
3581735908
checkVarDeclaredNamesNotShadowed(node);
3581835909
}
35819-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
35820-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
35821-
if (languageVersion < ScriptTarget.ESNext
35822-
&& (needCollisionCheckForIdentifier(node, node.name, "WeakMap") || needCollisionCheckForIdentifier(node, node.name, "WeakSet"))) {
35823-
potentialWeakMapSetCollisions.push(node);
35824-
}
35910+
checkCollisionsForDeclarationName(node, node.name);
3582535911
}
3582635912
}
3582735913

@@ -37380,14 +37466,7 @@ namespace ts {
3738037466
function checkClassLikeDeclaration(node: ClassLikeDeclaration) {
3738137467
checkGrammarClassLikeDeclaration(node);
3738237468
checkDecorators(node);
37383-
if (node.name) {
37384-
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
37385-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
37386-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
37387-
if (!(node.flags & NodeFlags.Ambient)) {
37388-
checkClassNameCollisionWithObject(node.name);
37389-
}
37390-
}
37469+
checkCollisionsForDeclarationName(node, node.name);
3739137470
checkTypeParameters(getEffectiveTypeParameterDeclarations(node));
3739237471
checkExportsOnMergedDeclarations(node);
3739337472
const symbol = getSymbolOfNode(node);
@@ -38114,9 +38193,7 @@ namespace ts {
3811438193
// Grammar checking
3811538194
checkGrammarDecoratorsAndModifiers(node);
3811638195

38117-
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
38118-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
38119-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
38196+
checkCollisionsForDeclarationName(node, node.name);
3812038197
checkExportsOnMergedDeclarations(node);
3812138198
node.members.forEach(checkEnumMember);
3812238199

@@ -38225,8 +38302,7 @@ namespace ts {
3822538302
}
3822638303

3822738304
if (isIdentifier(node.name)) {
38228-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
38229-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
38305+
checkCollisionsForDeclarationName(node, node.name);
3823038306
}
3823138307

3823238308
checkExportsOnMergedDeclarations(node);
@@ -38443,8 +38519,7 @@ namespace ts {
3844338519
}
3844438520

3844538521
function checkImportBinding(node: ImportEqualsDeclaration | ImportClause | NamespaceImport | ImportSpecifier) {
38446-
checkCollisionWithRequireExportsInGeneratedCode(node, node.name!);
38447-
checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name!);
38522+
checkCollisionsForDeclarationName(node, node.name);
3844838523
checkAliasSymbol(node);
3844938524
if (node.kind === SyntaxKind.ImportSpecifier &&
3845038525
idText(node.propertyName || node.name) === "default" &&
@@ -39162,6 +39237,7 @@ namespace ts {
3916239237
clear(potentialThisCollisions);
3916339238
clear(potentialNewTargetCollisions);
3916439239
clear(potentialWeakMapSetCollisions);
39240+
clear(potentialReflectCollisions);
3916539241

3916639242
forEach(node.statements, checkSourceElement);
3916739243
checkSourceElement(node.endOfFileToken);
@@ -39206,6 +39282,11 @@ namespace ts {
3920639282
clear(potentialWeakMapSetCollisions);
3920739283
}
3920839284

39285+
if (potentialReflectCollisions.length) {
39286+
forEach(potentialReflectCollisions, checkReflectCollision);
39287+
clear(potentialReflectCollisions);
39288+
}
39289+
3920939290
links.flags |= NodeCheckFlags.TypeChecked;
3921039291
}
3921139292
}
@@ -40318,7 +40399,9 @@ namespace ts {
4031840399
}
4031940400

4032040401
function getNodeCheckFlags(node: Node): NodeCheckFlags {
40321-
return getNodeLinks(node).flags || 0;
40402+
const nodeId = node.id || 0;
40403+
if (nodeId < 0 || nodeId >= nodeLinks.length) return 0;
40404+
return nodeLinks[nodeId]?.flags || 0;
4032240405
}
4032340406

4032440407
function getEnumMemberValue(node: EnumMember): string | number | undefined {

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,10 @@
33563356
"category": "Error",
33573357
"code": 2817
33583358
},
3359+
"Duplicate identifier '{0}'. Compiler reserves name '{1}' when emitting 'super' references in static initializers.": {
3360+
"category": "Error",
3361+
"code": 2818
3362+
},
33593363

33603364
"Import declaration '{0}' is using private name '{1}'.": {
33613365
"category": "Error",

src/compiler/moduleNameResolver.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ namespace ts {
494494
export interface PackageJsonInfoCache {
495495
/*@internal*/ getPackageJsonInfo(packageJsonPath: string): PackageJsonInfo | boolean | undefined;
496496
/*@internal*/ setPackageJsonInfo(packageJsonPath: string, info: PackageJsonInfo | boolean): void;
497+
/*@internal*/ entries(): [Path, PackageJsonInfo | boolean][];
497498
clear(): void;
498499
}
499500

@@ -559,7 +560,7 @@ namespace ts {
559560

560561
function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache {
561562
let cache: ESMap<Path, PackageJsonInfo | boolean> | undefined;
562-
return { getPackageJsonInfo, setPackageJsonInfo, clear };
563+
return { getPackageJsonInfo, setPackageJsonInfo, clear, entries };
563564
function getPackageJsonInfo(packageJsonPath: string) {
564565
return cache?.get(toPath(packageJsonPath, currentDirectory, getCanonicalFileName));
565566
}
@@ -569,6 +570,10 @@ namespace ts {
569570
function clear() {
570571
cache = undefined;
571572
}
573+
function entries() {
574+
const iter = cache?.entries();
575+
return iter ? arrayFrom(iter) : [];
576+
}
572577
}
573578

574579
function getOrCreateCache<T>(cacheWithRedirects: CacheWithRedirects<T>, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T {

0 commit comments

Comments
 (0)