From edcd245e3233b50d6af2d7d4307a2b5c002e45e9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 11 Nov 2025 18:19:20 -0800 Subject: [PATCH] Don't add export modifier to KindCommonJSExport reparsed nodes --- internal/ast/parseoptions.go | 3 --- internal/binder/binder.go | 4 ++-- internal/parser/reparser.go | 5 +---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/internal/ast/parseoptions.go b/internal/ast/parseoptions.go index 89960d37e3..a697eceb75 100644 --- a/internal/ast/parseoptions.go +++ b/internal/ast/parseoptions.go @@ -112,9 +112,6 @@ func isFileProbablyExternalModule(sourceFile *SourceFile) *Node { } func isAnExternalModuleIndicatorNode(node *Node) bool { - if node.Flags&NodeFlagsReparsed != 0 { - return false - } return HasSyntacticModifier(node, ModifierFlagsExport) || IsImportEqualsDeclaration(node) && IsExternalModuleReference(node.AsImportEqualsDeclaration().ModuleReference) || IsImportDeclaration(node) || IsExportAssignment(node) || IsExportDeclaration(node) diff --git a/internal/binder/binder.go b/internal/binder/binder.go index e813bb7e19..e7409cea4e 100644 --- a/internal/binder/binder.go +++ b/internal/binder/binder.go @@ -377,7 +377,7 @@ func GetSymbolNameForPrivateIdentifier(containingClassSymbol *ast.Symbol, descri func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags, symbolExcludes ast.SymbolFlags) *ast.Symbol { container := b.container - if node.Kind == ast.KindCommonJSExport { + if ast.IsCommonJSExport(node) { container = b.file.AsNode() } hasExportModifier := ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsExport != 0 || ast.IsImplicitlyExportedJSTypeAlias(node) @@ -402,7 +402,7 @@ func (b *Binder) declareModuleMember(node *ast.Node, symbolFlags ast.SymbolFlags // during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. - if !ast.IsAmbientModule(node) && (hasExportModifier || container.Flags&ast.NodeFlagsExportContext != 0) { + if !ast.IsAmbientModule(node) && (hasExportModifier || ast.IsCommonJSExport(node) || container.Flags&ast.NodeFlagsExportContext != 0) { if !ast.IsLocalsContainer(container) || (ast.HasSyntacticModifier(node, ast.ModifierFlagsDefault) && b.getDeclarationName(node) == ast.InternalSymbolNameMissing) || ast.IsCommonJSExport(node) { return b.declareSymbol(ast.GetExports(container.Symbol()), container.Symbol(), node, symbolFlags, symbolExcludes) // No local symbol for an unnamed default! diff --git a/internal/parser/reparser.go b/internal/parser/reparser.go index f6ec4c5bee..9d3637e303 100644 --- a/internal/parser/reparser.go +++ b/internal/parser/reparser.go @@ -29,12 +29,9 @@ func (p *Parser) reparseCommonJS(node *ast.Node, jsdoc []*ast.Node) { case ast.JSDeclarationKindModuleExports: export = p.factory.NewJSExportAssignment(nil, p.factory.DeepCloneReparse(bin.Right)) case ast.JSDeclarationKindExportsProperty: - mod := p.factory.NewModifier(ast.KindExportKeyword) - mod.Flags = p.contextFlags | ast.NodeFlagsReparsed - mod.Loc = bin.Loc // TODO: Name can sometimes be a string literal, so downstream code needs to handle this export = p.factory.NewCommonJSExport( - p.newModifierList(bin.Loc, p.nodeSlicePool.NewSlice1(mod)), + nil, p.factory.DeepCloneReparse(ast.GetElementOrPropertyAccessName(bin.Left)), nil, /*typeNode*/ p.factory.DeepCloneReparse(bin.Right))