diff --git a/internal/transformers/tstransforms/importelision.go b/internal/transformers/tstransforms/importelision.go index 7b23343d4a7..ec36ede7e6c 100644 --- a/internal/transformers/tstransforms/importelision.go +++ b/internal/transformers/tstransforms/importelision.go @@ -27,30 +27,26 @@ func NewImportElisionTransformer(opt *transformers.TransformOptions) *transforme func (tx *ImportElisionTransformer) visit(node *ast.Node) *ast.Node { switch node.Kind { case ast.KindImportEqualsDeclaration: - if !tx.isElisionBlocked(node) { - if ast.IsExternalModuleImportEqualsDeclaration(node) { - if !tx.shouldEmitAliasDeclaration(node) { - return nil - } - } else { - if !tx.shouldEmitImportEqualsDeclaration(node.AsImportEqualsDeclaration()) { - return nil - } + if ast.IsExternalModuleImportEqualsDeclaration(node) { + if !tx.shouldEmitAliasDeclaration(node) { + return nil + } + } else { + if !tx.shouldEmitImportEqualsDeclaration(node.AsImportEqualsDeclaration()) { + return nil } } return tx.Visitor().VisitEachChild(node) case ast.KindImportDeclaration: - if !tx.isElisionBlocked(node) { - n := node.AsImportDeclaration() - // Do not elide a side-effect only import declaration. - // import "foo"; - if n.ImportClause != nil { - importClause := tx.Visitor().VisitNode(n.ImportClause) - if importClause == nil { - return nil - } - return tx.Factory().UpdateImportDeclaration(n, n.Modifiers(), importClause, n.ModuleSpecifier, tx.Visitor().VisitNode(n.Attributes)) + n := node.AsImportDeclaration() + // Do not elide a side-effect only import declaration. + // import "foo"; + if n.ImportClause != nil { + importClause := tx.Visitor().VisitNode(n.ImportClause) + if importClause == nil { + return nil } + return tx.Factory().UpdateImportDeclaration(n, n.Modifiers(), importClause, n.ModuleSpecifier, tx.Visitor().VisitNode(n.Attributes)) } return tx.Visitor().VisitEachChild(node) case ast.KindImportClause: @@ -83,25 +79,22 @@ func (tx *ImportElisionTransformer) visit(node *ast.Node) *ast.Node { } return node case ast.KindExportAssignment: - if !tx.isElisionBlocked(node) && !tx.compilerOptions.VerbatimModuleSyntax.IsTrue() && !tx.isValueAliasDeclaration(node) { + if !tx.compilerOptions.VerbatimModuleSyntax.IsTrue() && !tx.isValueAliasDeclaration(node) { // elide unused import return nil } return tx.Visitor().VisitEachChild(node) case ast.KindExportDeclaration: - if !tx.isElisionBlocked(node) { - n := node.AsExportDeclaration() - var exportClause *ast.Node - if n.ExportClause != nil { - exportClause = tx.Visitor().VisitNode(n.ExportClause) - if exportClause == nil { - // all export bindings were elided - return nil - } + n := node.AsExportDeclaration() + var exportClause *ast.Node + if n.ExportClause != nil { + exportClause = tx.Visitor().VisitNode(n.ExportClause) + if exportClause == nil { + // all export bindings were elided + return nil } - return tx.Factory().UpdateExportDeclaration(n, nil /*modifiers*/, false /*isTypeOnly*/, exportClause, tx.Visitor().VisitNode(n.ModuleSpecifier), tx.Visitor().VisitNode(n.Attributes)) } - return tx.Visitor().VisitEachChild(node) + return tx.Factory().UpdateExportDeclaration(n, nil /*modifiers*/, false /*isTypeOnly*/, exportClause, tx.Visitor().VisitNode(n.ModuleSpecifier), tx.Visitor().VisitNode(n.Attributes)) case ast.KindNamedExports: n := node.AsNamedExports() elements := tx.Visitor().VisitNodes(n.Elements) @@ -152,56 +145,3 @@ func (tx *ImportElisionTransformer) isTopLevelValueImportEqualsWithEntityName(no node = tx.EmitContext().ParseNode(node) return node != nil && tx.emitResolver.IsTopLevelValueImportEqualsWithEntityName(node) } - -// Determines whether import/export elision is blocked for this statement. -// -// @description -// We generally block import/export elision if the statement was modified by a `before` custom -// transform, although we will continue to allow it if the statement hasn't replaced a node of a different kind and -// as long as the local bindings for the declarations are unchanged. -func (tx *ImportElisionTransformer) isElisionBlocked(node *ast.Node /*ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration*/) bool { - parsed := tx.EmitContext().ParseNode(node) - if parsed == node || ast.IsExportAssignment(node) { - return false - } - - if parsed == nil || parsed.Kind != node.Kind { - // no longer safe to elide as the declaration was replaced with a node of a different kind - return true - } - - switch node.Kind { - case ast.KindImportDeclaration: - n := node.AsImportDeclaration() - p := parsed.AsImportDeclaration() - if n.ImportClause != p.ImportClause { - return true // no longer safe to elide as the import clause has changed - } - if n.Attributes != p.Attributes { - return true // no longer safe to elide as the import attributes have changed - } - case ast.KindImportEqualsDeclaration: - n := node.AsImportEqualsDeclaration() - p := parsed.AsImportEqualsDeclaration() - if n.Name() != p.Name() { - return true // no longer safe to elide as local binding has changed - } - if n.IsTypeOnly != p.IsTypeOnly { - return true // no longer safe to elide as `type` modifier has changed - } - if n.ModuleReference != p.ModuleReference && (ast.IsEntityName(n.ModuleReference) || ast.IsEntityName(p.ModuleReference)) { - return true // no longer safe to elide as EntityName reference has changed. - } - case ast.KindExportDeclaration: - n := node.AsExportDeclaration() - p := parsed.AsExportDeclaration() - if n.ExportClause != p.ExportClause { - return true // no longer safe to elide as the export clause has changed - } - if n.Attributes != p.Attributes { - return true // no longer safe to elide as the export attributes have changed - } - } - - return false -} diff --git a/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js b/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js index 46f834fbebe..71db89bcbb4 100644 --- a/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js +++ b/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js @@ -62,7 +62,7 @@ type; // Error (cannot resolve name) as; // Error (used in emitting position) export {}; //// [d.js] -import "./mod.js"; // Error +export {}; //// [e.js] import { type as type } from "./mod.js"; type; diff --git a/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js.diff b/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js.diff deleted file mode 100644 index 3031ffe9e73..00000000000 --- a/testdata/baselines/reference/submodule/conformance/importSpecifiers1.js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.importSpecifiers1.js -+++ new.importSpecifiers1.js -@@= skipped -61, +61 lines =@@ - as; // Error (used in emitting position) - export {}; - //// [d.js] --export {}; -+import "./mod.js"; // Error - //// [e.js] - import { type as type } from "./mod.js"; - type; \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js index 9d1ac266495..988072b042c 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js.diff deleted file mode 100644 index d8de5a5e71b..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js -+++ new.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node16).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js index 9d1ac266495..988072b042c 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js.diff deleted file mode 100644 index b59663c1020..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js -+++ new.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node18).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js index 9d1ac266495..988072b042c 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js.diff deleted file mode 100644 index ebc4ffa1db2..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js -+++ new.nodeModulesImportAttributesModeDeclarationEmitErrors(module=node20).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js index 9d1ac266495..988072b042c 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js.diff deleted file mode 100644 index f07a514c7ec..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js -+++ new.nodeModulesImportAttributesModeDeclarationEmitErrors(module=nodenext).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js index 4888c6ec436..2f14482b274 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js.diff deleted file mode 100644 index fe0234b6b8b..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node16).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportModeDeclarationEmitErrors1(module=node16).js -+++ new.nodeModulesImportModeDeclarationEmitErrors1(module=node16).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js index 4888c6ec436..2f14482b274 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js.diff deleted file mode 100644 index 28700d7fd14..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node18).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportModeDeclarationEmitErrors1(module=node18).js -+++ new.nodeModulesImportModeDeclarationEmitErrors1(module=node18).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js index 4888c6ec436..2f14482b274 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js.diff deleted file mode 100644 index f7b38f460c0..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=node20).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportModeDeclarationEmitErrors1(module=node20).js -+++ new.nodeModulesImportModeDeclarationEmitErrors1(module=node20).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js index 4888c6ec436..2f14482b274 100644 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js +++ b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js @@ -30,8 +30,6 @@ export interface LocalInterface extends RequireInterface, ImportInterface {} //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -// not exclusively type-only -require("pkg"); //// [index.d.ts] diff --git a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js.diff b/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js.diff deleted file mode 100644 index 4b93d9af954..00000000000 --- a/testdata/baselines/reference/submodule/conformance/nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- old.nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js -+++ new.nodeModulesImportModeDeclarationEmitErrors1(module=nodenext).js -@@= skipped -29, +29 lines =@@ - //// [index.js] - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); -+// not exclusively type-only -+require("pkg"); - - - //// [index.d.ts] \ No newline at end of file