diff --git a/.changeset/cool-eggs-jump.md b/.changeset/cool-eggs-jump.md
new file mode 100644
index 000000000000..f44c6ae593cf
--- /dev/null
+++ b/.changeset/cool-eggs-jump.md
@@ -0,0 +1,6 @@
+---
+swc_core: patch
+swc_ecma_parser: patch
+---
+
+fix(es/parser): Preserve comment positions with leading semicolon
diff --git a/crates/swc/tests/fixture/issues-10xxx/10018/input/.swcrc b/crates/swc/tests/fixture/issues-10xxx/10018/input/.swcrc
new file mode 100644
index 000000000000..ed5fe8178efd
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-10xxx/10018/input/.swcrc
@@ -0,0 +1,19 @@
+{
+ "jsc": {
+ "parser": {
+ "syntax": "ecmascript",
+ "jsx": true
+ },
+ "target": "es5",
+ "loose": false,
+ "minify": {
+ "compress": false,
+ "mangle": false
+ }
+ },
+ "module": {
+ "type": "es6"
+ },
+ "minify": false,
+ "isModule": true
+}
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-10xxx/10018/input/idnex.jsx b/crates/swc/tests/fixture/issues-10xxx/10018/input/idnex.jsx
new file mode 100644
index 000000000000..edc47a439099
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-10xxx/10018/input/idnex.jsx
@@ -0,0 +1,3 @@
+/* @jsxImportSource foo */
+;
+
\ No newline at end of file
diff --git a/crates/swc/tests/fixture/issues-10xxx/10018/output/idnex.jsx b/crates/swc/tests/fixture/issues-10xxx/10018/output/idnex.jsx
new file mode 100644
index 000000000000..130d3db9d6be
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-10xxx/10018/output/idnex.jsx
@@ -0,0 +1,3 @@
+var _require = require("foo/jsx-runtime"), _jsx = _require.jsx;
+;
+_jsx("a", {});
diff --git a/crates/swc_ecma_codegen/tests/test262/f2142c1dabd961c1.js b/crates/swc_ecma_codegen/tests/test262/f2142c1dabd961c1.js
index 221bebd698c3..a9320bf0c68a 100644
--- a/crates/swc_ecma_codegen/tests/test262/f2142c1dabd961c1.js
+++ b/crates/swc_ecma_codegen/tests/test262/f2142c1dabd961c1.js
@@ -1,2 +1,2 @@
-;
+/* not comment*/ ;
a-- > 1;
diff --git a/crates/swc_ecma_minifier/tests/benches-full/lodash.js b/crates/swc_ecma_minifier/tests/benches-full/lodash.js
index 7693c0cc5f3d..3bea154e12dc 100644
--- a/crates/swc_ecma_minifier/tests/benches-full/lodash.js
+++ b/crates/swc_ecma_minifier/tests/benches-full/lodash.js
@@ -1,4 +1,11 @@
-(function() {
+/**
+ * @license
+ * Lodash
+ * Copyright OpenJS Foundation and other contributors
+ * Released under MIT license
+ * Based on Underscore.js 1.8.3
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ */ (function() {
/** Error message constants. */ var undefined, FUNC_ERROR_TEXT = 'Expected a function', HASH_UNDEFINED = '__lodash_hash_undefined__', PLACEHOLDER = '__lodash_placeholder__', INFINITY = 1 / 0, NAN = 0 / 0, wrapFlags = [
[
'ary',
diff --git a/crates/swc_ecma_minifier/tests/benches-full/three.js b/crates/swc_ecma_minifier/tests/benches-full/three.js
index f2c6f65c4a8e..69d9d810c12d 100644
--- a/crates/swc_ecma_minifier/tests/benches-full/three.js
+++ b/crates/swc_ecma_minifier/tests/benches-full/three.js
@@ -13111,7 +13111,7 @@ function(global, factory) {
void 0 === skeleton ? console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton) : child.bind(skeleton, child.bindMatrix);
}
});
- } /* DEPRECATED */ , _proto.setTexturePath = function(value) {
+ }, _proto.setTexturePath = function(value) {
return console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().'), this.setResourcePath(value);
}, ObjectLoader;
}(Loader), TEXTURE_MAPPING = {
@@ -15420,33 +15420,15 @@ function(global, factory) {
void 0 === sigma && (sigma = 0), void 0 === near && (near = 0.1), void 0 === far && (far = 100), _oldTarget = this._renderer.getRenderTarget();
var cubeUVRenderTarget = this._allocateTargets();
return this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget), sigma > 0 && this._blur(cubeUVRenderTarget, 0, 0, sigma), this._applyPMREM(cubeUVRenderTarget), this._cleanup(cubeUVRenderTarget), cubeUVRenderTarget;
- } /**
- * Generates a PMREM from an equirectangular texture, which can be either LDR
- * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512),
- * as this matches best with the 256 x 256 cubemap output.
- */ , _proto.fromEquirectangular = function(equirectangular) {
+ }, _proto.fromEquirectangular = function(equirectangular) {
return this._fromTexture(equirectangular);
- } /**
- * Generates a PMREM from an cubemap texture, which can be either LDR
- * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256,
- * as this matches best with the 256 x 256 cubemap output.
- */ , _proto.fromCubemap = function(cubemap) {
+ }, _proto.fromCubemap = function(cubemap) {
return this._fromTexture(cubemap);
- } /**
- * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
- * your texture's network fetch for increased concurrency.
- */ , _proto.compileCubemapShader = function() {
+ }, _proto.compileCubemapShader = function() {
null === this._cubemapShader && (this._cubemapShader = _getCubemapShader(), this._compileMaterial(this._cubemapShader));
- } /**
- * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
- * your texture's network fetch for increased concurrency.
- */ , _proto.compileEquirectangularShader = function() {
+ }, _proto.compileEquirectangularShader = function() {
null === this._equirectShader && (this._equirectShader = _getEquirectShader(), this._compileMaterial(this._equirectShader));
- } /**
- * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
- * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
- * one of them will cause any others to also become unusable.
- */ , _proto.dispose = function() {
+ }, _proto.dispose = function() {
this._blurMaterial.dispose(), null !== this._cubemapShader && this._cubemapShader.dispose(), null !== this._equirectShader && this._equirectShader.dispose();
for(var i = 0; i < _lodPlanes.length; i++)_lodPlanes[i].dispose();
} // private interface
@@ -15514,13 +15496,7 @@ function(global, factory) {
this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis);
}
renderer.autoClear = autoClear;
- } /**
- * This is a two-pass Gaussian blur for a cubemap. Normally this is done
- * vertically and horizontally, but this breaks down on a cube. Here we apply
- * the blur latitudinally (around the poles), and then longitudinally (towards
- * the poles) to approximate the orthogonally-separable blur. It is least
- * accurate at the poles, but still does a decent job.
- */ , _proto._blur = function(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
+ }, _proto._blur = function(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
var pingPongRenderTarget = this._pingPongRenderTarget;
this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis), this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis);
}, _proto._halfBlur = function(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) {
diff --git a/crates/swc_ecma_parser/src/lexer/util.rs b/crates/swc_ecma_parser/src/lexer/util.rs
index cb7dc83c2681..23c6c368f12e 100644
--- a/crates/swc_ecma_parser/src/lexer/util.rs
+++ b/crates/swc_ecma_parser/src/lexer/util.rs
@@ -272,7 +272,7 @@ impl Lexer<'_> {
self.skip_space::();
- if self.input.is_byte(b';') {
+ if !self.state.had_line_break && self.input.is_byte(b';') {
is_for_next = false;
}