Repository: swc-project/swc (rust)

Issue:
imported tagged template call should be transformed into indirect call
### Describe the bug

see the playground.

### Input code

```typescript
import foo from "mod";

foo("foo");
foo`foo`;
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "ecmascript"
    },
    "target": "es2022"
  },
  "module": {
    "type": "commonjs"
  },
  "minify": false,
  "isModule": true
}
```


### Playground link

[swc playground](https://play.swc.rs/?version=1.2.222&code=H4sIAAAAAAAAA8vMLcgvKlFIy89XSCvKz1VQys1PUbLm4gIKaCgBCSVNaxA7AYStAXMeqoYtAAAA&config=H4sIAAAAAAAAAy2LSwqAMAxE7zJrF9Jl7%2BAhQo1SsR%2BSCBbx7lpxNcN7Mxc2DfAXKomy9KYtG53w4JBIg8RquAcYycrWsbrRuY5SmY%2Bd%2B8dafROhpFTypp%2BMOS4NfqFdeUDU6V%2BbHHw%2FPvro7HgAAAA%3D)

### Expected behavior

```JavaScript
(0, _mod.default)("foo");
(0, _mod.default)`foo`;
```

### Actual behavior

```JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
const _mod = /*#__PURE__*/ _interopRequireDefault(require("mod"));
function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
(0, _mod.default)("foo");
_mod.default`foo`;
```

### Version

1.2.222

### Additional context

_No response_

Pull request description:
fix(es/module): indirect call for tagged template
<!-- Note: CI script will automatically rebase your PR so please do not rebase unless required -->

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**Description:**

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->

**BREAKING CHANGE:**

<!--
If this PR introduces a breaking change, it must contain a notice for it to be included in the CHANGELOG. Add description or remove entirely if not breaking.

You may need to update `MIGRATION.md` for the breaking changes.
-->

**Related issue (if exists):**
- fix #5381 

Patch:
diff --git a/crates/swc_ecma_transforms_module/src/module_ref_rewriter.rs b/crates/swc_ecma_transforms_module/src/module_ref_rewriter.rs
index 4c6cc3a7b9..526c014552 100644
--- a/crates/swc_ecma_transforms_module/src/module_ref_rewriter.rs
+++ b/crates/swc_ecma_transforms_module/src/module_ref_rewriter.rs
@@ -98,6 +98,21 @@ impl VisitMut for ModuleRefRewriter {
         }
     }
 
+    fn visit_mut_tagged_tpl(&mut self, n: &mut TaggedTpl) {
+        let is_indirect = n
+            .tag
+            .as_ident()
+            .and_then(|ident| self.import_map.get(&ident.to_id()))
+            .map(|(_, prop)| prop.is_some())
+            .unwrap_or_default();
+
+        n.visit_mut_children_with(self);
+
+        if is_indirect {
+            *n = n.take().into_indirect()
+        }
+    }
+
     fn visit_mut_function(&mut self, n: &mut Function) {
         self.visit_mut_with_non_global_this(n);
     }
diff --git a/crates/swc_ecma_utils/src/factory.rs b/crates/swc_ecma_utils/src/factory.rs
index cf7ba2766e..a6eaffe1b7 100644
--- a/crates/swc_ecma_utils/src/factory.rs
+++ b/crates/swc_ecma_utils/src/factory.rs
@@ -1,7 +1,7 @@
 use std::iter;
 
 use swc_atoms::js_word;
-use swc_common::{Span, Spanned, DUMMY_SP};
+use swc_common::{util::take::Take, Span, Spanned, DUMMY_SP};
 use swc_ecma_ast::*;
 
 /// Extension methods for [Expr].
@@ -326,6 +326,24 @@ impl IntoIndirectCall for Callee {
     }
 }
 
