diff --git a/Cargo.toml b/Cargo.toml index 567a008ed68f..7fbb30b0819e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc" repository = "https://github.com/swc-project/swc.git" -version = "0.10.0" +version = "0.11.0" [lib] name = "swc" @@ -31,10 +31,10 @@ swc_atoms = {version = "0.2", path = "./atoms"} swc_common = {version = "0.10.10", path = "./common", features = ["sourcemap", "concurrent"]} swc_ecma_ast = {version = "0.40.0", path = "./ecmascript/ast"} swc_ecma_codegen = {version = "0.48.0", path = "./ecmascript/codegen"} -swc_ecma_ext_transforms = {version = "0.7.0", path = "./ecmascript/ext-transforms"} +swc_ecma_ext_transforms = {version = "0.8.0", path = "./ecmascript/ext-transforms"} swc_ecma_parser = {version = "0.50.0", path = "./ecmascript/parser"} -swc_ecma_preset_env = {version = "0.10.0", path = "./ecmascript/preset_env"} -swc_ecma_transforms = {version = "0.40.0", path = "./ecmascript/transforms", features = [ +swc_ecma_preset_env = {version = "0.11.0", path = "./ecmascript/preset_env"} +swc_ecma_transforms = {version = "0.41.0", path = "./ecmascript/transforms", features = [ "compat", "module", "optimization", @@ -42,7 +42,7 @@ swc_ecma_transforms = {version = "0.40.0", path = "./ecmascript/transforms", fea "react", "typescript", ]} -swc_ecma_utils = {version = "0.30.0", path = "./ecmascript/utils"} +swc_ecma_utils = {version = "0.31.0", path = "./ecmascript/utils"} swc_ecma_visit = {version = "0.26.0", path = "./ecmascript/visit"} swc_visit = {version = "0.2.3", path = "./visit"} diff --git a/bundler/Cargo.toml b/bundler/Cargo.toml index fcd4c22bb7dd..1fe14dfcabf8 100644 --- a/bundler/Cargo.toml +++ b/bundler/Cargo.toml @@ -9,7 +9,7 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/**/*.js"] license = "Apache-2.0/MIT" name = "swc_bundler" repository = "https://github.com/swc-project/swc.git" -version = "0.27.0" +version = "0.28.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] @@ -35,8 +35,8 @@ swc_common = {version = "0.10.10", path = "../common"} swc_ecma_ast = {version = "0.40.0", path = "../ecmascript/ast"} swc_ecma_codegen = {version = "0.48.0", path = "../ecmascript/codegen"} swc_ecma_parser = {version = "0.50.0", path = "../ecmascript/parser"} -swc_ecma_transforms = {version = "0.40.0", path = "../ecmascript/transforms", features = ["optimization"]} -swc_ecma_utils = {version = "0.30.0", path = "../ecmascript/utils"} +swc_ecma_transforms = {version = "0.41.0", path = "../ecmascript/transforms", features = ["optimization"]} +swc_ecma_utils = {version = "0.31.0", path = "../ecmascript/utils"} swc_ecma_visit = {version = "0.26.0", path = "../ecmascript/visit"} [dev-dependencies] @@ -44,7 +44,7 @@ hex = "0.4" ntest = "0.7.2" reqwest = {version = "0.10.8", features = ["blocking"]} sha-1 = "0.9" -swc_ecma_transforms = {version = "0.40.0", path = "../ecmascript/transforms", features = ["react", "typescript"]} +swc_ecma_transforms = {version = "0.41.0", path = "../ecmascript/transforms", features = ["react", "typescript"]} tempfile = "3.1.0" testing = {version = "0.10.3", path = "../testing"} url = "2.1.1" diff --git a/bundler/tests/fixture/deno-9591/output/entry.inlined.ts b/bundler/tests/fixture/deno-9591/output/entry.inlined.ts index 3a28a5a1666c..cc0a57aff025 100644 --- a/bundler/tests/fixture/deno-9591/output/entry.inlined.ts +++ b/bundler/tests/fixture/deno-9591/output/entry.inlined.ts @@ -1327,7 +1327,7 @@ function common(paths, sep2 = SEP) { const prefix = parts.slice(0, endOfPrefix).join(sep2); return prefix.endsWith(sep2) ? prefix : `${prefix}${sep2}`; } -const path1 = isWindows ? mod1 : mod2; +const path = isWindows ? mod1 : mod2; const regExpEscapeChars = [ "!", "$", @@ -1344,7 +1344,7 @@ const regExpEscapeChars = [ "{", "|" ]; -const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join2 , normalize: normalize2 , parse: parse3 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 , } = path1; +const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join2 , normalize: normalize2 , parse: parse3 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 , } = path; const rangeEscapeChars = [ "-", "\\", @@ -1851,26 +1851,26 @@ const MIN_BUF_SIZE = 16; const CR = "\r".charCodeAt(0); const LF = "\n".charCodeAt(0); class BufferFullError extends Error { - name = "BufferFullError"; constructor(partial){ super("Buffer full"); this.partial = partial; + this.name = "BufferFullError"; } } class PartialReadError extends Deno.errors.UnexpectedEof { - name = "PartialReadError"; constructor(){ super("Encountered UnexpectedEof, data only partially read"); + this.name = "PartialReadError"; } } class BufReader { - r = 0; - w = 0; - eof = false; static create(r, size = 4096) { return r instanceof BufReader ? r : new BufReader(r, size); } constructor(rd1, size1 = 4096){ + this.r = 0; + this.w = 0; + this.eof = false; if (size1 < 16) { size1 = MIN_BUF_SIZE; } @@ -2073,8 +2073,6 @@ class BufReader { } } class AbstractBufBase { - usedBufferBytes = 0; - err = null; size() { return this.buf.byteLength; } @@ -2084,6 +2082,10 @@ class AbstractBufBase { buffered() { return this.usedBufferBytes; } + constructor(){ + this.usedBufferBytes = 0; + this.err = null; + } } class BufWriter extends AbstractBufBase { static create(writer, size = 4096) { @@ -2257,11 +2259,11 @@ class WriterHandler extends BaseHandler { #encoder=new TextEncoder(); } class FileHandler extends WriterHandler { - _encoder = new TextEncoder(); #unloadCallback=()=>this.destroy() ; constructor(levelName3, options3){ super(levelName3, options3); + this._encoder = new TextEncoder(); this._filename = options3.filename; this._mode = options3.mode ? options3.mode : "a"; this._openOptions = { @@ -5925,10 +5927,10 @@ class ADLMap { } } class Manifest { - jsonBinding = createJsonBinding(RESOLVER, texprManifest()); - tasks = new ADLMap([], (k1, k2)=>k1 === k2 - ); constructor(dir, filename = ".manifest.json"){ + this.jsonBinding = createJsonBinding(RESOLVER, texprManifest()); + this.tasks = new ADLMap([], (k1, k2)=>k1 === k2 + ); this.filename = mod3.join(dir, filename); } async load() { @@ -5957,10 +5959,10 @@ class Manifest { } } class TaskManifest { - lastExecution = null; - trackedFiles = new ADLMap([], (k1, k2)=>k1 === k2 - ); constructor(data1){ + this.lastExecution = null; + this.trackedFiles = new ADLMap([], (k1, k2)=>k1 === k2 + ); this.trackedFiles = new ADLMap(data1.trackedFiles, (k1, k2)=>k1 === k2 ); this.lastExecution = data1.lastExecution; @@ -5982,9 +5984,9 @@ class TaskManifest { } } class AsyncQueue { - inProgress = 0; - queue = []; constructor(concurrency){ + this.inProgress = 0; + this.queue = []; this.concurrency = concurrency; } async schedule(t) { @@ -6017,16 +6019,16 @@ class AsyncQueue { } } class ExecContext { - taskRegister = new Map(); - targetRegister = new Map(); - doneTasks = new Set(); - inprogressTasks = new Set(); - internalLogger = mod4.getLogger("internal"); - taskLogger = mod4.getLogger("task"); - userLogger = mod4.getLogger("user"); constructor(manifest, args){ this.manifest = manifest; this.args = args; + this.taskRegister = new Map(); + this.targetRegister = new Map(); + this.doneTasks = new Set(); + this.inprogressTasks = new Set(); + this.internalLogger = mod4.getLogger("internal"); + this.taskLogger = mod4.getLogger("task"); + this.userLogger = mod4.getLogger("user"); if (args["verbose"] !== undefined) { this.internalLogger.levelName = "INFO"; } @@ -6071,8 +6073,8 @@ async function statPath(path1) { } } class Task { - taskManifest = null; constructor(taskParams){ + this.taskManifest = null; this.name = taskParams.name; this.action = taskParams.action; this.description = taskParams.description; @@ -6199,11 +6201,11 @@ class Task { } } class TrackedFile { - path = ""; #getHash; #getTimestamp; - fromTask = null; constructor(fileParams){ + this.path = ""; + this.fromTask = null; this.path = mod3.posix.resolve(fileParams.path); this.#getHash = fileParams.getHash || getFileSha1Sum; this.#getTimestamp = fileParams.getTimestamp || getFileTimestamp; @@ -6293,9 +6295,9 @@ class TrackedFile { } } class TrackedFilesAsync { - kind = 'trackedfilesasync'; constructor(gen){ this.gen = gen; + this.kind = 'trackedfilesasync'; } async getTrackedFiles() { return this.gen(); diff --git a/bundler/tests/fixture/deno-9591/output/entry.ts b/bundler/tests/fixture/deno-9591/output/entry.ts index 9bb455c935a6..c79b599ae22b 100644 --- a/bundler/tests/fixture/deno-9591/output/entry.ts +++ b/bundler/tests/fixture/deno-9591/output/entry.ts @@ -1335,7 +1335,7 @@ function common(paths, sep2 = SEP) { const prefix = parts.slice(0, endOfPrefix).join(sep2); return prefix.endsWith(sep2) ? prefix : `${prefix}${sep2}`; } -const path1 = isWindows ? mod1 : mod2; +const path = isWindows ? mod1 : mod2; const regExpEscapeChars = [ "!", "$", @@ -1354,7 +1354,7 @@ const regExpEscapeChars = [ ]; const win32 = mod1; const posix = mod2; -const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join2 , normalize: normalize2 , parse: parse3 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 , } = path1; +const { basename: basename2 , delimiter: delimiter2 , dirname: dirname2 , extname: extname2 , format: format2 , fromFileUrl: fromFileUrl2 , isAbsolute: isAbsolute2 , join: join2 , normalize: normalize2 , parse: parse3 , relative: relative2 , resolve: resolve2 , sep: sep2 , toFileUrl: toFileUrl2 , toNamespacedPath: toNamespacedPath2 , } = path; const rangeEscapeChars = [ "-", "\\", @@ -1862,26 +1862,26 @@ const MAX_CONSECUTIVE_EMPTY_READS = 100; const CR = "\r".charCodeAt(0); const LF = "\n".charCodeAt(0); class BufferFullError extends Error { - name = "BufferFullError"; constructor(partial){ super("Buffer full"); this.partial = partial; + this.name = "BufferFullError"; } } class PartialReadError extends Deno.errors.UnexpectedEof { - name = "PartialReadError"; constructor(){ super("Encountered UnexpectedEof, data only partially read"); + this.name = "PartialReadError"; } } class BufReader { - r = 0; - w = 0; - eof = false; static create(r, size = DEFAULT_BUF_SIZE) { return r instanceof BufReader ? r : new BufReader(r, size); } constructor(rd1, size1 = DEFAULT_BUF_SIZE){ + this.r = 0; + this.w = 0; + this.eof = false; if (size1 < MIN_BUF_SIZE) { size1 = MIN_BUF_SIZE; } @@ -2084,8 +2084,6 @@ class BufReader { } } class AbstractBufBase { - usedBufferBytes = 0; - err = null; size() { return this.buf.byteLength; } @@ -2095,6 +2093,10 @@ class AbstractBufBase { buffered() { return this.usedBufferBytes; } + constructor(){ + this.usedBufferBytes = 0; + this.err = null; + } } class BufWriter extends AbstractBufBase { static create(writer, size = DEFAULT_BUF_SIZE) { @@ -2268,11 +2270,11 @@ class WriterHandler extends BaseHandler { #encoder=new TextEncoder(); } class FileHandler extends WriterHandler { - _encoder = new TextEncoder(); #unloadCallback=()=>this.destroy() ; constructor(levelName3, options3){ super(levelName3, options3); + this._encoder = new TextEncoder(); this._filename = options3.filename; this._mode = options3.mode ? options3.mode : "a"; this._openOptions = { @@ -5937,10 +5939,10 @@ class ADLMap { } } class Manifest { - jsonBinding = createJsonBinding(RESOLVER, texprManifest()); - tasks = new ADLMap([], (k1, k2)=>k1 === k2 - ); constructor(dir, filename = ".manifest.json"){ + this.jsonBinding = createJsonBinding(RESOLVER, texprManifest()); + this.tasks = new ADLMap([], (k1, k2)=>k1 === k2 + ); this.filename = mod3.join(dir, filename); } async load() { @@ -5969,10 +5971,10 @@ class Manifest { } } class TaskManifest { - lastExecution = null; - trackedFiles = new ADLMap([], (k1, k2)=>k1 === k2 - ); constructor(data1){ + this.lastExecution = null; + this.trackedFiles = new ADLMap([], (k1, k2)=>k1 === k2 + ); this.trackedFiles = new ADLMap(data1.trackedFiles, (k1, k2)=>k1 === k2 ); this.lastExecution = data1.lastExecution; @@ -5994,9 +5996,9 @@ class TaskManifest { } } class AsyncQueue { - inProgress = 0; - queue = []; constructor(concurrency){ + this.inProgress = 0; + this.queue = []; this.concurrency = concurrency; } async schedule(t) { @@ -6029,16 +6031,16 @@ class AsyncQueue { } } class ExecContext { - taskRegister = new Map(); - targetRegister = new Map(); - doneTasks = new Set(); - inprogressTasks = new Set(); - internalLogger = mod4.getLogger("internal"); - taskLogger = mod4.getLogger("task"); - userLogger = mod4.getLogger("user"); constructor(manifest, args){ this.manifest = manifest; this.args = args; + this.taskRegister = new Map(); + this.targetRegister = new Map(); + this.doneTasks = new Set(); + this.inprogressTasks = new Set(); + this.internalLogger = mod4.getLogger("internal"); + this.taskLogger = mod4.getLogger("task"); + this.userLogger = mod4.getLogger("user"); if (args["verbose"] !== undefined) { this.internalLogger.levelName = "INFO"; } @@ -6083,8 +6085,8 @@ async function statPath(path1) { } } class Task { - taskManifest = null; constructor(taskParams){ + this.taskManifest = null; this.name = taskParams.name; this.action = taskParams.action; this.description = taskParams.description; @@ -6211,11 +6213,11 @@ class Task { } } class TrackedFile { - path = ""; #getHash; #getTimestamp; - fromTask = null; constructor(fileParams){ + this.path = ""; + this.fromTask = null; this.path = mod3.posix.resolve(fileParams.path); this.#getHash = fileParams.getHash || getFileSha1Sum; this.#getTimestamp = fileParams.getTimestamp || getFileTimestamp; @@ -6305,9 +6307,9 @@ class TrackedFile { } } class TrackedFilesAsync { - kind = 'trackedfilesasync'; constructor(gen){ this.gen = gen; + this.kind = 'trackedfilesasync'; } async getTrackedFiles() { return this.gen(); diff --git a/bundler/tests/fixture/deno-9620/case1/output/entry.inlined.ts b/bundler/tests/fixture/deno-9620/case1/output/entry.inlined.ts index ab6366fa58c1..faf587414ce6 100644 --- a/bundler/tests/fixture/deno-9620/case1/output/entry.inlined.ts +++ b/bundler/tests/fixture/deno-9620/case1/output/entry.inlined.ts @@ -126,8 +126,8 @@ class StringReader extends Deno.Buffer { } } class MultiReader { - currentIndex = 0; constructor(...readers){ + this.currentIndex = 0; this.readers = readers; } async read(p) { @@ -1225,26 +1225,26 @@ const MIN_BUF_SIZE = 16; const CR = "\r".charCodeAt(0); const LF = "\n".charCodeAt(0); class BufferFullError extends Error { - name = "BufferFullError"; constructor(partial){ super("Buffer full"); this.partial = partial; + this.name = "BufferFullError"; } } class PartialReadError extends Deno.errors.UnexpectedEof { - name = "PartialReadError"; constructor(){ super("Encountered UnexpectedEof, data only partially read"); + this.name = "PartialReadError"; } } class BufReader { - r = 0; - w = 0; - eof = false; static create(r, size = 4096) { return r instanceof BufReader ? r : new BufReader(r, size); } constructor(rd1, size1 = 4096){ + this.r = 0; + this.w = 0; + this.eof = false; if (size1 < 16) { size1 = MIN_BUF_SIZE; } @@ -1447,8 +1447,6 @@ class BufReader { } } class AbstractBufBase { - usedBufferBytes = 0; - err = null; size() { return this.buf.byteLength; } @@ -1458,6 +1456,10 @@ class AbstractBufBase { buffered() { return this.usedBufferBytes; } + constructor(){ + this.usedBufferBytes = 0; + this.err = null; + } } class BufWriter extends AbstractBufBase { static create(writer, size = 4096) { @@ -1704,11 +1706,11 @@ function scanUntilBoundary(buf, dashBoundary, newLineDashBoundary, total, eof) { return buf.length; } class PartReader { - n = 0; - total = 0; constructor(mr, headers2){ this.mr = mr; this.headers = headers2; + this.n = 0; + this.total = 0; } async read(p) { const br = this.mr.bufReader; @@ -1785,12 +1787,13 @@ function skipLWSPChar(u) { return ret.slice(0, j); } class MultipartReader { - newLine = encoder.encode("\r\n"); - newLineDashBoundary = encoder.encode(`\r\n--${this.boundary}`); - dashBoundaryDash = encoder.encode(`--${this.boundary}--`); - dashBoundary = encoder.encode(`--${this.boundary}`); constructor(reader1, boundary){ this.boundary = boundary; + this.newLine = encoder.encode("\r\n"); + this.newLineDashBoundary = encoder.encode(`\r\n--${this.boundary}`); + this.dashBoundaryDash = encoder.encode(`--${this.boundary}--`); + this.dashBoundary = encoder.encode(`--${this.boundary}`); + this.partsRead = 0; this.bufReader = new BufReader(reader1); } async readForm(maxMemory = 10 << 20) { @@ -1872,7 +1875,6 @@ class MultipartReader { } return multipartFormData(fileMap, valueMap); } - partsRead = 0; async nextPart() { if (this.currentPart) { this.currentPart.close(); @@ -1965,12 +1967,12 @@ function multipartFormData(fileMap, valueMap) { }; } class PartWriter { - closed = false; - headersWritten = false; constructor(writer3, boundary1, headers1, isFirstBoundary){ this.writer = writer3; this.boundary = boundary1; this.headers = headers1; + this.closed = false; + this.headersWritten = false; let buf = ""; if (isFirstBoundary) { buf += `--${boundary1}\r\n`; @@ -2014,9 +2016,9 @@ class MultipartWriter { get boundary() { return this._boundary; } - isClosed = false; constructor(writer4, boundary2){ this.writer = writer4; + this.isClosed = false; if (boundary2 !== void 0) { this._boundary = checkBoundary(boundary2); } else { diff --git a/bundler/tests/fixture/deno-9620/case1/output/entry.ts b/bundler/tests/fixture/deno-9620/case1/output/entry.ts index 67842adfa855..2409b4a605cc 100644 --- a/bundler/tests/fixture/deno-9620/case1/output/entry.ts +++ b/bundler/tests/fixture/deno-9620/case1/output/entry.ts @@ -126,8 +126,8 @@ class StringReader extends Deno.Buffer { } } class MultiReader { - currentIndex = 0; constructor(...readers){ + this.currentIndex = 0; this.readers = readers; } async read(p) { @@ -1234,26 +1234,26 @@ const MAX_CONSECUTIVE_EMPTY_READS = 100; const CR = "\r".charCodeAt(0); const LF = "\n".charCodeAt(0); class BufferFullError extends Error { - name = "BufferFullError"; constructor(partial){ super("Buffer full"); this.partial = partial; + this.name = "BufferFullError"; } } class PartialReadError extends Deno.errors.UnexpectedEof { - name = "PartialReadError"; constructor(){ super("Encountered UnexpectedEof, data only partially read"); + this.name = "PartialReadError"; } } class BufReader { - r = 0; - w = 0; - eof = false; static create(r, size = DEFAULT_BUF_SIZE) { return r instanceof BufReader ? r : new BufReader(r, size); } constructor(rd1, size1 = DEFAULT_BUF_SIZE){ + this.r = 0; + this.w = 0; + this.eof = false; if (size1 < MIN_BUF_SIZE) { size1 = MIN_BUF_SIZE; } @@ -1456,8 +1456,6 @@ class BufReader { } } class AbstractBufBase { - usedBufferBytes = 0; - err = null; size() { return this.buf.byteLength; } @@ -1467,6 +1465,10 @@ class AbstractBufBase { buffered() { return this.usedBufferBytes; } + constructor(){ + this.usedBufferBytes = 0; + this.err = null; + } } class BufWriter extends AbstractBufBase { static create(writer, size = DEFAULT_BUF_SIZE) { @@ -1713,11 +1715,11 @@ function scanUntilBoundary(buf, dashBoundary, newLineDashBoundary, total, eof) { return buf.length; } class PartReader { - n = 0; - total = 0; constructor(mr, headers2){ this.mr = mr; this.headers = headers2; + this.n = 0; + this.total = 0; } async read(p) { const br = this.mr.bufReader; @@ -1794,12 +1796,13 @@ function skipLWSPChar(u) { return ret.slice(0, j); } class MultipartReader { - newLine = encoder.encode("\r\n"); - newLineDashBoundary = encoder.encode(`\r\n--${this.boundary}`); - dashBoundaryDash = encoder.encode(`--${this.boundary}--`); - dashBoundary = encoder.encode(`--${this.boundary}`); constructor(reader1, boundary){ this.boundary = boundary; + this.newLine = encoder.encode("\r\n"); + this.newLineDashBoundary = encoder.encode(`\r\n--${this.boundary}`); + this.dashBoundaryDash = encoder.encode(`--${this.boundary}--`); + this.dashBoundary = encoder.encode(`--${this.boundary}`); + this.partsRead = 0; this.bufReader = new BufReader(reader1); } async readForm(maxMemory = 10 << 20) { @@ -1881,7 +1884,6 @@ class MultipartReader { } return multipartFormData(fileMap, valueMap); } - partsRead = 0; async nextPart() { if (this.currentPart) { this.currentPart.close(); @@ -1974,12 +1976,12 @@ function multipartFormData(fileMap, valueMap) { }; } class PartWriter { - closed = false; - headersWritten = false; constructor(writer3, boundary1, headers1, isFirstBoundary){ this.writer = writer3; this.boundary = boundary1; this.headers = headers1; + this.closed = false; + this.headersWritten = false; let buf = ""; if (isFirstBoundary) { buf += `--${boundary1}\r\n`; @@ -2023,9 +2025,9 @@ class MultipartWriter { get boundary() { return this._boundary; } - isClosed = false; constructor(writer4, boundary2){ this.writer = writer4; + this.isClosed = false; if (boundary2 !== void 0) { this._boundary = checkBoundary(boundary2); } else { diff --git a/bundler/tests/fixture/issue-1156-1/output/entry.inlined.ts b/bundler/tests/fixture/issue-1156-1/output/entry.inlined.ts index 409e58e27b21..0bff4b5c9fa3 100644 --- a/bundler/tests/fixture/issue-1156-1/output/entry.inlined.ts +++ b/bundler/tests/fixture/issue-1156-1/output/entry.inlined.ts @@ -9,12 +9,14 @@ function d() { return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } b() { this.s = d(); } + constructor(){ + this.s = d(); + } } new A(); diff --git a/bundler/tests/fixture/issue-1156-1/output/entry.ts b/bundler/tests/fixture/issue-1156-1/output/entry.ts index 409e58e27b21..0bff4b5c9fa3 100644 --- a/bundler/tests/fixture/issue-1156-1/output/entry.ts +++ b/bundler/tests/fixture/issue-1156-1/output/entry.ts @@ -9,12 +9,14 @@ function d() { return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } b() { this.s = d(); } + constructor(){ + this.s = d(); + } } new A(); diff --git a/bundler/tests/fixture/issue-1156-2/output/entry.inlined.ts b/bundler/tests/fixture/issue-1156-2/output/entry.inlined.ts index 1c7a8c99197e..2c511528011b 100644 --- a/bundler/tests/fixture/issue-1156-2/output/entry.inlined.ts +++ b/bundler/tests/fixture/issue-1156-2/output/entry.inlined.ts @@ -9,9 +9,11 @@ function d() { return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } + constructor(){ + this.s = d(); + } } new A(); diff --git a/bundler/tests/fixture/issue-1156-2/output/entry.ts b/bundler/tests/fixture/issue-1156-2/output/entry.ts index 1c7a8c99197e..2c511528011b 100644 --- a/bundler/tests/fixture/issue-1156-2/output/entry.ts +++ b/bundler/tests/fixture/issue-1156-2/output/entry.ts @@ -9,9 +9,11 @@ function d() { return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } + constructor(){ + this.s = d(); + } } new A(); diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index 21f32e0a0d15..8b50b28db3ad 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecmascript" repository = "https://github.com/swc-project/swc.git" -version = "0.26.0" +version = "0.27.0" [package.metadata.docs.rs] all-features = true @@ -31,8 +31,8 @@ swc_ecma_ast = {version = "0.40.0", path = "./ast"} swc_ecma_codegen = {version = "0.48.0", path = "./codegen", optional = true} swc_ecma_dep_graph = {version = "0.18.0", path = "./dep-graph", optional = true} swc_ecma_parser = {version = "0.50.0", path = "./parser", optional = true} -swc_ecma_transforms = {version = "0.40.0", path = "./transforms", optional = true} -swc_ecma_utils = {version = "0.30.0", path = "./utils", optional = true} +swc_ecma_transforms = {version = "0.41.0", path = "./transforms", optional = true} +swc_ecma_utils = {version = "0.31.0", path = "./utils", optional = true} swc_ecma_visit = {version = "0.26.0", path = "./visit", optional = true} [dev-dependencies] diff --git a/ecmascript/ext-transforms/Cargo.toml b/ecmascript/ext-transforms/Cargo.toml index 322e76c12671..6cd873c9e256 100644 --- a/ecmascript/ext-transforms/Cargo.toml +++ b/ecmascript/ext-transforms/Cargo.toml @@ -5,7 +5,7 @@ documentation = "https://swc.rs/rustdoc/swc_ecma_ext_transforms/" edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_ext_transforms" -version = "0.7.0" +version = "0.8.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,5 +15,5 @@ swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.10", path = "../../common"} swc_ecma_ast = {version = "0.40.0", path = "../ast"} swc_ecma_parser = {version = "0.50.0", path = "../parser"} -swc_ecma_utils = {version = "0.30.0", path = "../utils"} +swc_ecma_utils = {version = "0.31.0", path = "../utils"} swc_ecma_visit = {version = "0.26.0", path = "../visit"} diff --git a/ecmascript/preset_env/Cargo.toml b/ecmascript/preset_env/Cargo.toml index e92aadf04e5e..405b5be26d87 100644 --- a/ecmascript/preset_env/Cargo.toml +++ b/ecmascript/preset_env/Cargo.toml @@ -5,7 +5,7 @@ documentation = "https://swc.rs/rustdoc/swc_ecma_preset_env/" edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_preset_env" -version = "0.10.0" +version = "0.11.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -21,8 +21,8 @@ string_enum = {version = "0.3.1", path = "../../macros/string_enum"} swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.10", path = "../../common"} swc_ecma_ast = {version = "0.40.0", path = "../ast"} -swc_ecma_transforms = {version = "0.40.0", path = "../transforms", features = ["compat", "proposal"]} -swc_ecma_utils = {version = "0.30.0", path = "../utils"} +swc_ecma_transforms = {version = "0.41.0", path = "../transforms", features = ["compat", "proposal"]} +swc_ecma_utils = {version = "0.31.0", path = "../utils"} swc_ecma_visit = {version = "0.26.0", path = "../visit"} walkdir = "2" diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml index 5a03e8bfe396..cfb64b3536fa 100644 --- a/ecmascript/transforms/Cargo.toml +++ b/ecmascript/transforms/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms" repository = "https://github.com/swc-project/swc.git" -version = "0.40.0" +version = "0.41.0" [package.metadata.docs.rs] all-features = true @@ -25,14 +25,14 @@ swc_atoms = {version = "0.2.0", path = "../../atoms"} swc_common = {version = "0.10.10", path = "../../common"} swc_ecma_ast = {version = "0.40.0", path = "../ast"} swc_ecma_parser = {version = "0.50.0", path = "../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "./base"} -swc_ecma_transforms_compat = {version = "0.8.0", path = "./compat", optional = true} -swc_ecma_transforms_module = {version = "0.8.0", path = "./module", optional = true} -swc_ecma_transforms_optimization = {version = "0.10.0", path = "./optimization", optional = true} -swc_ecma_transforms_proposal = {version = "0.8.0", path = "./proposal", optional = true} -swc_ecma_transforms_react = {version = "0.9.0", path = "./react", optional = true} -swc_ecma_transforms_typescript = {version = "0.9.0", path = "./typescript", optional = true} -swc_ecma_utils = {version = "0.30.0", path = "../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "./base"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "./compat", optional = true} +swc_ecma_transforms_module = {version = "0.9.0", path = "./module", optional = true} +swc_ecma_transforms_optimization = {version = "0.11.0", path = "./optimization", optional = true} +swc_ecma_transforms_proposal = {version = "0.9.0", path = "./proposal", optional = true} +swc_ecma_transforms_react = {version = "0.10.0", path = "./react", optional = true} +swc_ecma_transforms_typescript = {version = "0.10.0", path = "./typescript", optional = true} +swc_ecma_utils = {version = "0.31.0", path = "../utils"} swc_ecma_visit = {version = "0.26.0", path = "../visit"} unicode-xid = "0.2" @@ -40,7 +40,7 @@ unicode-xid = "0.2" pretty_assertions = "0.6" sourcemap = "6" swc_ecma_codegen = {version = "0.48.0", path = "../codegen"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "./testing"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "./testing"} tempfile = "3" testing = {version = "0.10.3", path = "../../testing"} walkdir = "2" diff --git a/ecmascript/transforms/base/Cargo.toml b/ecmascript/transforms/base/Cargo.toml index d719734009b8..85c3d01979ed 100644 --- a/ecmascript/transforms/base/Cargo.toml +++ b/ecmascript/transforms/base/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_base" repository = "https://github.com/swc-project/swc.git" -version = "0.7.0" +version = "0.8.0" [dependencies] fxhash = "0.2.1" @@ -18,7 +18,7 @@ swc_atoms = {version = "0.2", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] diff --git a/ecmascript/transforms/compat/Cargo.toml b/ecmascript/transforms/compat/Cargo.toml index 03190103e8ee..e56d067d4fd8 100644 --- a/ecmascript/transforms/compat/Cargo.toml +++ b/ecmascript/transforms/compat/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_compat" repository = "https://github.com/swc-project/swc.git" -version = "0.8.0" +version = "0.9.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -21,12 +21,12 @@ smallvec = "1.6.0" swc_atoms = {version = "0.2.5", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} swc_ecma_transforms_macros = {version = "0.2.1", path = "../macros"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing"} testing = {version = "0.10.3", path = "../../../testing"} diff --git a/ecmascript/transforms/compat/src/es2020/class_properties.rs b/ecmascript/transforms/compat/src/es2020/class_properties.rs index 0a401596cce3..73569bd640db 100644 --- a/ecmascript/transforms/compat/src/es2020/class_properties.rs +++ b/ecmascript/transforms/compat/src/es2020/class_properties.rs @@ -758,9 +758,10 @@ impl ClassProperties { } }); - if let Some(c) = constructor { + if let Some(mut c) = constructor { // Prepend properties - Some(inject_after_super(c, constructor_exprs)) + inject_after_super(&mut c, constructor_exprs); + Some(c) } else { None } diff --git a/ecmascript/transforms/module/Cargo.toml b/ecmascript/transforms/module/Cargo.toml index b7948ea35060..dbc852d890b3 100644 --- a/ecmascript/transforms/module/Cargo.toml +++ b/ecmascript/transforms/module/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_module" repository = "https://github.com/swc-project/swc.git" -version = "0.8.0" +version = "0.9.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -18,11 +18,11 @@ swc_atoms = {version = "0.2", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] -swc_ecma_transforms_compat = {version = "0.8.0", path = "../compat"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing/"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "../compat"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing/"} testing = {version = "0.10.3", path = "../../../testing/"} diff --git a/ecmascript/transforms/optimization/Cargo.toml b/ecmascript/transforms/optimization/Cargo.toml index 8221b7fe7b7d..aaf249fd48f3 100644 --- a/ecmascript/transforms/optimization/Cargo.toml +++ b/ecmascript/transforms/optimization/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_optimization" repository = "https://github.com/swc-project/swc.git" -version = "0.10.0" +version = "0.11.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -21,15 +21,15 @@ swc_atoms = {version = "0.2", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] -swc_ecma_transforms_compat = {version = "0.8.0", path = "../compat"} -swc_ecma_transforms_module = {version = "0.8.0", path = "../module"} -swc_ecma_transforms_proposal = {version = "0.8.0", path = "../proposal"} -swc_ecma_transforms_react = {version = "0.9.0", path = "../react"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing"} -swc_ecma_transforms_typescript = {version = "0.9.0", path = "../typescript"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "../compat"} +swc_ecma_transforms_module = {version = "0.9.0", path = "../module"} +swc_ecma_transforms_proposal = {version = "0.9.0", path = "../proposal"} +swc_ecma_transforms_react = {version = "0.10.0", path = "../react"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing"} +swc_ecma_transforms_typescript = {version = "0.10.0", path = "../typescript"} testing = {version = "0.10.0", path = "../../../testing"} diff --git a/ecmascript/transforms/optimization/tests/simplify.rs b/ecmascript/transforms/optimization/tests/simplify.rs index 8e21d933f466..4b37a091ffa8 100644 --- a/ecmascript/transforms/optimization/tests/simplify.rs +++ b/ecmascript/transforms/optimization/tests/simplify.rs @@ -511,13 +511,15 @@ test!( return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } b() { this.s = d(); } + constructor(){ + this.s = d(); + } } new A(); " diff --git a/ecmascript/transforms/optimization/tests/simplify_dce.rs b/ecmascript/transforms/optimization/tests/simplify_dce.rs index 243c6748f1cf..21f76ee95cce 100644 --- a/ecmascript/transforms/optimization/tests/simplify_dce.rs +++ b/ecmascript/transforms/optimization/tests/simplify_dce.rs @@ -677,13 +677,15 @@ test!( return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } b() { this.s = d(); } + constructor(){ + this.s = d(); + } } new A(); " @@ -765,10 +767,12 @@ test!( return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } + constructor(){ + this.s = d(); + } } new A(); " diff --git a/ecmascript/transforms/optimization/tests/simplify_inlining.rs b/ecmascript/transforms/optimization/tests/simplify_inlining.rs index f85954fb7e99..f31688f96598 100644 --- a/ecmascript/transforms/optimization/tests/simplify_inlining.rs +++ b/ecmascript/transforms/optimization/tests/simplify_inlining.rs @@ -2215,13 +2215,15 @@ test!( return Object.assign(promise, methods); } class A { - s = d(); a() { this.s.resolve(); } b() { this.s = d(); } + constructor(){ + this.s = d(); + } } new A(); " diff --git a/ecmascript/transforms/proposal/Cargo.toml b/ecmascript/transforms/proposal/Cargo.toml index b1cfbdf78b11..070d065a6051 100644 --- a/ecmascript/transforms/proposal/Cargo.toml +++ b/ecmascript/transforms/proposal/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_proposal" repository = "https://github.com/swc-project/swc.git" -version = "0.8.0" +version = "0.9.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -24,11 +24,11 @@ swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_loader = {version = "0.1.0", path = "../../loader", optional = true} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] -swc_ecma_transforms_compat = {version = "0.8.0", path = "../compat"} -swc_ecma_transforms_module = {version = "0.8.0", path = "../module"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "../compat"} +swc_ecma_transforms_module = {version = "0.9.0", path = "../module"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing"} diff --git a/ecmascript/transforms/proposal/src/decorators.rs b/ecmascript/transforms/proposal/src/decorators.rs index 5e985a30af67..cb2cb3662684 100644 --- a/ecmascript/transforms/proposal/src/decorators.rs +++ b/ecmascript/transforms/proposal/src/decorators.rs @@ -279,7 +279,7 @@ impl Decorators { ClassMember::Constructor(c) => c, _ => unreachable!(), }; - c = inject_after_super(c, vec![initialize_call]); + inject_after_super(&mut c, vec![initialize_call]); ClassMember::Constructor(c) } diff --git a/ecmascript/transforms/react/Cargo.toml b/ecmascript/transforms/react/Cargo.toml index c75eeafcf697..97b430dceb68 100644 --- a/ecmascript/transforms/react/Cargo.toml +++ b/ecmascript/transforms/react/Cargo.toml @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0/MIT" name = "swc_ecma_transforms_react" repository = "https://github.com/swc-project/swc.git" -version = "0.9.0" +version = "0.10.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -20,12 +20,12 @@ swc_atoms = {version = "0.2", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] -swc_ecma_transforms_compat = {version = "0.8.0", path = "../compat/"} -swc_ecma_transforms_module = {version = "0.8.0", path = "../module"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing/"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "../compat/"} +swc_ecma_transforms_module = {version = "0.9.0", path = "../module"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing/"} testing = {version = "0.10.3", path = "../../../testing"} diff --git a/ecmascript/transforms/testing/Cargo.toml b/ecmascript/transforms/testing/Cargo.toml index 694382dde7e5..a56f41dd20e9 100644 --- a/ecmascript/transforms/testing/Cargo.toml +++ b/ecmascript/transforms/testing/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_testing" repository = "https://github.com/swc-project/swc.git" -version = "0.7.0" +version = "0.8.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -18,8 +18,8 @@ swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_codegen = {version = "0.48.0", path = "../../codegen"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} tempfile = "3.1.0" testing = {version = "0.10.3", path = "../../../testing"} diff --git a/ecmascript/transforms/tests/decorators.rs b/ecmascript/transforms/tests/decorators.rs index 8646be9729d3..d3a7652727de 100644 --- a/ecmascript/transforms/tests/decorators.rs +++ b/ecmascript/transforms/tests/decorators.rs @@ -470,7 +470,7 @@ class B { class B { bar() {} constructor() { - _defineProperty(this, "foo", 2); + this.foo = 2; } } diff --git a/ecmascript/transforms/typescript/Cargo.toml b/ecmascript/transforms/typescript/Cargo.toml index da6bdbf136dd..e143f7304313 100644 --- a/ecmascript/transforms/typescript/Cargo.toml +++ b/ecmascript/transforms/typescript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_transforms_typescript" repository = "https://github.com/swc-project/swc.git" -version = "0.9.0" +version = "0.10.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] @@ -16,15 +16,15 @@ swc_atoms = {version = "0.2", path = "../../../atoms"} swc_common = {version = "0.10.10", path = "../../../common"} swc_ecma_ast = {version = "0.40.0", path = "../../ast"} swc_ecma_parser = {version = "0.50.0", path = "../../parser"} -swc_ecma_transforms_base = {version = "0.7.0", path = "../base"} -swc_ecma_utils = {version = "0.30.0", path = "../../utils"} +swc_ecma_transforms_base = {version = "0.8.0", path = "../base"} +swc_ecma_utils = {version = "0.31.0", path = "../../utils"} swc_ecma_visit = {version = "0.26.0", path = "../../visit"} [dev-dependencies] swc_ecma_codegen = {version = "0.48.0", path = "../../codegen"} -swc_ecma_transforms_compat = {version = "0.8.0", path = "../compat"} -swc_ecma_transforms_module = {version = "0.8.0", path = "../module"} -swc_ecma_transforms_proposal = {version = "0.8.0", path = "../proposal/"} -swc_ecma_transforms_testing = {version = "0.7.0", path = "../testing"} +swc_ecma_transforms_compat = {version = "0.9.0", path = "../compat"} +swc_ecma_transforms_module = {version = "0.9.0", path = "../module"} +swc_ecma_transforms_proposal = {version = "0.9.0", path = "../proposal/"} +swc_ecma_transforms_testing = {version = "0.8.0", path = "../testing"} testing = {version = "0.10.3", path = "../../../testing"} walkdir = "2.3.1" diff --git a/ecmascript/transforms/typescript/src/strip.rs b/ecmascript/transforms/typescript/src/strip.rs index 027fe77fc446..7e6ebe10b093 100644 --- a/ecmascript/transforms/typescript/src/strip.rs +++ b/ecmascript/transforms/typescript/src/strip.rs @@ -1,17 +1,14 @@ use fxhash::FxHashMap; use serde::{Deserialize, Serialize}; -use std::mem::take; +use std::{borrow::Borrow, mem::take}; use swc_atoms::{js_word, JsWord}; use swc_common::{util::move_map::MoveMap, Span, Spanned, SyntaxContext, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_transforms_base::ext::MapWithMut; -use swc_ecma_utils::default_constructor; -use swc_ecma_utils::member_expr; -use swc_ecma_utils::prepend_stmts; use swc_ecma_utils::private_ident; -use swc_ecma_utils::quote_ident; use swc_ecma_utils::var::VarCollector; use swc_ecma_utils::ExprFactory; +use swc_ecma_utils::{constructor::inject_after_super, default_constructor}; use swc_ecma_utils::{ident::IdentLike, Id, StmtLike}; use swc_ecma_visit::{as_folder, Fold, Node, Visit, VisitMut, VisitMutWith, VisitWith}; @@ -41,10 +38,21 @@ impl Default for ImportsNotUsedAsValues { pub struct Config { #[serde(default)] pub import_not_used_as_values: ImportsNotUsedAsValues, - /// Use `defineProperty` for class properties. + /// Align the semantics of TS class fields with TC39 class fields. Defaults + /// to `false`. /// + /// See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#the-usedefineforclassfields-flag-and-the-declare-property-modifier. /// - /// See https://github.com/swc-project/swc/issues/1472 + /// When running `tsc` with configuration `"target": "ESNext", + /// "useDefineForClassFields": true`, TS class fields are preserved as JS + /// class fields. We target ESNext, so this our behavior with + /// `use_define_for_class_fields: true`. + /// + /// When running `tsc` with configuration `"target": "", + /// "useDefineForClassFields": true`, TS class fields are transformed to + /// `Object.defineProperty()` statements. You must additionally apply the + /// `swc_ecmascript::transforms::compat::es2020::class_properties()` pass to + /// get this backward-compatible output. #[serde(default)] pub use_define_for_class_fields: bool, } @@ -145,141 +153,108 @@ impl Strip { } impl Strip { - /// Convert class properties to `defineProperty` calls from constructor. - /// - /// This should be called after handling constructor parameter properties. - /// This is because this method simply appends `definedProperty` calls to - /// constructor. - fn convert_properties_to_define_property(&mut self, class: &mut Class) { - if !self.config.use_define_for_class_fields { + fn transform_class_fields(&mut self, class: &mut Class) { + if self.config.use_define_for_class_fields { + let mut param_class_fields = vec![]; + for member in &class.body { + match member { + ClassMember::Constructor(constructor) => { + for param in &constructor.params { + match param { + ParamOrTsParamProp::TsParamProp(param_prop) => { + let ident = match ¶m_prop.param { + TsParamPropParam::Ident(ident) => ident.id.clone(), + TsParamPropParam::Assign(pat) => { + pat.clone().left.ident().unwrap().id + } + }; + let param_class_field = ClassMember::ClassProp(ClassProp { + span: class.span, + key: Box::new(Expr::Ident(ident)), + value: None, + type_ann: None, + is_static: false, + decorators: param_prop.decorators.clone(), + computed: false, + accessibility: param_prop.accessibility.clone(), + is_abstract: false, + is_optional: false, + readonly: param_prop.readonly, + declare: false, + definite: false, + }); + param_class_fields.push(param_class_field); + } + _ => {} + } + } + break; + } + _ => {} + } + } + if !param_class_fields.is_empty() { + param_class_fields.append(&mut class.body.take()); + class.body = param_class_fields; + } return; } - - let mut define_property_stmts = vec![]; - let mut preserved_members = vec![]; + let mut assign_exprs = vec![]; + let mut new_body = vec![]; for member in take(&mut class.body) { match member { - ClassMember::ClassProp(ClassProp { - span, - key, - computed, - value: Some(value), - is_static: false, - .. - }) => { - let mut define_property_args = vec![]; - - define_property_args.push(ThisExpr { span: class.span }.as_arg()); - define_property_args.push(match *key { - Expr::Ident(key) if !computed => Lit::Str(Str { - span: key.span, - value: key.sym, - has_escape: false, - kind: StrKind::Normal { - contains_quote: false, - }, - }) - .as_arg(), - _ => key.as_arg(), - }); - define_property_args.push( - ObjectLit { - span: DUMMY_SP, - props: { - let mut props = vec![]; - - // enumerable: true, - props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue( - KeyValueProp { - key: PropName::Ident(quote_ident!("enumerable")), - value: Box::new(Expr::Lit(Lit::Bool(Bool { - span: DUMMY_SP, - value: true, - }))), - }, - )))); - // configurable: true, - props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue( - KeyValueProp { - key: PropName::Ident(quote_ident!("configurable")), - value: Box::new(Expr::Lit(Lit::Bool(Bool { - span: DUMMY_SP, - value: true, - }))), - }, - )))); - // writable: true, - props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue( - KeyValueProp { - key: PropName::Ident(quote_ident!("writable")), - value: Box::new(Expr::Lit(Lit::Bool(Bool { - span: DUMMY_SP, - value: true, - }))), - }, - )))); - - // value: initializer - props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue( - KeyValueProp { - key: PropName::Ident(quote_ident!("value")), - value, - }, - )))); - - props - }, - } - .as_arg(), - ); - - let define_property_call = Box::new(Expr::Call(CallExpr { - span, - callee: member_expr!(span, Object.definedProperty).as_callee(), - args: define_property_args, - type_args: Default::default(), - })); - let stmt = Stmt::Expr(ExprStmt { - span, - expr: define_property_call, - }); - - define_property_stmts.push(stmt); + // This handling is for non-static fields only. Also preserve + // fields with decorators for now, these should be transformed + // differently during the `decorators()` pass. + ClassMember::ClassProp(mut class_field) + if !class_field.is_static && class_field.decorators.is_empty() => + { + if let Some(value) = class_field.value.take() { + let computed = class_field.computed + || !matches!(class_field.key.borrow(), Expr::Ident(_)); + let assign_lhs = PatOrExpr::Expr(Box::new(Expr::Member(MemberExpr { + span: class_field.span, + obj: ExprOrSuper::Expr(Box::new(Expr::This(ThisExpr { + span: class.span, + }))), + prop: class_field.key, + computed, + }))); + let assign_expr = Box::new(Expr::Assign(AssignExpr { + span: class_field.span, + op: op!("="), + left: assign_lhs, + right: value, + })); + assign_exprs.push(assign_expr); + } } + // TODO(nayeemrmn): Static fields should also be moved to + // assignments after the class. Figure out how. They are + // preserved for now. + // ClassMember::ClassProp(_) => { ... } _ => { - preserved_members.push(member); + new_body.push(member); } } } - - if !define_property_stmts.is_empty() { - // We should append `definedProperty` calls to a constructor. - - // If user have defined a constructor, append to it. - for member in &mut preserved_members { + if !assign_exprs.is_empty() { + for member in &mut new_body { match member { - ClassMember::Constructor(Constructor { - body: Some(body), .. - }) => { - body.stmts.extend(take(&mut define_property_stmts)); + ClassMember::Constructor(constructor) => { + inject_after_super(constructor, take(&mut assign_exprs)); + break; } _ => {} } } - - // If there's no constructor, we create one. - if !define_property_stmts.is_empty() { - let mut c = default_constructor(class.super_class.is_some()); - c.body - .as_mut() - .unwrap() - .stmts - .extend(take(&mut define_property_stmts)); - preserved_members.push(ClassMember::Constructor(c)); + if !assign_exprs.is_empty() { + let mut constructor = default_constructor(class.super_class.is_some()); + inject_after_super(&mut constructor, assign_exprs); + new_body.push(ClassMember::Constructor(constructor)); } } - - class.body = preserved_members; + class.body = new_body; } /// Returns [Some] if the method should be called again. @@ -978,16 +953,16 @@ impl VisitMut for Strip { n.implements = Default::default(); + self.transform_class_fields(n); n.decorators.visit_mut_with(self); n.body.visit_mut_with(self); - self.convert_properties_to_define_property(n); n.super_class.visit_mut_with(self); } fn visit_mut_constructor(&mut self, n: &mut Constructor) { n.visit_mut_children_with(self); - let mut stmts = vec![]; + let mut assign_exprs = vec![]; n.params.map_with_mut(|params| { params.move_map(|param| match param { @@ -1023,30 +998,22 @@ impl VisitMut for Strip { } _ => unreachable!("destructuring pattern inside TsParameterProperty"), }; - stmts.push( - AssignExpr { - span: DUMMY_SP, - left: PatOrExpr::Expr(Box::new( - ThisExpr { span: DUMMY_SP }.make_member(ident.id.clone()), - )), - op: op!("="), - right: Box::new(Expr::Ident(ident.id)), - } - .into_stmt(), - ); + let assign_expr = Box::new(Expr::Assign(AssignExpr { + span: DUMMY_SP, + left: PatOrExpr::Expr(Box::new( + ThisExpr { span: DUMMY_SP }.make_member(ident.id.clone()), + )), + op: op!("="), + right: Box::new(Expr::Ident(ident.id)), + })); + assign_exprs.push(assign_expr); ParamOrTsParamProp::Param(param) } }) }); - n.body = match n.body.take() { - Some(mut body) => { - prepend_stmts(&mut body.stmts, stmts.into_iter()); - Some(body) - } - None => None, - }; + inject_after_super(n, assign_exprs); } fn visit_mut_expr(&mut self, n: &mut Expr) { @@ -1249,7 +1216,7 @@ impl VisitMut for Strip { value: None, ref decorators, .. - }) if decorators.is_empty() => false, + }) if decorators.is_empty() && !self.config.use_define_for_class_fields => false, _ => true, }); diff --git a/ecmascript/transforms/typescript/tests/strip.rs b/ecmascript/transforms/typescript/tests/strip.rs index 1a6ae054fba7..a1290ac86579 100644 --- a/ecmascript/transforms/typescript/tests/strip.rs +++ b/ecmascript/transforms/typescript/tests/strip.rs @@ -684,7 +684,9 @@ to!( readonly newLine = encoder.encode("\r\n"); }"#, r#"export class MultipartReader { - newLine = encoder.encode("\r\n"); + constructor(){ + this.newLine = encoder.encode("\r\n"); + } }"# ); @@ -729,7 +731,7 @@ to!( test!( ::swc_ecma_parser::Syntax::Typescript(Default::default()), - |_| chain!(typescript_class_properties(), tr()), + |_| tr(), issue_930_instance, "class A { b = this.a; @@ -746,6 +748,8 @@ test!( test!( ::swc_ecma_parser::Syntax::Typescript(Default::default()), + // TODO(nayeemrmn): This output should be achieved without + // `typescript_class_properties()`. |_| chain!(typescript_class_properties(), tr()), issue_930_static, "class A { @@ -762,7 +766,7 @@ test!( test!( ::swc_ecma_parser::Syntax::Typescript(Default::default()), - |_| chain!(typescript_class_properties(), tr()), + |_| tr(), typescript_001, "class A { foo = new Subject() @@ -781,7 +785,7 @@ test!( test!( ::swc_ecma_parser::Syntax::Typescript(Default::default()), - |_| chain!(typescript_class_properties(), tr()), + |_| tr(), typescript_002, "class A extends B { foo = 'foo' @@ -810,7 +814,7 @@ test!( test!( ::swc_ecma_parser::Syntax::Typescript(Default::default()), - |_| chain!(typescript_class_properties(), tr()), + |_| tr(), issue_958, "export class Test { constructor(readonly test?: string) {} @@ -3151,9 +3155,9 @@ test!( return a.toUpperCase() === a; })(); } - + } - + _asyncToGenerator(function* () { yield new Service().is('ABC'); })(); @@ -3185,27 +3189,27 @@ test!( interface SuperSubmission { [key: string]: any; } - + const normalizedQuestionSet: any = {}; - + const submissions: SuperSubmission[] = ( normalizedQuestionSet.submissionIds ?? [] ).map( (id, index): SuperSubmission => { const submission = normalizedQuestionSet.submissions?.[id]; - + const submissionAnswers = (submission.answers ?? []).map( (answerId) => normalizedQuestionSet.answers?.[answerId] ); - + console.log(id, index); - + return { type: "super-submission", }; } ); - + console.log(submissions); "#, r#" @@ -3231,7 +3235,14 @@ test!( Syntax::Typescript(TsConfig { ..Default::default() }), - |_| chain!(strip(), class_properties()), + |_| chain!( + strip_with_config({ + let mut config = strip::Config::default(); + config.use_define_for_class_fields = true; + config + }), + class_properties() + ), compile_to_class_constructor_collision_ignores_types, r#" class C { @@ -3246,6 +3257,7 @@ class C { class C { // Output should not use `_initialiseProps` constructor(T) { + _defineProperty(this, "x", void 0); _defineProperty(this, "y", 0); } @@ -3354,11 +3366,11 @@ to!( }; export const getValues = (obj: any) => { - + }; export const objectValues = (obj: any) => { - + }; } ", @@ -3435,7 +3447,7 @@ to!( B = 'B', } } - + console(Test.DummyValues.A); ", " @@ -3463,7 +3475,7 @@ to!( return args.param1; } } - + declare namespace TestClass { export interface TestArgs { param1: boolean; @@ -3498,7 +3510,7 @@ to!( declare global { const process: Process; } - + export {} ", " @@ -3521,15 +3533,11 @@ test_with_config!( ", " class A extends Object { + b; + a = 1; constructor(b = 2){ super(); this.b = b; - Object.definedProperty(this, 'a', { - enumerable: true, - configurable: true, - writable: true, - value: 1 - }); } } " @@ -3551,10 +3559,10 @@ test_with_config!( ", " class A extends Object { - a = 1; constructor(b = 2){ super(); this.b = b; + this.a = 1; } } " diff --git a/ecmascript/utils/Cargo.toml b/ecmascript/utils/Cargo.toml index 9ecccf66fb52..539e23614aa3 100644 --- a/ecmascript/utils/Cargo.toml +++ b/ecmascript/utils/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecma_utils" repository = "https://github.com/swc-project/swc.git" -version = "0.30.0" +version = "0.31.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/ecmascript/utils/src/constructor.rs b/ecmascript/utils/src/constructor.rs index 6f260e76ce03..d0a2a377c3e4 100644 --- a/ecmascript/utils/src/constructor.rs +++ b/ecmascript/utils/src/constructor.rs @@ -4,22 +4,27 @@ use swc_common::DUMMY_SP; use swc_ecma_ast::*; use swc_ecma_visit::{noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitMutWith}; -pub fn inject_after_super(mut c: Constructor, exprs: Vec>) -> Constructor { +pub fn inject_after_super(c: &mut Constructor, exprs: Vec>) { // Allow using super multiple time let mut folder = Injector { exprs: &exprs, injected: false, }; - c.body = c.body.fold_with(&mut folder); + c.body = std::mem::take(&mut c.body).fold_with(&mut folder); if !folder.injected { + if c.body.is_none() { + c.body = Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![], + }); + } // there was no super() call prepend_stmts( &mut c.body.as_mut().unwrap().stmts, exprs.into_iter().map(|v| v.into_stmt()), ); } - c } struct Injector<'a> {