Repository: swc-project/swc (rust)

Issue:
Coverage reports include <<jsx-config-pragma.js>>, causing errors
looks like this is still an issue in 1.2.198. for me it causes problems when generating lcov reports from test runs with @swc/jest. my config looks like this:
```
        "^.+\\.(t|j)s$": ["@swc/jest", {
            sourceMaps: "inline",
            module: {
                strict: false,
                strictMode: false
            },

            jsc: {
                target: "es5",
                parser: {
                    syntax: "typescript",
                    dynamicImport: true
                }
            }
        }]
```
the lcov.info file ends with this:
```
SF:source\core\asyncCore\actions\<<jsx-config-pragma.js>>
FNF:0
FNH:0
DA:1,1
LF:1
LH:1
BRF:0
BRH:0
end_of_record
```
and the coverage report fails with
```
Error: ENOENT: no such file or directory, open 'C:\project\packages\my-package\test-results\lcov-report\core\asyncCore\actions\<<jsx-config-pragma.js>>.html'
    at Object.openSync (node:fs:585:3)
    at FileWriter.writeFile (C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\file-writer.js:185:41)
    at HtmlReport.onDetail (C:\project\node_modules\.pnpm\istanbul-reports@3.1.4\node_modules\istanbul-reports\lib\html\index.js:411:44) 
    at LcovReport.<computed> [as onDetail] (C:\project\node_modules\.pnpm\istanbul-reports@3.1.4\node_modules\istanbul-reports\lib\lcov\index.js:28:23)
    at Visitor.value (C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\tree.js:38:38)        
    at ReportNode.visit (C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\tree.js:88:21)     
    at C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\tree.js:92:19
    at Array.forEach (<anonymous>)
    at ReportNode.visit (C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\tree.js:91:28)     
    at C:\project\node_modules\.pnpm\istanbul-lib-report@3.0.0\node_modules\istanbul-lib-report\lib\tree.js:92:19
```

unfortunately i don't have the option to switch to es2021 because lots of tests fail then (i'm not exactly sure why, probably related to some patched polyfill that won't initialize on that target...)

-----

i found a bit more details in the cobertura report (which is also broken because of these <<jsx-config-pragma.js>> references). it seems that the coverage reporters really see that file in some directories, not all. the rest of the files of those directories are reported fine, but it still creates a report entry for those weird files too:
```
        <class name="&lt;&lt;jsx-config-pragma.js&gt;&gt;" filename="source\core\asyncCore\actions\<<jsx-config-pragma.js>>" line-rate="1" branch-rate="1">
          <methods>
          </methods>
          <lines>
            <line number="1" hits="1" branch="false"/>
          </lines>
        </class>
```

-----

edit: excluding this weird file from coverage doesn't work either.

_Originally posted by @DerGernTod in https://github.com/swc-project/swc/issues/4691#issuecomment-1191343209_

Pull request:
fix(common): Fix logic for excluding `FileName` from source maps
**Description:**

This PR also modifies React transform to use `FileName::Internal` and makes `SourceMapGenConfig` skips `FileName::Internal`.

**Related issue:**

 - Closes #5272

Patch:
diff --git a/crates/swc/src/lib.rs b/crates/swc/src/lib.rs
index 0a29f12587..6ef1ade4d1 100644
--- a/crates/swc/src/lib.rs
+++ b/crates/swc/src/lib.rs
@@ -681,10 +681,10 @@ impl SourceMapGenConfig for SwcSourceMapConfig<'_> {
     }
 
     fn skip(&self, f: &FileName) -> bool {
-        if let FileName::Custom(s) = f {
-            s.starts_with('<')
-        } else {
-            false
+        match f {
+            FileName::Internal(..) => true,
+            FileName::Custom(s) => s.starts_with('<'),
+            _ => false,
         }
     }
 }
