Skip to content

Commit 4af52c7

Browse files
kdy1jridgewell
andauthoredDec 2, 2022
fix(common): Fix handling of input source maps (#6561)
**Related issue:** - Closes #4578. - Closes #6244. - vercel/next.js#39878. Co-authored-by: Justin Ridgewell <justin@ridgewell.name>
1 parent d00b291 commit 4af52c7

File tree

13 files changed

+315
-111
lines changed

13 files changed

+315
-111
lines changed
 

‎Cargo.lock

+9-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/swc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ swc_plugin_runner = { version = "0.78.1", path = "../swc_plugin_runner", optiona
9898
swc_timer = { version = "0.17.17", path = "../swc_timer" }
9999
swc_visit = { version = "0.5.2", path = "../swc_visit" }
100100
tracing = "0.1.32"
101+
url = "2.3.1"
101102

102103
[dependencies.napi-derive]
103104
default-features = false

‎crates/swc/src/lib.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ use swc_ecma_visit::{noop_visit_type, FoldWith, Visit, VisitMutWith, VisitWith};
158158
pub use swc_error_reporters::handler::{try_with_handler, HandlerOpts};
159159
pub use swc_node_comments::SwcComments;
160160
use swc_timer::timer;
161+
use url::Url;
161162

162163
pub use crate::builder::PassBuilder;
163164
use crate::config::{
@@ -328,20 +329,35 @@ impl Compiler {
328329
}
329330
InputSourceMap::Str(ref s) => {
330331
if s == "inline" {
332+
const NEEDLE: &str = "sourceMappingURL=";
331333
// Load inline source map by simple string
332334
// operations
333-
let s = "sourceMappingURL=data:application/json;base64,";
334-
let idx = fm.src.rfind(s);
335+
let idx = fm.src.rfind(NEEDLE);
335336
let idx = match idx {
336337
None => bail!(
337338
"failed to parse inline source map: `sourceMappingURL` not found"
338339
),
339340
Some(v) => v,
340341
};
341-
let encoded = &fm.src[idx + s.len()..];
342+
let data_url = fm.src[idx + NEEDLE.len()..].trim();
343+
let url = Url::parse(data_url).with_context(|| {
344+
format!("failed to parse inline source map url\n{}", data_url)
345+
})?;
342346

343-
let res = base64::decode(encoded.as_bytes())
344-
.context("failed to decode base64-encoded source map")?;
347+
let idx = match url.path().find("base64,") {
348+
Some(v) => v,
349+
None => {
350+
bail!("failed to parse inline source map: not base64: {:?}", url)
351+
}
352+
};
353+
354+
let content = url.path()[idx + "base64,".len()..].trim();
355+
356+
let res = base64::decode_config(
357+
content.as_bytes(),
358+
base64::Config::new(base64::CharacterSet::Standard, true),
359+
)
360+
.context("failed to decode base64-encoded source map")?;
345361

346362
Ok(Some(sourcemap::SourceMap::from_slice(&res).context(
347363
"failed to read input source map from inlined base64 encoded string",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"env": {
3+
"targets": {
4+
"chrome": "95"
5+
}
6+
},
7+
"jsc": {
8+
"parser": {
9+
"syntax": "typescript",
10+
"tsx": true
11+
}
12+
},
13+
"sourceMaps": true
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { UIStore, UIThunkAction } from "ui/actions";
2+
import { isInspectorSelected } from "ui/reducers/app";
3+
import { AppStartListening } from "ui/setup/listenerMiddleware";
4+
import { getBoundingRectAsync, getComputedStyleAsync } from "ui/suspense/styleCaches";
5+
6+
import { nodeSelected } from "../../markup/reducers/markup";
7+
import { LAYOUT_NUMERIC_FIELDS, Layout, layoutUpdated } from "../reducers/box-model";
8+
9+
export function setupBoxModel(store: UIStore, startAppListening: AppStartListening) {
10+
// Any time a new node is selected in the "Markup" panel,
11+
// try to update the box model layout data
12+
startAppListening({
13+
actionCreator: nodeSelected,
14+
effect: async (action, listenerApi) => {
15+
const { extra, getState, dispatch } = listenerApi;
16+
const { ThreadFront, protocolClient, replayClient } = extra;
17+
const state = getState();
18+
const { selectedNode, tree } = state.markup;
19+
20+
if (!isInspectorSelected(state) || !selectedNode || !ThreadFront.currentPause?.pauseId) {
21+
return;
22+
}
23+
24+
const nodeInfo = tree.entities[selectedNode];
25+
26+
if (!nodeInfo) {
27+
return;
28+
}
29+
30+
const [bounds, style] = await Promise.all([
31+
getBoundingRectAsync(
32+
protocolClient,
33+
ThreadFront.sessionId!,
34+
ThreadFront.currentPause.pauseId,
35+
selectedNode
36+
),
37+
getComputedStyleAsync(
38+
protocolClient,
39+
ThreadFront.sessionId!,
40+
ThreadFront.currentPause.pauseId,
41+
selectedNode
42+
),
43+
]);
44+
45+
if (!bounds || !style) {
46+
return;
47+
}
48+
49+
const layout = {
50+
width: parseFloat(bounds.width.toPrecision(6)),
51+
height: parseFloat(bounds.height.toPrecision(6)),
52+
autoMargins: {},
53+
} as Layout;
54+
55+
for (const prop of LAYOUT_NUMERIC_FIELDS) {
56+
layout[prop] = style.get(prop)!;
57+
}
58+
59+
// Update the redux store with the latest layout properties and update the box model view.
60+
dispatch(layoutUpdated(layout));
61+
},
62+
});
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"mappings": "AACA,SAASA,mBAAmB,QAAQ,kBAAkB;AAEtD,SAASC,oBAAoB,EAAEC,qBAAqB,QAAQ,0BAA0B;AAEtF,SAASC,YAAY,QAAQ,+BAA+B;AAC5D,SAASC,qBAAqB,EAAUC,aAAa,QAAQ,wBAAwB;AAErF,OAAO,SAASC,cAAcC,KAAc,EAAEC,iBAAoC,EAAE;IAClF,yDAAyD;IACzD,0CAA0C;IAC1CA,kBAAkB;QAChBC,eAAeN;QACfO,QAAQ,OAAOC,QAAQC,cAAgB;YACrC,MAAM,EAAEC,MAAK,EAAEC,SAAQ,EAAEC,SAAQ,EAAE,GAAGH;YACtC,MAAM,EAAEI,YAAW,EAAEC,eAAc,EAAEC,aAAY,EAAE,GAAGL;YACtD,MAAMM,QAAQL;YACd,MAAM,EAAEM,aAAY,EAAEC,KAAI,EAAE,GAAGF,MAAMG,MAAM;YAE3C,IAAI,CAACtB,oBAAoBmB,UAAU,CAACC,gBAAgB,CAACJ,YAAYO,YAAY,EAAEC,SAAS;gBACtF;YACF,CAAC;YAED,MAAMC,WAAWJ,KAAKK,QAAQ,CAACN,aAAa;YAE5C,IAAI,CAACK,UAAU;gBACb;YACF,CAAC;YAED,MAAM,CAACE,QAAQC,MAAM,GAAG,MAAMC,QAAQC,GAAG,CAAC;gBACxC7B,qBACEgB,gBACAD,YAAYe,SAAS,EACrBf,YAAYO,YAAY,CAACC,OAAO,EAChCJ;gBAEFlB,sBACEe,gBACAD,YAAYe,SAAS,EACrBf,YAAYO,YAAY,CAACC,OAAO,EAChCJ;aAEH;YAED,IAAI,CAACO,UAAU,CAACC,OAAO;gBACrB;YACF,CAAC;YAED,MAAMI,SAAS;gBACbC,OAAOC,WAAWP,OAAOM,KAAK,CAACE,WAAW,CAAC;gBAC3CC,QAAQF,WAAWP,OAAOS,MAAM,CAACD,WAAW,CAAC;gBAC7CE,aAAa,CAAC;YAChB;YAEA,KAAK,MAAMC,QAAQlC,sBAAuB;gBACxC4B,MAAM,CAACM,KAAK,GAAGV,MAAMW,GAAG,CAACD;YAC3B;YAEA,0FAA0F;YAC1FvB,SAASV,cAAc2B;QACzB;IACF;AACF,CAAC",
3+
"names": [
4+
"isInspectorSelected",
5+
"getBoundingRectAsync",
6+
"getComputedStyleAsync",
7+
"nodeSelected",
8+
"LAYOUT_NUMERIC_FIELDS",
9+
"layoutUpdated",
10+
"setupBoxModel",
11+
"store",
12+
"startAppListening",
13+
"actionCreator",
14+
"effect",
15+
"action",
16+
"listenerApi",
17+
"extra",
18+
"getState",
19+
"dispatch",
20+
"ThreadFront",
21+
"protocolClient",
22+
"replayClient",
23+
"state",
24+
"selectedNode",
25+
"tree",
26+
"markup",
27+
"currentPause",
28+
"pauseId",
29+
"nodeInfo",
30+
"entities",
31+
"bounds",
32+
"style",
33+
"Promise",
34+
"all",
35+
"sessionId",
36+
"layout",
37+
"width",
38+
"parseFloat",
39+
"toPrecision",
40+
"height",
41+
"autoMargins",
42+
"prop",
43+
"get"
44+
],
45+
"sources": [
46+
"../../input/box-model.ts"
47+
],
48+
"sourcesContent": [
49+
"import type { UIStore, UIThunkAction } from \"ui/actions\";\nimport { isInspectorSelected } from \"ui/reducers/app\";\nimport { AppStartListening } from \"ui/setup/listenerMiddleware\";\nimport { getBoundingRectAsync, getComputedStyleAsync } from \"ui/suspense/styleCaches\";\n\nimport { nodeSelected } from \"../../markup/reducers/markup\";\nimport { LAYOUT_NUMERIC_FIELDS, Layout, layoutUpdated } from \"../reducers/box-model\";\n\nexport function setupBoxModel(store: UIStore, startAppListening: AppStartListening) {\n // Any time a new node is selected in the \"Markup\" panel,\n // try to update the box model layout data\n startAppListening({\n actionCreator: nodeSelected,\n effect: async (action, listenerApi) => {\n const { extra, getState, dispatch } = listenerApi;\n const { ThreadFront, protocolClient, replayClient } = extra;\n const state = getState();\n const { selectedNode, tree } = state.markup;\n\n if (!isInspectorSelected(state) || !selectedNode || !ThreadFront.currentPause?.pauseId) {\n return;\n }\n\n const nodeInfo = tree.entities[selectedNode];\n\n if (!nodeInfo) {\n return;\n }\n\n const [bounds, style] = await Promise.all([\n getBoundingRectAsync(\n protocolClient,\n ThreadFront.sessionId!,\n ThreadFront.currentPause.pauseId,\n selectedNode\n ),\n getComputedStyleAsync(\n protocolClient,\n ThreadFront.sessionId!,\n ThreadFront.currentPause.pauseId,\n selectedNode\n ),\n ]);\n\n if (!bounds || !style) {\n return;\n }\n\n const layout = {\n width: parseFloat(bounds.width.toPrecision(6)),\n height: parseFloat(bounds.height.toPrecision(6)),\n autoMargins: {},\n } as Layout;\n\n for (const prop of LAYOUT_NUMERIC_FIELDS) {\n layout[prop] = style.get(prop)!;\n }\n\n // Update the redux store with the latest layout properties and update the box model view.\n dispatch(layoutUpdated(layout));\n },\n });\n}\n"
50+
],
51+
"version": 3
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { isInspectorSelected } from "ui/reducers/app";
2+
import { getBoundingRectAsync, getComputedStyleAsync } from "ui/suspense/styleCaches";
3+
import { nodeSelected } from "../../markup/reducers/markup";
4+
import { LAYOUT_NUMERIC_FIELDS, layoutUpdated } from "../reducers/box-model";
5+
export function setupBoxModel(store, startAppListening) {
6+
// Any time a new node is selected in the "Markup" panel,
7+
// try to update the box model layout data
8+
startAppListening({
9+
actionCreator: nodeSelected,
10+
effect: async (action, listenerApi)=>{
11+
const { extra , getState , dispatch } = listenerApi;
12+
const { ThreadFront , protocolClient , replayClient } = extra;
13+
const state = getState();
14+
const { selectedNode , tree } = state.markup;
15+
if (!isInspectorSelected(state) || !selectedNode || !ThreadFront.currentPause?.pauseId) {
16+
return;
17+
}
18+
const nodeInfo = tree.entities[selectedNode];
19+
if (!nodeInfo) {
20+
return;
21+
}
22+
const [bounds, style] = await Promise.all([
23+
getBoundingRectAsync(protocolClient, ThreadFront.sessionId, ThreadFront.currentPause.pauseId, selectedNode),
24+
getComputedStyleAsync(protocolClient, ThreadFront.sessionId, ThreadFront.currentPause.pauseId, selectedNode)
25+
]);
26+
if (!bounds || !style) {
27+
return;
28+
}
29+
const layout = {
30+
width: parseFloat(bounds.width.toPrecision(6)),
31+
height: parseFloat(bounds.height.toPrecision(6)),
32+
autoMargins: {}
33+
};
34+
for (const prop of LAYOUT_NUMERIC_FIELDS){
35+
layout[prop] = style.get(prop);
36+
}
37+
// Update the redux store with the latest layout properties and update the box model view.
38+
dispatch(layoutUpdated(layout));
39+
}
40+
});
41+
}
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,42 @@
1-
(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
2-
[158],
1+
(self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([
2+
[
3+
158
4+
],
35
{
4-
/***/ 2943: /***/ function (
5-
__unused_webpack_module,
6-
__webpack_exports__,
7-
__webpack_require__
8-
) {
6+
2943: function(n, t, u) {
97
"use strict";
10-
__webpack_require__.r(__webpack_exports__);
11-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
12-
/* harmony export */ __N_SSG: function () {
13-
return /* binding */ __N_SSG;
14-
},
15-
/* harmony export */ default: function () {
16-
return /* binding */ StaticPage;
8+
var r = function(n) {
9+
var t = n.data;
10+
return (0, _.jsx)("div", {
11+
children: t.foo
12+
});
13+
};
14+
u.r(t), u.d(t, {
15+
__N_SSG: function() {
16+
return i;
1717
},
18-
/* harmony export */
18+
default: function() {
19+
return r;
20+
}
1921
});
20-
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
21-
__webpack_require__(4512);
22-
23-
var __N_SSG = true;
24-
function StaticPage(_ref) {
25-
var data = _ref.data;
26-
return /*#__PURE__*/ (0,
27-
react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
28-
children: data.foo,
29-
});
30-
}
31-
32-
/***/
22+
var _ = u(4512), i = !0;
3323
},
34-
35-
/***/ 7139: /***/ function (
36-
__unused_webpack_module,
37-
__unused_webpack_exports,
38-
__webpack_require__
39-
) {
24+
7139: function(n, t, u) {
4025
(window.__NEXT_P = window.__NEXT_P || []).push([
4126
"/static",
42-
function () {
43-
return __webpack_require__(2943);
44-
},
27+
function() {
28+
return u(2943);
29+
}
4530
]);
46-
if (false) {
47-
}
48-
49-
/***/
50-
},
51-
},
52-
/******/ function (__webpack_require__) {
53-
// webpackRuntimeModules
54-
/******/ var __webpack_exec__ = function (moduleId) {
55-
return __webpack_require__((__webpack_require__.s = moduleId));
56-
};
57-
/******/ __webpack_require__.O(0, [774, 888, 179], function () {
58-
return __webpack_exec__(7139);
59-
});
60-
/******/ var __webpack_exports__ = __webpack_require__.O();
61-
/******/ _N_E = __webpack_exports__;
62-
/******/
31+
}
6332
},
33+
function(n) {
34+
n.O(0, [
35+
774,
36+
888,
37+
179
38+
], function() {
39+
return n(n.s = 7139);
40+
}), _N_E = n.O();
41+
}
6442
]);

‎crates/swc/tests/fixture/sourcemap/004/input/index.js.map

+32-16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/swc/tests/fixture/sourcemap/004/output/index.map

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
2-
"mappings": "AEACA,CAAAA,KAAK,gBAAmB,GAAGA,KAAK,gBAAmB,IAAI,EAAE,AAAD,EAAGC,IAAI,CAAC;IAC7D;QAAC;KAAI;IACL;QACU,MAAY,SACdC,CAAuB,EACvBC,CAAmB,EACnBC,CAAmB,EACrB;YACE;gBFNXC,IAAA,SAAAC,CAAA,EAAA;gBAAA,IAAAC,IAAAD,EAAAC,IAAA;gBAAA,OAAA,CAAA,GCDDC,EAAAC,GAAA,EAAA,OAAA;oBACAC,UAAAH,EAAAI,GAAA;gBACA;YACA;YAKYP,EAAoBQ,CAAC,CAACT,IACDC,EAAoBS,CAAC,CAACV,GAAqB;gBACvCW,SAAS,WAAY;oBACtC,OAAqBA;gBDZjB;gBAAqBC,SAAA,WAAA;oBAC3C,OAAOV;gBAAM;YACd;YAAA,IAAAG,IAAAJ,EAAA,OAAAU,IAAA,CAAA;QCKM;QAKP,MAAA,SAAAZ,CAAA,EAAAc,CAAA,EAAAZ,CAAA,EAAA;YAAAa,CAAAA,OAAAC,QAAA,GAAAD,OAAAC,QAAA,IAAA,EAAA,EAAAjB,IAAA,CAAA;gBAAA;gBAAA,WAAA;oBAAA,OAAAG,EAAA;gBAAA;aAAA;QAAA;IAAA;IAAA,SAAAA,CAAA,EAAA;QAAAA,EAAAe,CAAA,CAAA,GAAA;YAAA;YAAA;YAAA;SAAA,EAAA,WAAA;YAAA,OAAAf,EAAAA,EAAAgB,CAAA,GAAA;QAAA,IAAAC,OAAAjB,EAAAe,CAAA;IAAA;CAAA",
2+
"mappings": "AAACA,CAAAA,KAAKC,gBAAmB,GAAGD,KAAKC,gBAAmB,IAAI,EAAC,AAAD,EAAIC,IAAI,CAAC;IAC7D;QACI;KACH;IACD;QACU,MAAY,SAAUC,CAAuB,EAAEC,CAAmB,EAAEC,CAAmB,EAAE;YAC3F;YACA,IAAIC,IAAa,SAAoBC,CAAI,EAAE;gBACvC,IAAIC,IAAOD,EAAKC,IAAI;gBACpB,OAAsB,CAAA,GAAGC,EAA+CC,GAAE,AAAFA,EAAK,OAAO;oBAChFC,UAAUH,EAAKI,GAAG;gBACtB;YACJ;YACAP,EAAoBQ,CAAC,CAACT,IACDC,EAAoBS,CAAC,CAACV,GAAqB;gBACvCW,SAAS,WAAoB;oBAC9C,OAAqBA;gBACzB;gBACqBC,SAAS,WAAoB;oBAC9C,OAAqBV;gBACzB;YACJ,EAAA;YACqB,IAAIG,IAAiDJ,EAAoB,OAC1FU,IAAU,CAAA;QAE1B;QACc,MAAY,SAAUZ,CAAuB,EAAEc,CAAwB,EAAEZ,CAAmB,EAAE;YAC/Fa,CAAAA,OAAOC,QAAQ,GAAGD,OAAOC,QAAQ,IAAI,EAAC,AAAD,EAAIjB,IAAI,CAAC;gBAC3C;gBACA,WAAY;oBACR,OAAOG,EAAoB;gBAC/B;aACH;QAGb;IACI;IACS,SAAUA,CAAmB,EAAE;QAK3BA,EAAoBe,CAAC,CAAC,GAAG;YAC9B;YACA;YACA;SACH,EAAE,WAAY;YACX,OAPOf,EAAoBA,EAAoBgB,CAAC,GAOxB;QAC5B,IAESC,OAD0BjB,EAAoBe,CAAC,EAAA;IAGhE;CACC",
33
"names": [
44
"self",
5+
"webpackChunk_N_E",
56
"push",
67
"__unused_webpack_module",
78
"__webpack_exports__",
@@ -25,14 +26,10 @@
2526
"_N_E"
2627
],
2728
"sources": [
28-
"webpack://./pages/static.js",
29-
"webpack://../../../packages/next/dist/build/webpack/loaders/next-client-pages-loader.js?page=%2Fstatic&absolutePagePath=private-next-pages%2Fstatic.js!",
3029
"../../input/index.js"
3130
],
3231
"sourcesContent": [
33-
"export default function StaticPage({ data }) {\n return <div>{data.foo}</div>\n}\n\nexport async function getStaticProps() {\n return {\n props: {\n data: {\n foo: 'bar',\n },\n },\n }\n}\n",
34-
"\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/static\",\n function () {\n return require(\"private-next-pages/static.js\");\n }\n ]);\n if(module.hot) {\n module.hot.dispose(function () {\n window.__NEXT_P.push([\"/static\"])\n });\n }\n ",
35-
"(self[\"webpackChunk_N_E\"] = self[\"webpackChunk_N_E\"] || []).push([\n [158],\n {\n /***/ 2943: /***/ function (\n __unused_webpack_module,\n __webpack_exports__,\n __webpack_require__\n ) {\n \"use strict\";\n __webpack_require__.r(__webpack_exports__);\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ __N_SSG: function () {\n return /* binding */ __N_SSG;\n },\n /* harmony export */ default: function () {\n return /* binding */ StaticPage;\n },\n /* harmony export */\n });\n /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =\n __webpack_require__(4512);\n\n var __N_SSG = true;\n function StaticPage(_ref) {\n var data = _ref.data;\n return /*#__PURE__*/ (0,\n react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: data.foo,\n });\n }\n\n /***/\n },\n\n /***/ 7139: /***/ function (\n __unused_webpack_module,\n __unused_webpack_exports,\n __webpack_require__\n ) {\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/static\",\n function () {\n return __webpack_require__(2943);\n },\n ]);\n if (false) {\n }\n\n /***/\n },\n },\n /******/ function (__webpack_require__) {\n // webpackRuntimeModules\n /******/ var __webpack_exec__ = function (moduleId) {\n return __webpack_require__((__webpack_require__.s = moduleId));\n };\n /******/ __webpack_require__.O(0, [774, 888, 179], function () {\n return __webpack_exec__(7139);\n });\n /******/ var __webpack_exports__ = __webpack_require__.O();\n /******/ _N_E = __webpack_exports__;\n /******/\n },\n]);\n"
32+
"(self[\"webpackChunk_N_E\"] = self[\"webpackChunk_N_E\"] || []).push([\n [\n 158\n ],\n {\n /***/ 2943: /***/ function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n \"use strict\";\n var StaticPage = function StaticPage(_ref) {\n var data = _ref.data;\n return /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(\"div\", {\n children: data.foo\n });\n };\n __webpack_require__.r(__webpack_exports__);\n /* harmony export */ __webpack_require__.d(__webpack_exports__, {\n /* harmony export */ __N_SSG: function __N_SSG1() {\n return /* binding */ __N_SSG;\n },\n /* harmony export */ default: function _default() {\n return /* binding */ StaticPage;\n }\n });\n /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4512);\n var __N_SSG = true;\n /***/\n},\n /***/ 7139: /***/ function (__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {\n (window.__NEXT_P = window.__NEXT_P || []).push([\n \"/static\",\n function () {\n return __webpack_require__(2943);\n }\n ]);\n if (false) { }\n /***/\n}\n },\n /******/ function (__webpack_require__) {\n // webpackRuntimeModules\n /******/ var __webpack_exec__ = function __webpack_exec__(moduleId) {\n return __webpack_require__(__webpack_require__.s = moduleId);\n };\n /******/ __webpack_require__.O(0, [\n 774,\n 888,\n 179\n ], function () {\n return __webpack_exec__(7139);\n });\n /******/ var __webpack_exports__ = __webpack_require__.O();\n /******/ _N_E = __webpack_exports__;\n /******/\n}\n]);\n"
3633
],
3734
"version": 3
3835
}

‎crates/swc/tests/source_map.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ use std::{
1111

1212
use anyhow::{Context, Error};
1313
use swc::{
14-
config::{Config, IsModule, ModuleConfig, Options, SourceMapsConfig},
14+
config::{Config, InputSourceMap, IsModule, ModuleConfig, Options, SourceMapsConfig},
1515
Compiler,
1616
};
1717
use testing::{assert_eq, NormalizedOutput, StdErr, Tester};
1818
use walkdir::WalkDir;
1919

20-
fn file(f: &str) -> Result<(), StdErr> {
20+
fn file(f: &str, config: Config) -> Result<(), StdErr> {
2121
Tester::new().print_errors(|cm, handler| {
2222
let path = canonicalize(f).expect("failed to canonicalize");
2323

@@ -32,7 +32,7 @@ fn file(f: &str) -> Result<(), StdErr> {
3232
config: Config {
3333
is_module: IsModule::Bool(true),
3434
inline_sources_content: true.into(),
35-
..Default::default()
35+
..config
3636
},
3737
swcrc: true,
3838
source_maps: Some(SourceMapsConfig::Bool(true)),
@@ -69,7 +69,7 @@ fn file(f: &str) -> Result<(), StdErr> {
6969

7070
#[test]
7171
fn issue_622() {
72-
file("tests/srcmap/issue-622/index.js").unwrap();
72+
file("tests/srcmap/issue-622/index.js", Default::default()).unwrap();
7373
}
7474

7575
fn inline(f: &str) -> Result<(), StdErr> {
@@ -412,3 +412,15 @@ fn should_work_with_emit_source_map_columns() {
412412
Ok(())
413413
});
414414
}
415+
416+
#[test]
417+
fn issue_4578() {
418+
file(
419+
"tests/srcmap/issue-4578/after-babel.js",
420+
Config {
421+
input_source_map: Some(InputSourceMap::Str("inline".into())),
422+
..Default::default()
423+
},
424+
)
425+
.unwrap();
426+
}

‎crates/swc/tests/srcmap/issue-4578/after-babel.js

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/swc_common/src/source_map.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,7 @@ impl SourceMap {
11951195
let mut ch_start = 0;
11961196
let mut line_prev_extra_bytes = 0;
11971197
let mut line_ch_start = 0;
1198+
let mut inline_sources_content = false;
11981199

11991200
for (pos, lc) in mappings.iter() {
12001201
let pos = *pos;
@@ -1223,7 +1224,8 @@ impl SourceMap {
12231224
f = self.lookup_source_file(pos);
12241225
src_id = builder.add_source(&config.file_name_to_source(&f.name));
12251226

1226-
if config.inline_sources_content(&f.name) {
1227+
inline_sources_content = config.inline_sources_content(&f.name);
1228+
if inline_sources_content && orig.is_none() {
12271229
builder.set_source_contents(src_id, Some(&f.src));
12281230
}
12291231

@@ -1252,13 +1254,10 @@ impl SourceMap {
12521254
None => continue,
12531255
};
12541256

1257+
let mut name = config.name_for_bytepos(pos);
12551258
let mut name_idx = None;
12561259

1257-
if let Some(name) = config.name_for_bytepos(pos) {
1258-
name_idx = Some(builder.add_name(name))
1259-
}
1260-
1261-
let mut line = a + 1; // Line numbers start at 1
1260+
let mut line = a;
12621261

12631262
let linebpos = f.lines[a as usize];
12641263
debug_assert!(
@@ -1281,16 +1280,33 @@ impl SourceMap {
12811280
let mut col = max(chpos, linechpos) - min(chpos, linechpos);
12821281

12831282
if let Some(orig) = &orig {
1284-
if let Some(token) = orig.lookup_token(line, col) {
1285-
line = token.get_src_line() + 1;
1283+
if let Some(token) = orig
1284+
.lookup_token(line, col)
1285+
.filter(|t| t.get_dst_line() == line)
1286+
{
1287+
line = token.get_src_line();
12861288
col = token.get_src_col();
1289+
if token.has_name() {
1290+
name = token.get_name();
1291+
}
12871292
if let Some(src) = token.get_source() {
12881293
src_id = builder.add_source(src);
1294+
if inline_sources_content && !builder.has_source_contents(src_id) {
1295+
if let Some(contents) = token.get_source_view() {
1296+
builder.set_source_contents(src_id, Some(contents.source()));
1297+
}
1298+
}
12891299
}
1300+
} else {
1301+
continue;
12901302
}
12911303
}
12921304

1293-
builder.add_raw(lc.line, lc.col, line - 1, col, Some(src_id), name_idx);
1305+
if let Some(name) = name {
1306+
name_idx = Some(builder.add_name(name))
1307+
}
1308+
1309+
builder.add_raw(lc.line, lc.col, line, col, Some(src_id), name_idx);
12941310
prev_dst_line = lc.line;
12951311
}
12961312

1 commit comments

Comments
 (1)

github-actions[bot] commented on Dec 2, 2022

@github-actions[bot]

Benchmark

Benchmark suite Current: 4af52c7 Previous: cdf0d8a Ratio
es/full/bugs-1 336470 ns/iter (± 26017) 347600 ns/iter (± 21107) 0.97
es/full/minify/libraries/antd 1977533977 ns/iter (± 22733268) 2036833240 ns/iter (± 65299279) 0.97
es/full/minify/libraries/d3 440415931 ns/iter (± 18969435) 449921640 ns/iter (± 15545822) 0.98
es/full/minify/libraries/echarts 1727554504 ns/iter (± 44917915) 1747869817 ns/iter (± 284198529) 0.99
es/full/minify/libraries/jquery 111171313 ns/iter (± 2980819) 114051503 ns/iter (± 2348462) 0.97
es/full/minify/libraries/lodash 140959178 ns/iter (± 2959741) 131359407 ns/iter (± 5068345) 1.07
es/full/minify/libraries/moment 70889602 ns/iter (± 1540179) 66839836 ns/iter (± 2236533) 1.06
es/full/minify/libraries/react 22869963 ns/iter (± 546241) 22065996 ns/iter (± 609807) 1.04
es/full/minify/libraries/terser 336309217 ns/iter (± 21053548) 342266503 ns/iter (± 15979735) 0.98
es/full/minify/libraries/three 616913334 ns/iter (± 8726645) 625347510 ns/iter (± 13892819) 0.99
es/full/minify/libraries/typescript 3668020802 ns/iter (± 29183046) 3659254464 ns/iter (± 77550761) 1.00
es/full/minify/libraries/victory 903282720 ns/iter (± 21075307) 909940842 ns/iter (± 27053033) 0.99
es/full/minify/libraries/vue 168089590 ns/iter (± 8536610) 172808513 ns/iter (± 13676562) 0.97
es/full/codegen/es3 33481 ns/iter (± 579) 34457 ns/iter (± 2655) 0.97
es/full/codegen/es5 33410 ns/iter (± 526) 34829 ns/iter (± 1764) 0.96
es/full/codegen/es2015 33423 ns/iter (± 463) 34404 ns/iter (± 1268) 0.97
es/full/codegen/es2016 33390 ns/iter (± 977) 35214 ns/iter (± 927) 0.95
es/full/codegen/es2017 32839 ns/iter (± 1105) 34752 ns/iter (± 713) 0.94
es/full/codegen/es2018 33307 ns/iter (± 1154) 34071 ns/iter (± 950) 0.98
es/full/codegen/es2019 33400 ns/iter (± 511) 34559 ns/iter (± 1412) 0.97
es/full/codegen/es2020 33420 ns/iter (± 342) 34200 ns/iter (± 1638) 0.98
es/full/all/es3 188046506 ns/iter (± 8881474) 206436493 ns/iter (± 28503818) 0.91
es/full/all/es5 179533046 ns/iter (± 8181022) 209892739 ns/iter (± 18569666) 0.86
es/full/all/es2015 144321531 ns/iter (± 8234440) 152457874 ns/iter (± 17148838) 0.95
es/full/all/es2016 143821601 ns/iter (± 20042934) 155336471 ns/iter (± 23154947) 0.93
es/full/all/es2017 141150194 ns/iter (± 4526075) 156618860 ns/iter (± 16557551) 0.90
es/full/all/es2018 139321767 ns/iter (± 9122253) 148978570 ns/iter (± 14036603) 0.94
es/full/all/es2019 150396187 ns/iter (± 10414466) 156612369 ns/iter (± 17188799) 0.96
es/full/all/es2020 145464943 ns/iter (± 13307571) 150456177 ns/iter (± 14219881) 0.97
es/full/parser 708816 ns/iter (± 41381) 741042 ns/iter (± 38352) 0.96
es/full/base/fixer 25966 ns/iter (± 935) 26725 ns/iter (± 1304) 0.97
es/full/base/resolver_and_hygiene 91685 ns/iter (± 3209) 93473 ns/iter (± 5180) 0.98
serialization of ast node 209 ns/iter (± 5) 211 ns/iter (± 8) 0.99
serialization of serde 218 ns/iter (± 10) 222 ns/iter (± 5) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.