Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/typescript/src/enums/checkFlags.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export enum CheckFlags {
IsDiscriminantComputed = 1 << 24,
IsDiscriminant = 1 << 25,
IndexSymbol = 1 << 26,
ExportConflict = 1 << 27,
Synthetic = SyntheticProperty | SyntheticMethod,
NonUniformAndLiteral = HasNonUniformType | HasLiteralType,
Partial = ReadPartial | WritePartial,
Expand Down
1 change: 1 addition & 0 deletions packages/typescript/src/enums/checkFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export var CheckFlags: any;
CheckFlags[CheckFlags["IsDiscriminantComputed"] = 16777216] = "IsDiscriminantComputed";
CheckFlags[CheckFlags["IsDiscriminant"] = 33554432] = "IsDiscriminant";
CheckFlags[CheckFlags["IndexSymbol"] = 67108864] = "IndexSymbol";
CheckFlags[CheckFlags["ExportConflict"] = 134217728] = "ExportConflict";
CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
CheckFlags[CheckFlags["NonUniformAndLiteral"] = 192] = "NonUniformAndLiteral";
CheckFlags[CheckFlags["Partial"] = 48] = "Partial";
Expand Down
1 change: 1 addition & 0 deletions tsc/internal/api/enum_values_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tsc/internal/ast/checkflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
CheckFlagsIsDiscriminantComputed CheckFlags = 1 << 24 // IsDiscriminant flags has been computed
CheckFlagsIsDiscriminant CheckFlags = 1 << 25 // Discriminant property
CheckFlagsIndexSymbol CheckFlags = 1 << 26 // Synthetic property created from index signature
CheckFlagsExportConflict CheckFlags = 1 << 27 // Ambiguous export from multiple export * declarations
CheckFlagsSynthetic = CheckFlagsSyntheticProperty | CheckFlagsSyntheticMethod
CheckFlagsNonUniformAndLiteral = CheckFlagsHasNonUniformType | CheckFlagsHasLiteralType
CheckFlagsPartial = CheckFlagsReadPartial | CheckFlagsWritePartial
Expand Down
117 changes: 62 additions & 55 deletions tsc/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -11559,6 +11559,10 @@ func (c *Checker) checkPropertyAccessExpressionOrQualifiedName(node *ast.Node, l
}
prop = c.getPropertyOfTypeEx(apparentType, right.Text(), isConstEnumObjectType(apparentType) /*skipObjectFunctionPropertyAugment*/, node.Kind == ast.KindQualifiedName /*includeTypeOnlyMembers*/)
}
if c.checkExportConflict(prop, right) {
c.symbolNodeLinks.Get(node).resolvedSymbol = prop
return c.errorType
}
c.markLinkedReferences(node, ReferenceHintProperty, prop, leftType)
var propType *Type
if prop == nil {
Expand Down Expand Up @@ -14890,23 +14894,7 @@ func (c *Checker) reportNonDefaultExport(moduleSymbol *ast.Symbol, node *ast.Nod
if moduleSymbol.Exports() != nil && moduleSymbol.Exports()[node.Symbol().Name()] != nil {
c.error(node, diagnostics.Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead, c.symbolToString(moduleSymbol), c.symbolToString(node.Symbol()))
} else {
diagnostic := c.error(node.Name(), diagnostics.Module_0_has_no_default_export, c.symbolToString(moduleSymbol))
var exportStar *ast.Symbol
if moduleSymbol.Exports() != nil {
exportStar = moduleSymbol.Exports()[ast.InternalSymbolNameExportStar]
}
if exportStar != nil {
defaultExport := core.Find(exportStar.Declarations(), func(decl *ast.Declaration) bool {
if !(ast.IsExportDeclaration(decl) && decl.ModuleSpecifier() != nil) {
return false
}
resolvedExternalModuleName := c.resolveExternalModuleName(decl, decl.ModuleSpecifier(), false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(decl)))
return resolvedExternalModuleName != nil && resolvedExternalModuleName.Exports()[ast.InternalSymbolNameDefault] != nil
})
if defaultExport != nil {
diagnostic.AddRelatedInfo(createDiagnosticForNode(defaultExport, diagnostics.X_export_Asterisk_does_not_re_export_a_default))
}
}
c.error(node.Name(), diagnostics.Module_0_has_no_default_export, c.symbolToString(moduleSymbol))
}
}

