@@ -774,6 +774,7 @@ type Checker struct {
774774 lastFlowNodeReachable bool
775775 flowNodeReachable map[*ast.FlowNode]bool
776776 flowNodePostSuper map[*ast.FlowNode]bool
777+ potentialWeakMapSetCollisions []*ast.Node
777778 renamedBindingElementsInTypes []*ast.Node
778779 contextualInfos []ContextualInfo
779780 inferenceContextInfos []InferenceContextInfo
@@ -2126,6 +2127,7 @@ func (c *Checker) checkSourceFile(ctx context.Context, sourceFile *ast.SourceFil
21262127 // Grammar checking
21272128 c.checkGrammarSourceFile(sourceFile)
21282129 c.renamedBindingElementsInTypes = nil
2130+ c.potentialWeakMapSetCollisions = nil
21292131 c.checkSourceElements(sourceFile.Statements.Nodes)
21302132 c.checkDeferredNodes(sourceFile)
21312133 if ast.IsExternalOrCommonJSModule(sourceFile) {
@@ -2143,6 +2145,12 @@ func (c *Checker) checkSourceFile(ctx context.Context, sourceFile *ast.SourceFil
21432145 } else {
21442146 c.wasCanceled = true
21452147 }
2148+ if len(c.potentialWeakMapSetCollisions) > 0 {
2149+ for _, node := range c.potentialWeakMapSetCollisions {
2150+ c.checkWeakMapSetCollision(node)
2151+ }
2152+ c.potentialWeakMapSetCollisions = nil
2153+ }
21462154 c.ctx = nil
21472155 links.typeChecked = true
21482156 }
@@ -2536,6 +2544,7 @@ func (c *Checker) checkPropertyDeclaration(node *ast.Node) {
25362544 c.checkGrammarComputedPropertyName(node.Name())
25372545 }
25382546 c.checkVariableLikeDeclaration(node)
2547+ c.setNodeLinksForPrivateIdentifierScope(node)
25392548 // property signatures already report "initializer not allowed in ambient context" elsewhere
25402549 if ast.HasSyntacticModifier(node, ast.ModifierFlagsAbstract) && ast.IsPropertyDeclaration(node) {
25412550 if node.Initializer() != nil {
@@ -2633,6 +2642,7 @@ func (c *Checker) checkMethodDeclaration(node *ast.Node) {
26332642 if ast.IsPrivateIdentifier(node.Name()) && ast.GetContainingClass(node) == nil {
26342643 c.error(node, diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies)
26352644 }
2645+ c.setNodeLinksForPrivateIdentifierScope(node)
26362646}
26372647
26382648func (c *Checker) checkClassStaticBlockDeclaration(node *ast.Node) {
@@ -2800,6 +2810,7 @@ func (c *Checker) checkAccessorDeclaration(node *ast.Node) {
28002810 c.checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType)
28012811 }
28022812 c.checkSourceElement(node.Body())
2813+ c.setNodeLinksForPrivateIdentifierScope(node)
28032814}
28042815
28052816func (c *Checker) checkTypeReferenceNode(node *ast.Node) {
@@ -10148,6 +10159,7 @@ func (c *Checker) assignBindingElementTypes(pattern *ast.Node, parentType *Type)
1014810159
1014910160func (c *Checker) checkCollisionsForDeclarationName(node *ast.Node, name *ast.Node) {
1015010161 c.checkCollisionWithRequireExportsInGeneratedCode(node, name)
10162+ c.recordPotentialCollisionWithWeakMapSetInGeneratedCode(node, name)
1015110163 switch {
1015210164 case name == nil:
1015310165 return
@@ -10206,6 +10218,35 @@ func (c *Checker) needCollisionCheckForIdentifier(node *ast.Node, identifier *as
1020610218 return true
1020710219}
1020810220
10221+ func (c *Checker) setNodeLinksForPrivateIdentifierScope(node *ast.Node) {
10222+ if name := node.Name(); ast.IsPrivateIdentifier(name) {
10223+ // Check if we need to mark containers with the ContainsClassWithPrivateIdentifiers flag
10224+ // This happens for older language versions or when useDefineForClassFields is false
10225+ // PrivateNamesAndClassStaticBlocks is ES2022, ClassAndClassElementDecorators is ESNext
10226+ if c.languageVersion < core.ScriptTargetES2022 || c.languageVersion < core.ScriptTargetESNext || !c.emitStandardClassFields {
10227+ for lexicalScope := ast.GetEnclosingBlockScopeContainer(node); lexicalScope != nil; lexicalScope = ast.GetEnclosingBlockScopeContainer(lexicalScope) {
10228+ c.nodeLinks.Get(lexicalScope).flags |= NodeCheckFlagsContainsClassWithPrivateIdentifiers
10229+ }
10230+ }
10231+ }
10232+ }
10233+
10234+ func (c *Checker) recordPotentialCollisionWithWeakMapSetInGeneratedCode(node *ast.Node, name *ast.Node) {
10235+ if c.languageVersion <= core.ScriptTargetES2021 &&
10236+ (c.needCollisionCheckForIdentifier(node, name, "WeakMap") || c.needCollisionCheckForIdentifier(node, name, "WeakSet")) {
10237+ c.potentialWeakMapSetCollisions = append(c.potentialWeakMapSetCollisions, node)
10238+ }
10239+ }
10240+
10241+ func (c *Checker) checkWeakMapSetCollision(node *ast.Node) {
10242+ enclosingBlockScope := ast.GetEnclosingBlockScopeContainer(node)
10243+ if c.nodeLinks.Get(enclosingBlockScope).flags&NodeCheckFlagsContainsClassWithPrivateIdentifiers != 0 {
10244+ if name := node.Name(); ast.IsIdentifier(name) {
10245+ c.errorSkippedOnNoEmit(node, diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, name.Text())
10246+ }
10247+ }
10248+ }
10249+
1020910250func (c *Checker) checkTypeOfExpression(node *ast.Node) *Type {
1021010251 c.checkExpression(node.Expression())
1021110252 return c.typeofType
0 commit comments