+impl IntoIndirectCall for TaggedTpl {
+    type Item = TaggedTpl;
+
+    #[cfg_attr(not(debug_assertions), inline(always))]
+    fn into_indirect(mut self) -> Self {
+        Self {
+            tag: Box::new(
+                SeqExpr {
+                    span: DUMMY_SP,
+                    exprs: vec![0f64.into(), self.tag.take()],
+                }
+                .into(),
+            ),
+            ..self
+        }
+    }
+}
+
 pub trait FunctionFactory: Into<Function> {
     #[cfg_attr(not(debug_assertions), inline(always))]
     fn into_fn_expr(self, ident: Option<Ident>) -> FnExpr {


Test patch:
diff --git a/crates/swc/tests/fixture/jest/sourcemap-1/output/index.ts b/crates/swc/tests/fixture/jest/sourcemap-1/output/index.ts
index 2d89511ac1..5b5179f460 100644
--- a/crates/swc/tests/fixture/jest/sourcemap-1/output/index.ts
+++ b/crates/swc/tests/fixture/jest/sourcemap-1/output/index.ts
@@ -7,8 +7,8 @@ Object.defineProperty(exports, "Button", {
     get: ()=>Button
 });
 const _linaria = require("linaria");
-const Button = _linaria.css`
+const Button = (0, _linaria.css)`
     color: red;
 `;
 
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2lucHV0L2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNzcyB9IGZyb20gXCJsaW5hcmlhXCI7XG5cbmV4cG9ydCBjb25zdCBCdXR0b24gPSBjc3NgXG4gICAgY29sb3I6IHJlZDtcbmA7XG4iXSwibmFtZXMiOlsiQnV0dG9uIiwiY3NzIl0sIm1hcHBpbmdzIjoiQUFBQTs7OzsrQkFFYUEsUUFBTTs7YUFBTkEsTUFBTTs7eUJBRkMsU0FBUztBQUV0QixNQUFNQSxNQUFNLEdBQUdDLFFBQUcsSUFBQSxDQUFDOztBQUUxQixDQUFDLEFBQUMifQ==
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2lucHV0L2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNzcyB9IGZyb20gXCJsaW5hcmlhXCI7XG5cbmV4cG9ydCBjb25zdCBCdXR0b24gPSBjc3NgXG4gICAgY29sb3I6IHJlZDtcbmA7XG4iXSwibmFtZXMiOlsiQnV0dG9uIiwiY3NzIl0sIm1hcHBpbmdzIjoiQUFBQTs7OzsrQkFFYUEsUUFBTTs7YUFBTkEsTUFBTTs7eUJBRkMsU0FBUztBQUV0QixNQUFNQSxNQUFNLEdBQUdDLElBQUFBLFFBQUcsSUFBQSxDQUFBLENBQUM7O0FBRTFCLENBQUMsQUFBQyJ9
diff --git a/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/input.js b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/input.js
new file mode 100644
index 0000000000..b3c5392d94
--- /dev/null
+++ b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/input.js
@@ -0,0 +1,8 @@
+import foo from "foo";
+import { bar } from "bar";
+
+foo("foo");
+foo`foo`;
+
+bar("bar");
+bar`bar`;
diff --git a/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.amd.js b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.amd.js
new file mode 100644
index 0000000000..01b96ade69
--- /dev/null
+++ b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.amd.js
@@ -0,0 +1,16 @@
+define([
+    "require",
+    "exports",
+    "foo",
+    "bar"
+], function(require, exports, _foo, _bar) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", {
+        value: true
+    });
+    _foo = /*#__PURE__*/ _interopRequireDefault(_foo);
+    (0, _foo.default)("foo");
+    (0, _foo.default)`foo`;
+    (0, _bar.bar)("bar");
+    (0, _bar.bar)`bar`;
+});
diff --git a/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.cjs b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.cjs
new file mode 100644
index 0000000000..15a260253f
--- /dev/null
+++ b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.cjs
@@ -0,0 +1,10 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+const _foo = /*#__PURE__*/ _interopRequireDefault(require("foo"));
+const _bar = require("bar");
+(0, _foo.default)("foo");
+(0, _foo.default)`foo`;
+(0, _bar.bar)("bar");
+(0, _bar.bar)`bar`;
diff --git a/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.umd.js b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.umd.js
new file mode 100644
index 0000000000..5e0ed9ad32
--- /dev/null
+++ b/crates/swc_ecma_transforms_module/tests/fixture/common/interop/imports-call/output.umd.js
@@ -0,0 +1,19 @@
+(function(global, factory) {
+    if (typeof module === "object" && typeof module.exports === "object") factory(exports, require("foo"), require("bar"));
+    else if (typeof define === "function" && define.amd) define([
+        "exports",
+        "foo",
+        "bar"
+    ], factory);
+    else if (global = typeof globalThis !== "undefined" ? globalThis : global || self) factory(global.input = {}, global.foo, global.bar);
+})(this, function(exports, _foo, _bar) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", {
+        value: true
+    });
+    _foo = /*#__PURE__*/ _interopRequireDefault(_foo);
+    (0, _foo.default)("foo");
+    (0, _foo.default)`foo`;
+    (0, _bar.bar)("bar");
+    (0, _bar.bar)`bar`;
+});