Expand All @@ -14916,10 +14904,18 @@ func (c *Checker) resolveExportByName(moduleSymbol *ast.Symbol, name string, sou
if exportValue != nil {
exportSymbol = c.getPropertyOfTypeEx(c.getTypeOfSymbol(exportValue), name, true /*skipObjectFunctionPropertyAugment*/, false /*includeTypeOnlyMembers*/)
} else {
exportSymbol = moduleSymbol.Exports()[name]
exportSymbol = c.getExportsOfModule(moduleSymbol)[name]
}
resolved := c.resolveSymbolEx(exportSymbol, dontResolveAlias)
c.markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, nil)
var errorNode *ast.Node
if sourceNode != nil {
errorNode = sourceNode.Name()
if ast.IsImportOrExportSpecifier(sourceNode) {
errorNode = sourceNode.PropertyNameOrName()
}
}
c.checkExportConflict(c.resolveSymbol(exportSymbol), errorNode)
c.markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, c.moduleSymbolLinks.Get(moduleSymbol).typeOnlyExportStarMap[name])
return resolved
}

Expand Down Expand Up @@ -15093,13 +15089,29 @@ func (c *Checker) getExportOfModule(symbol *ast.Symbol, nameText string, specifi
if symbol.Flags()&ast.SymbolFlagsModule != 0 {
exportSymbol := c.getExportsOfSymbol(symbol)[nameText]
resolved := c.resolveSymbolEx(exportSymbol, dontResolveAlias)
errorNode := specifier
if ast.IsImportOrExportSpecifier(specifier) || ast.IsBindingElement(specifier) {
errorNode = specifier.PropertyNameOrName()
}
c.checkExportConflict(c.resolveSymbol(exportSymbol), errorNode)
exportStarDeclaration := c.moduleSymbolLinks.Get(symbol).typeOnlyExportStarMap[nameText]
c.markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportStarDeclaration)
return resolved
}
return nil
}

func (c *Checker) checkExportConflict(symbol *ast.Symbol, node *ast.Node) bool {
symbol = c.resolveSymbol(symbol)
if symbol == nil || symbol.CheckFlags()&ast.CheckFlagsExportConflict == 0 {
return false
}
if node != nil {
c.error(node, diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, c.symbolToString(symbol.Parent()), symbol.Name())
}
return true
}

