Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
106 changes: 83 additions & 23 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5162,7 +5162,7 @@ func (c *Checker) checkImportAttributes(declaration *ast.Node) {
return
}

if c.moduleKind == core.ModuleKindNodeNext && !isImportAttributes {
if core.ModuleKindNode20 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext && !isImportAttributes {
c.grammarErrorOnNode(node, diagnostics.Import_assertions_have_been_replaced_by_import_attributes_Use_with_instead_of_assert)
return
}
Expand Down Expand Up @@ -13890,6 +13890,12 @@ func (c *Checker) getTargetOfImportEqualsDeclaration(node *ast.Node, dontResolve
}
immediate := c.resolveExternalModuleName(node, moduleReference, false /*ignoreErrors*/)
resolved := c.resolveExternalModuleSymbol(immediate, false /*dontResolveAlias*/)
if resolved != nil && core.ModuleKindNode20 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext {
moduleExports := c.getExportOfModule(resolved, ast.InternalSymbolNameModuleExports, node, dontResolveAlias)
if moduleExports != nil {
return moduleExports
}
}
c.markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, false /*overwriteEmpty*/, nil, "")
return resolved
}
Expand Down Expand Up @@ -13959,14 +13965,42 @@ func (c *Checker) getTargetOfImportClause(node *ast.Node, dontResolveAlias bool)
}