diff --git a/crates/swc_common/src/source_map.rs b/crates/swc_common/src/source_map.rs
index 1b8c97f8aa..cc121bee11 100644
--- a/crates/swc_common/src/source_map.rs
+++ b/crates/swc_common/src/source_map.rs
@@ -1266,6 +1266,9 @@ impl SourceMap {
                 Some(ref f) if f.start_pos <= pos && pos < f.end_pos => f,
                 _ => {
                     f = self.lookup_source_file(pos);
+                    if config.skip(&f.name) {
+                        continue;
+                    }
                     src_id = builder.add_source(&config.file_name_to_source(&f.name));
 
                     inline_sources_content = config.inline_sources_content(&f.name);
@@ -1447,8 +1450,9 @@ pub trait SourceMapGenConfig {
         true
     }
 
-    fn skip(&self, _f: &FileName) -> bool {
-        false
+    /// By default, we skip internal files.
+    fn skip(&self, f: &FileName) -> bool {
+        matches!(f, FileName::Internal(..))
     }
 }
 
diff --git a/crates/swc_ecma_transforms_module/src/umd/config.rs b/crates/swc_ecma_transforms_module/src/umd/config.rs
index 3fb840eef0..1564b7283b 100644
--- a/crates/swc_ecma_transforms_module/src/umd/config.rs
+++ b/crates/swc_ecma_transforms_module/src/umd/config.rs
@@ -29,8 +29,10 @@ impl Config {
                 .into_iter()
                 .map(|(k, v)| {
                     let parse = |s| {
-                        let fm = cm
-                            .new_source_file(FileName::Custom(format!("<umd-config-{}.js>", s)), s);
+                        let fm = cm.new_source_file(
+                            FileName::Internal(format!("<umd-config-{}.js>", s)),
+                            s,
+                        );
 
                         parse_file_as_expr(
                             &fm,
diff --git a/crates/swc_ecma_transforms_optimization/src/const_modules.rs b/crates/swc_ecma_transforms_optimization/src/const_modules.rs
index 5e578e07c1..ed71111e62 100644
--- a/crates/swc_ecma_transforms_optimization/src/const_modules.rs
+++ b/crates/swc_ecma_transforms_optimization/src/const_modules.rs
@@ -46,7 +46,10 @@ pub fn const_modules(
 fn parse_option(cm: &SourceMap, name: &str, src: String) -> Arc<Expr> {
     static CACHE: Lazy<DashMap<String, Arc<Expr>, ARandomState>> = Lazy::new(DashMap::default);
 
-    let fm = cm.new_source_file(FileName::Custom(format!("<const-module-{}.js>", name)), src);
+    let fm = cm.new_source_file(
+        FileName::Internal(format!("<const-module-{}.js>", name)),
+        src,
+    );
     if let Some(expr) = CACHE.get(&**fm.src) {
         return expr.clone();
     }
diff --git a/crates/swc_ecma_transforms_react/src/jsx/mod.rs b/crates/swc_ecma_transforms_react/src/jsx/mod.rs
index 66842c9c97..ea53f552cd 100644
--- a/crates/swc_ecma_transforms_react/src/jsx/mod.rs
+++ b/crates/swc_ecma_transforms_react/src/jsx/mod.rs
@@ -118,7 +118,7 @@ pub fn parse_expr_for_jsx(
     src: String,
     top_level_mark: Mark,
 ) -> Arc<Box<Expr>> {
-    let fm = cm.new_source_file(FileName::Custom(format!("<jsx-config-{}.js>", name)), src);
+    let fm = cm.new_source_file(FileName::Internal(format!("<jsx-config-{}.js>", name)), src);
 
     parse_file_as_expr(
         &fm,


Test patch:
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/input/.swcrc b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/.swcrc
new file mode 100644
index 0000000000..39df3d2984
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/.swcrc
@@ -0,0 +1,20 @@
+{
+    "sourceMaps": true,
+    "module": {
+        "type": "commonjs",
+        "strict": false,
+        "strictMode": false
+    },
+    "jsc": {
+        "target": "es5",
+        "parser": {
+            "syntax": "typescript",
+            "dynamicImport": true
+        },
+        "transform": {
+            "hidden": {
+                "jest": true
+            }
+        }
+    },
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.spec.ts b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.spec.ts
new file mode 100644
index 0000000000..3b3fa5e6b6
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.spec.ts
@@ -0,0 +1,9 @@
+import { Foo } from "./a";
+
+describe("a", () => {
+    it("does its thing", () => {
+        const a = new Foo();
+        expect(a.bar()).toBe(3);
+        expect(a.foo()).toBe(2);
+    });
+});
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.ts b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.ts
new file mode 100644
index 0000000000..4e741aeb16
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/input/source/a/a.ts
@@ -0,0 +1,6 @@
+import { Base } from "../b/base";
+export class Foo extends Base {
+    bar() {
+        return 1 + this.foo();
+    }
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.map b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.map
new file mode 100644
index 0000000000..926b19ade3
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.map
@@ -0,0 +1,16 @@
+{
+  "mappings": ";;;+BACaA;;;eAAAA;;;;;;;oBADQ;AACd,IAAA,AAAMA,oBAAN;;gBAAMA;iCAAAA;aAAAA;kCAAAA;;;oBAAAA;;YACTC,KAAAA;mBAAAA,SAAAA;gBACI,OAAO,IAAI,IAAI,CAACC,GAAG;YACvB;;;WAHSF;EAAYG,UAAI",
+  "names": [
+    "Foo",
+    "bar",
+    "foo",
+    "Base"
+  ],
+  "sources": [
+    "../../input/source/a/a.ts"
+  ],
+  "sourcesContent": [
+    "import { Base } from \"../b/base\";\nexport class Foo extends Base {\n    bar() {\n        return 1 + this.foo();\n    }\n}"
+  ],
+  "version": 3
+}
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.spec.map b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.spec.map
new file mode 100644
index 0000000000..0326470833
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/a.spec.map
@@ -0,0 +1,20 @@
+{
+  "mappings": ";;;iBAAoB;AAEpBA,SAAS,KAAK;IACVC,GAAG,kBAAkB;QACjB,IAAMC,IAAI,IAAIC,MAAG;QACjBC,OAAOF,EAAEG,GAAG,IAAIC,IAAI,CAAC;QACrBF,OAAOF,EAAEK,GAAG,IAAID,IAAI,CAAC;IACzB;AACJ",
+  "names": [
+    "describe",
+    "it",
+    "a",
+    "Foo",
+    "expect",
+    "bar",
+    "toBe",
+    "foo"
+  ],
+  "sources": [
+    "../../input/source/a/a.spec.ts"
+  ],
+  "sourcesContent": [
+    "import { Foo } from \"./a\";\n\ndescribe(\"a\", () => {\n    it(\"does its thing\", () => {\n        const a = new Foo();\n        expect(a.bar()).toBe(3);\n        expect(a.foo()).toBe(2);\n    });\n});"
+  ],
+  "version": 3
+}
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.spec.ts b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.spec.ts
new file mode 100644
index 0000000000..ac3485a50d
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.spec.ts
@@ -0,0 +1,11 @@
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+var _a = require("./a");
+describe("a", function() {
+    it("does its thing", function() {
+        var a = new _a.Foo();
+        expect(a.bar()).toBe(3);
+        expect(a.foo()).toBe(2);
+    });
+});
diff --git a/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.ts b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.ts
new file mode 100644
index 0000000000..19644b8928
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-5xxx/5272/1/output/source/a/a.ts
@@ -0,0 +1,32 @@
+Object.defineProperty(exports, "__esModule", {
+    value: true
+});
+Object.defineProperty(exports, "Foo", {
+    enumerable: true,
+    get: function() {
+        return Foo;
+    }
+});
+var _class_call_check = require("@swc/helpers/_/_class_call_check");
+var _create_class = require("@swc/helpers/_/_create_class");
+var _inherits = require("@swc/helpers/_/_inherits");
+var _create_super = require("@swc/helpers/_/_create_super");
+var _base = require("../b/base");
+var Foo = /*#__PURE__*/ function(Base) {
+    "use strict";
+    _inherits._(Foo, Base);
+    var _super = _create_super._(Foo);
+    function Foo() {
+        _class_call_check._(this, Foo);
+        return _super.apply(this, arguments);
+    }
+    _create_class._(Foo, [
+        {
+            key: "bar",
+            value: function bar() {
+                return 1 + this.foo();
+            }
+        }
+    ]);
+    return Foo;
+}(_base.Base);