func (c *Checker) isOnlyImportableAsDefault(usage *ast.Node, resolvedModule *ast.Symbol, importAttributesType *Type) bool {
// In Node.js, JSON modules don't get named exports
if core.ModuleKindNode16 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext {
Expand Down Expand Up @@ -15153,7 +15165,7 @@ func (c *Checker) canHaveSyntheticDefault(file *ast.Node, moduleSymbol *ast.Symb
if file == nil || file.AsSourceFile().IsDeclarationFile {
// Definitely cannot have a synthetic default if they have a syntactic default member specified
defaultExportSymbol := c.resolveExportByName(moduleSymbol, ast.InternalSymbolNameDefault /*sourceNode*/, nil /*dontResolveAlias*/, true) // Dont resolve alias because we want the immediately exported symbol's declaration
if defaultExportSymbol != nil && core.Some(defaultExportSymbol.Declarations(), isSyntacticDefault) {
if defaultExportSymbol != nil && (c.resolveSymbol(defaultExportSymbol).CheckFlags()&ast.CheckFlagsExportConflict != 0 || core.Some(defaultExportSymbol.Declarations(), isSyntacticDefault)) {
return false
}
// It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
Expand Down Expand Up @@ -16225,8 +16237,8 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as
if namespace == nil || ast.NodeIsMissing(right) {
return nil
}
if namespace == c.unknownSymbol {
return namespace
if namespace == c.unknownSymbol || namespace.CheckFlags()&ast.CheckFlagsExportConflict != 0 {
return c.unknownSymbol
}
if namespace.ValueDeclaration() != nil &&
ast.IsInJSFile(namespace.ValueDeclaration()) &&
Expand All @@ -16249,6 +16261,9 @@ func (c *Checker) resolveQualifiedName(name *ast.Node, left *ast.Node, right *as
// `namespace` can be resolved further if there was a symbol merge with a re-export
symbol = c.getMergedSymbol(c.getSymbol(c.getExportsOfSymbol(c.resolveAlias(namespace)), text, meaning))
}
if !ignoreErrors {
c.checkExportConflict(c.resolveSymbol(symbol), right)
}
if symbol == nil {
if !ignoreErrors {
namespaceName := c.getFullyQualifiedName(namespace, nil /*containingLocation*/)
Expand Down Expand Up @@ -16533,13 +16548,6 @@ func (c *Checker) getExportsOfModule(moduleSymbol *ast.Symbol) ast.SymbolTable {
return links.resolvedExports
}

type ExportCollision struct {
specifierText string
exportsWithDuplicate []*ast.Node
}

type ExportCollisionTable = map[string]*ExportCollision

func (c *Checker) getExportsOfModuleWorker(moduleSymbol *ast.Symbol) (exports ast.SymbolTable, typeOnlyExportStarMap map[string]*ast.Node) {
var visitedSymbols []*ast.Symbol
nonTypeOnlyNames := collections.NewSetWithSizeHint[string](len(moduleSymbol.Exports()))
Expand All @@ -16564,22 +16572,12 @@ func (c *Checker) getExportsOfModuleWorker(moduleSymbol *ast.Symbol) (exports as
exportStars := symbol.Exports()[ast.InternalSymbolNameExportStar]
if exportStars != nil {
nestedSymbols := make(ast.SymbolTable)
lookupTable := make(ExportCollisionTable)
for _, node := range exportStars.Declarations() {
resolvedModule := c.resolveExternalModuleName(node, node.ModuleSpecifier(), false /*ignoreErrors*/, c.getTypeFromImportAttributes(ast.GetImportAttributes(node)))
exportedSymbols := visit(resolvedModule, node, isTypeOnly || node.IsTypeOnly())
c.extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable, node)
}
for id, s := range lookupTable {
// It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
if id == ast.InternalSymbolNameExportEquals || len(s.exportsWithDuplicate) == 0 || symbols[id] != nil {
continue
}
for _, node := range s.exportsWithDuplicate {
c.addDiagnostic(createDiagnosticForNode(node, diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, s.specifierText, id))
}
c.extendExportSymbols(nestedSymbols, exportedSymbols, symbol)
}
c.extendExportSymbols(symbols, nestedSymbols, nil, nil)
c.extendExportSymbols(symbols, nestedSymbols, nil)
}
if exportStar != nil && exportStar.IsTypeOnly() {
if typeOnlyExportStarMap == nil {
Expand Down Expand Up @@ -16623,26 +16621,20 @@ func (c *Checker) getExportsOfModuleWorker(moduleSymbol *ast.Symbol) (exports as
return exports, typeOnlyExportStarMap
}

/**
* Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
* Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
*/
func (c *Checker) extendExportSymbols(target ast.SymbolTable, source ast.SymbolTable, lookupTable ExportCollisionTable, exportNode *ast.Node) {
// A non-nil moduleSymbol collects conflicting star exports. Explicit exports are
// merged afterward without conflicts, so they take precedence over star exports.
func (c *Checker) extendExportSymbols(target ast.SymbolTable, source ast.SymbolTable, moduleSymbol *ast.Symbol) {
for id, sourceSymbol := range source {
if id == ast.InternalSymbolNameDefault {
if id == ast.InternalSymbolNameExportStar || id == ast.InternalSymbolNameExportEquals {
continue
}
targetSymbol := target[id]
if targetSymbol == nil {
target[id] = sourceSymbol
if lookupTable != nil && exportNode != nil {
lookupTable[id] = &ExportCollision{
specifierText: scanner.GetTextOfNode(exportNode.ModuleSpecifier()),
}
}
} else if lookupTable != nil && exportNode != nil && c.resolveSymbol(targetSymbol) != c.resolveSymbol(sourceSymbol) {
s := lookupTable[id]
s.exportsWithDuplicate = append(s.exportsWithDuplicate, exportNode)
} else if moduleSymbol != nil && targetSymbol.CheckFlags()&ast.CheckFlagsExportConflict == 0 && c.resolveSymbol(targetSymbol) != c.resolveSymbol(sourceSymbol) {
conflict := c.newSymbolEx(ast.SymbolFlagsProperty|ast.SymbolFlagsTypeAlias|ast.SymbolFlagsNamespaceModule, id, ast.CheckFlagsExportConflict)
conflict.SetParent(moduleSymbol)
target[id] = conflict
}
}
}
Expand Down Expand Up @@ -16886,6 +16878,9 @@ func (c *Checker) GetTypeOfSymbolAtLocation(symbol *ast.Symbol, location *ast.No
}

func (c *Checker) getTypeOfSymbol(symbol *ast.Symbol) *Type {
if symbol.CheckFlags()&ast.CheckFlagsExportConflict != 0 {
return c.errorType
}
if symbol.CheckFlags()&ast.CheckFlagsDeferredType != 0 {
return c.getTypeOfSymbolWithDeferredType(symbol)
}
Expand Down Expand Up @@ -24206,6 +24201,8 @@ func (c *Checker) getDeclaredTypeOfSymbol(symbol *ast.Symbol) *Type {

func (c *Checker) tryGetDeclaredTypeOfSymbol(symbol *ast.Symbol) *Type {
switch {
case symbol.CheckFlags()&ast.CheckFlagsExportConflict != 0:
return c.errorType
case symbol.Flags()&(ast.SymbolFlagsClass|ast.SymbolFlagsInterface) != 0:
return c.getDeclaredTypeOfClassOrInterface(symbol)
case symbol.Flags()&ast.SymbolFlagsTypeParameter != 0:
Expand Down Expand Up @@ -27558,6 +27555,16 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy
}
prop := c.getPropertyOfType(objectType, propName)
if prop != nil {
var errorNode *ast.Node
if accessNode != nil {
errorNode = getIndexNodeForAccessExpression(accessNode)
}
if c.checkExportConflict(prop, errorNode) {
if accessExpression != nil && accessFlags&AccessFlagsCacheSymbol != 0 {
c.symbolNodeLinks.Get(accessNode).resolvedSymbol = prop
}
return c.errorType
}
if accessFlags&AccessFlagsReportDeprecated != 0 && accessNode != nil && len(prop.Declarations()) != 0 && c.isDeprecatedSymbol(prop) && c.isUncalledFunctionReference(accessNode, prop) {
var deprecatedNode *ast.Node
if accessExpression != nil {
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/printer/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ var exportStarHelper = &EmitHelper{
Dependencies: []*EmitHelper{createBindingHelper},
Priority: &Priority{2},
Text: `var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};`,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func collectExternalModuleInfo(sourceFile *ast.SourceFile, compilerOptions *core
func (c *externalModuleInfoCollector) collect() *externalModuleInfo {
hasImportStar := false
hasImportDefault := false
hasDefaultToInitialize := false
for _, node := range c.sourceFile.Statements.Nodes {
// Look through NotEmittedStatement to find elided export= declarations
// (e.g., `declare export = x` is elided by the type eraser but must still be collected)
Expand Down Expand Up @@ -118,6 +119,8 @@ func (c *externalModuleInfoCollector) collect() *externalModuleInfo {
if n.IsExportEquals && c.output.exportEquals == nil {
// export = x
c.output.exportEquals = n
} else if !n.IsExportEquals {
hasDefaultToInitialize = true
}

case ast.KindVariableStatement:
Expand All @@ -138,6 +141,7 @@ func (c *externalModuleInfoCollector) collect() *externalModuleInfo {
n := node.AsClassDeclaration()
if ast.HasSyntacticModifier(node, ast.ModifierFlagsExport) {
if ast.HasSyntacticModifier(node, ast.ModifierFlagsDefault) {
hasDefaultToInitialize = true
// export default class { }
if !c.hasExportDefault {
name := n.Name()
Expand All @@ -160,6 +164,9 @@ func (c *externalModuleInfoCollector) collect() *externalModuleInfo {
}
}
}
if hasDefaultToInitialize && c.output.hasExportStarsToExportValues && c.addUniqueExport("default") {
c.addExportedName(c.emitContext.Factory.NewIdentifier("default"))
}

return c.output
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("../../core/_namespaces/ts"), exports);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./thingB"), exports);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("@emotion/core"), exports);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./keys"), exports);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./keys"), exports);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "__esModule" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./keys"), exports);
Expand Down

This file was deleted.

Loading