func (c *Checker) getTargetOfModuleDefault(moduleSymbol *ast.Symbol, node *ast.Node, dontResolveAlias bool) *ast.Symbol {
file := core.Find(moduleSymbol.Declarations, ast.IsSourceFile)
specifier := c.getModuleSpecifierForImportOrExport(node)
var exportDefaultSymbol *ast.Symbol
var exportModuleDotExportsSymbol *ast.Symbol
if isShorthandAmbientModuleSymbol(moduleSymbol) {
exportDefaultSymbol = moduleSymbol
// !!! exportDefaultSymbol = moduleSymbol
// Does nothing?
} else if file != nil && specifier != nil &&
core.ModuleKindNode20 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext &&
c.getEmitSyntaxForModuleSpecifierExpression(specifier) == core.ModuleKindCommonJS &&
c.program.GetImpliedNodeFormatForEmit(file.AsSourceFile()) == core.ModuleKindESNext {
exportModuleDotExportsSymbol = c.resolveExportByName(moduleSymbol, ast.InternalSymbolNameModuleExports, node, dontResolveAlias)
}
if exportModuleDotExportsSymbol != nil {
// We have a transpiled default import where the `require` resolves to an ES module with a `module.exports` named
// export. If `esModuleInterop` is enabled, this will work:
//
// const dep_1 = __importDefault(require("./dep.mjs")); // wraps like { default: require("./dep.mjs") }
// dep_1.default; // require("./dep.mjs") -> the `module.exports` export value
//
// But without `esModuleInterop`, it will be broken:
//
// const dep_1 = require("./dep.mjs"); // the `module.exports` export value (could be primitive)
// dep_1.default; // `default` property access on the `module.exports` export value
//
// We could try to resolve the 'default' property in the latter case, but it's a mistake to run in this
// environment without `esModuleInterop`, so just error.
if !c.compilerOptions.GetESModuleInterop() {
c.error(node.Name(), diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, c.symbolToString(moduleSymbol), "esModuleInterop")
return nil
}
c.markSymbolOfAliasDeclarationIfTypeOnly(node, exportModuleDotExportsSymbol /*finalTarget*/, nil /*overwriteEmpty*/, false, nil, "")
return exportModuleDotExportsSymbol
} else {
exportDefaultSymbol = c.resolveExportByName(moduleSymbol, ast.InternalSymbolNameDefault, node, dontResolveAlias)
}
file := core.Find(moduleSymbol.Declarations, ast.IsSourceFile)
specifier := c.getModuleSpecifierForImportOrExport(node)
if specifier == nil {
return exportDefaultSymbol
}
Expand Down Expand Up @@ -14948,7 +14982,11 @@ func (c *Checker) resolveESModuleSymbol(moduleSymbol *ast.Symbol, referencingLoc
return symbol
}
referenceParent := referencingLocation.Parent
if ast.IsImportDeclaration(referenceParent) && ast.GetNamespaceDeclarationNode(referenceParent) != nil || ast.IsImportCall(referenceParent) {
var namespaceImport *ast.Node
if ast.IsImportDeclaration(referenceParent) {
namespaceImport = ast.GetNamespaceDeclarationNode(referenceParent)
}
if namespaceImport != nil || ast.IsImportCall(referenceParent) {
var reference *ast.Node
if ast.IsImportCall(referenceParent) {
reference = referenceParent.AsCallExpression().Arguments.Nodes[0]
Expand All @@ -14960,29 +14998,51 @@ func (c *Checker) resolveESModuleSymbol(moduleSymbol *ast.Symbol, referencingLoc
if defaultOnlyType != nil {
return c.cloneTypeAsModuleType(symbol, defaultOnlyType, referenceParent)
}
// !!!
// targetFile := moduleSymbol. /* ? */ declarations. /* ? */ find(isSourceFile)
// isEsmCjsRef := targetFile && c.isESMFormatImportImportingCommonjsFormatFile(c.getEmitSyntaxForModuleSpecifierExpression(reference), host.getImpliedNodeFormatForEmit(targetFile))
// if c.compilerOptions.GetESModuleInterop() || isEsmCjsRef {
// sigs := c.getSignaturesOfStructuredType(type_, SignatureKindCall)
// if !sigs || !sigs.length {
// sigs = c.getSignaturesOfStructuredType(type_, SignatureKindConstruct)
// }
// if (sigs && sigs.length) || c.getPropertyOfType(type_, ast.InternalSymbolNameDefault /*skipObjectFunctionPropertyAugment*/, true) || isEsmCjsRef {
// var moduleType *Type
// if type_.flags & TypeFlagsStructuredType {
// moduleType = c.getTypeWithSyntheticDefaultImportType(type_, symbol, moduleSymbol, reference)
// } else {
// moduleType = c.createDefaultPropertyWrapperForModule(symbol, symbol.parent)
// }
// return c.cloneTypeAsModuleType(symbol, moduleType, referenceParent)
// }
// }

targetFile := core.Find(moduleSymbol.Declarations, ast.IsSourceFile)
usageMode := c.getEmitSyntaxForModuleSpecifierExpression(reference)
var exportModuleDotExportsSymbol *ast.Symbol
if namespaceImport != nil && targetFile != nil &&
core.ModuleKindNode20 <= c.moduleKind && c.moduleKind <= core.ModuleKindNodeNext &&
usageMode == core.ModuleKindCommonJS &&
c.program.GetImpliedNodeFormatForEmit(targetFile.AsSourceFile()) == core.ModuleKindESNext {
exportModuleDotExportsSymbol = c.getExportOfModule(symbol, ast.InternalSymbolNameModuleExports, namespaceImport, dontResolveAlias)
}
if exportModuleDotExportsSymbol != nil {
if !suppressInteropError && symbol.Flags&(ast.SymbolFlagsModule|ast.SymbolFlagsVariable) == 0 {
c.error(referencingLocation, diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, "esModuleInterop")
}
if c.compilerOptions.GetESModuleInterop() && c.hasSignatures(typ) {
return c.cloneTypeAsModuleType(exportModuleDotExportsSymbol, typ, referenceParent)
}
return exportModuleDotExportsSymbol
}

isEsmCjsRef := targetFile != nil && isESMFormatImportImportingCommonjsFormatFile(usageMode, c.program.GetImpliedNodeFormatForEmit(targetFile.AsSourceFile()))
if c.compilerOptions.GetESModuleInterop() || isEsmCjsRef {
if c.hasSignatures(typ) || c.getPropertyOfTypeEx(typ, ast.InternalSymbolNameDefault, true /*skipObjectFunctionPropertyAugment*/, false /*includeTypeOnlyMembers*/) != nil || isEsmCjsRef {
var moduleType *Type
if typ.Flags()&TypeFlagsStructuredType != 0 {
moduleType = c.getTypeWithSyntheticDefaultImportType(typ, symbol, moduleSymbol, reference)
} else {
moduleType = c.createDefaultPropertyWrapperForModule(symbol, symbol.Parent, nil)
}
return c.cloneTypeAsModuleType(symbol, moduleType, referenceParent)
}
}
Comment on lines +15002 to +15032
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit is the code that's causing the circularity. Perhaps that's why it was commented out originally?

}
}
return symbol
}

func (c *Checker) hasSignatures(t *Type) bool {
return len(c.getSignaturesOfStructuredType(t, SignatureKindCall)) > 0 || len(c.getSignaturesOfStructuredType(t, SignatureKindConstruct)) > 0
}

func isESMFormatImportImportingCommonjsFormatFile(usageMode core.ResolutionMode, targetMode core.ResolutionMode) bool {
return usageMode == core.ModuleKindESNext && targetMode == core.ModuleKindCommonJS
}

func (c *Checker) getTypeWithSyntheticDefaultOnly(t *Type, symbol *ast.Symbol, originalSymbol *ast.Symbol, moduleSpecifier *ast.Node) *Type {
hasDefaultOnly := c.isOnlyImportableAsDefault(moduleSpecifier, nil)
if hasDefaultOnly && t != nil && !c.isErrorType(t) {
Expand Down
3 changes: 2 additions & 1 deletion internal/checker/grammarchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ func (c *Checker) checkGrammarForInOrForOfStatement(forInOrOfStatement *ast.ForI
c.diagnostics.Add(createDiagnosticForNode(forInOrOfStatement.AwaitModifier, diagnostics.X_for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module))
}
switch c.moduleKind {
case core.ModuleKindNode16, core.ModuleKindNode18, core.ModuleKindNodeNext:
case core.ModuleKindNode16, core.ModuleKindNode18, core.ModuleKindNode20, core.ModuleKindNodeNext:
sourceFileMetaData := c.program.GetSourceFileMetaData(sourceFile.Path())
if sourceFileMetaData.ImpliedNodeFormat == core.ModuleKindCommonJS {
c.diagnostics.Add(createDiagnosticForNode(forInOrOfStatement.AwaitModifier, diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level))
Expand Down Expand Up @@ -1752,6 +1752,7 @@ func (c *Checker) checkGrammarAwaitOrAwaitUsing(node *ast.Node) bool {
switch c.moduleKind {
case core.ModuleKindNode16,
core.ModuleKindNode18,
core.ModuleKindNode20,
core.ModuleKindNodeNext:
sourceFileMetaData := c.program.GetSourceFileMetaData(sourceFile.Path())
if sourceFileMetaData.ImpliedNodeFormat == core.ModuleKindCommonJS {
Expand Down
1 change: 1 addition & 0 deletions internal/compiler/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func getModuleTransformer(opts *transformers.TransformOptions) *transformers.Tra
core.ModuleKindES2022,
core.ModuleKindES2020,
core.ModuleKindES2015,
core.ModuleKindNode20,
core.ModuleKindNode18,
core.ModuleKindNode16,
core.ModuleKindNodeNext,
Expand Down
13 changes: 10 additions & 3 deletions internal/core/compileroptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ func (options *CompilerOptions) GetEmitScriptTarget() ScriptTarget {
switch options.GetEmitModuleKind() {
case ModuleKindNode16, ModuleKindNode18:
return ScriptTargetES2022
case ModuleKindNode20:
return ScriptTargetES2023
case ModuleKindNodeNext:
return ScriptTargetESNext
default:
Expand All @@ -212,7 +214,7 @@ func (options *CompilerOptions) GetModuleResolutionKind() ModuleResolutionKind {
return options.ModuleResolution
}
switch options.GetEmitModuleKind() {
case ModuleKindNode16, ModuleKindNode18:
case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20:
return ModuleResolutionKindNode16
case ModuleKindNodeNext:
return ModuleResolutionKindNodeNext
Expand All @@ -226,7 +228,7 @@ func (options *CompilerOptions) GetEmitModuleDetectionKind() ModuleDetectionKind
return options.ModuleDetection
}
switch options.GetEmitModuleKind() {
case ModuleKindNode16, ModuleKindNodeNext:
case ModuleKindNode16, ModuleKindNode20, ModuleKindNodeNext:
return ModuleDetectionKindForce
default:
return ModuleDetectionKindAuto
Expand Down Expand Up @@ -254,7 +256,7 @@ func (options *CompilerOptions) GetESModuleInterop() bool {
return options.ESModuleInterop == TSTrue
}
switch options.GetEmitModuleKind() {
case ModuleKindNode16, ModuleKindNode18, ModuleKindNodeNext, ModuleKindPreserve:
case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20, ModuleKindNodeNext, ModuleKindPreserve:
return true
}
return false
Expand All @@ -273,6 +275,11 @@ func (options *CompilerOptions) GetResolveJsonModule() bool {
if options.ResolveJsonModule != TSUnknown {
return options.ResolveJsonModule == TSTrue
}
switch options.GetEmitModuleKind() {
// TODO in 6.0: add Node16/Node18
case ModuleKindNode20, ModuleKindESNext:
return true
}
return options.GetModuleResolutionKind() == ModuleResolutionKindBundler
}

Expand Down
2 changes: 1 addition & 1 deletion internal/ls/autoimports.go
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ func getUmdImportKind(importingFile *ast.SourceFile /* | FutureSourceFile */, pr
case core.ModuleKindES2015, core.ModuleKindES2020, core.ModuleKindES2022, core.ModuleKindESNext, core.ModuleKindNone, core.ModuleKindPreserve:
// Fall back to the `import * as ns` style import.
return ImportKindNamespace
case core.ModuleKindNode16, core.ModuleKindNode18, core.ModuleKindNodeNext:
case core.ModuleKindNode16, core.ModuleKindNode18, core.ModuleKindNode20, core.ModuleKindNodeNext:
if program.GetImpliedNodeFormatForEmit(importingFile) == core.ModuleKindESNext {
return ImportKindNamespace
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

=== bar.d.ts ===
import * as foo from './foo'
>foo : Root
>foo : { default: Root; }

export as namespace foo
>foo : Root
>foo : { default: Root; }

export = foo;
>foo : Root
>foo : { default: Root; }

declare global {
>global : typeof global
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import a from "./a";
>a : Symbol(a, Decl(b.ts, 0, 6))

import { default as b } from "./a";
>default : Symbol(self.default, Decl(a.ts, 0, 30))
>default : Symbol(mod, Decl(a.ts, 0, 30))
>b : Symbol(b, Decl(b.ts, 1, 8))

import c, { default as d } from "./a";
>c : Symbol(c, Decl(b.ts, 2, 6))
>default : Symbol(self.default, Decl(a.ts, 0, 30))
>default : Symbol(mod, Decl(a.ts, 0, 30))
>d : Symbol(d, Decl(b.ts, 2, 11))

import * as self from "./b";
Expand All @@ -34,7 +34,7 @@ export { default } from "./a";
>default : Symbol(self.default, Decl(b.ts, 4, 8))

export { default as def } from "./a";
>default : Symbol(self.default, Decl(a.ts, 0, 30))
>default : Symbol(mod, Decl(a.ts, 0, 30))
>def : Symbol(self.def, Decl(b.ts, 5, 8))

a === b;
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ import * as foo from "./foo";
>foo : Symbol(foo, Decl(index.ts, 0, 6))

foo.default;
>foo.default : Symbol(default)
>foo : Symbol(foo, Decl(index.ts, 0, 6))
>default : Symbol(default)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ export = foo;

=== index.ts ===
import * as foo from "./foo";
>foo : () => void
>foo : { default: () => void; }

foo.default;
>foo.default : any
>foo : () => void
>default : any
>foo.default : () => void
>foo : { default: () => void; }
>default : () => void

Loading
Loading