Search Terms
Decorators and swc
Expected Behavior
I've got an upstream project that sets symbol properties inside a class decorator.
The generated code looks like this:
Details
function CreateDestroy() {
return (constructor) => {
var _a, _b, _c;
const constructor_ = class extends constructor {
constructor() {
super(...arguments);
this[_a] = false;
this[_b] = null;
this[_c] = new async_locks_1.RWLockWriter();
}
get [(_a = utils_1._destroyed, _b = utils_1._status, _c = utils_1.initLock, utils_1.destroyed)]() {
return this[utils_1._destroyed];
}
get [utils_1.status]() {
return this[utils_1._status];
}
async destroy(...args) {
return this[utils_1.initLock].withWriteF(async () => {
this[utils_1._status] = 'destroying';
try {
if (this[utils_1._destroyed]) {
return;
}
let result;
if (typeof super['destroy'] === 'function') {
result = await super.destroy(...args);
}
this[utils_1._destroyed] = true;
return result;
}
finally {
this[utils_1._status] = null;
}
});
}
};
// Preserve the name
Object.defineProperty(constructor_, 'name', Object.getOwnPropertyDescriptor(constructor, 'name'));
return constructor_;
};
}
Then I have code being executed under ts-node, which uses this decorator. The project has experimentalDecorators: "true" switched on.
With swc, it turns out that the decorator constructor itself is never executed.
If I put a console.log('hello world'); underneath
this[_c] = new async_locks_1.RWLockWriter();
The message never shows.
But if I switch off swc, it does work, and I see the message being printed on the console.
This seems to mean that ts-node with swc isn't understanding decorated code, or perhaps swc itself doesn't know how to transpile with decorator code upstream.
Actual Behavior
Because the decorator constructor doesn't work, the actual behaviour is that I get undefined properties when attempting to access properties that the decorated constructor is supposed to set.
Steps to reproduce the problem
Go to this PR: MatrixAI/js-workers#4. Check out this commit: MatrixAI/js-workers@7c591cd.
Then try npm run bench.
You should see:
[nix-shell:~/Projects/js-workers]$ npm run bench
> @matrixai/workers@1.3.4 bench
> rimraf ./benches/results && ts-node ./benches
WARN:WorkerManager Bench:Cores: 16
TypeError: Cannot read properties of undefined (reading 'isLocked')
at WorkerManager.queue (/home/cmcdragonkai/Projects/js-workers/node_modules/@matrixai/async-init/src/CreateDestroy.ts:159:38)
at /home/cmcdragonkai/Projects/js-workers/benches/worker_manager.ts:54:23
at /home/cmcdragonkai/Projects/js-workers/node_modules/benny/lib/add.js:16:47
at Generator.next (<anonymous>)
at /home/cmcdragonkai/Projects/js-workers/node_modules/benny/lib/add.js:8:71
at new Promise (<anonymous>)
at __awaiter (/home/cmcdragonkai/Projects/js-workers/node_modules/benny/lib/add.js:4:12)
at prepareCaseFn (/home/cmcdragonkai/Projects/js-workers/node_modules/benny/lib/add.js:15:33)
at /home/cmcdragonkai/Projects/js-workers/node_modules/benny/lib/add.js:59:38
at Generator.next (<anonymous>)
And the property is undefined because the constructor doesn't get executed.
Specifications
- ts-node version: v10.9.1
- node version: v16.15.0
- TypeScript version: v4.7.4
- tsconfig.json, if you're using one:
{
"compilerOptions": {
"outDir": "./dist",
"tsBuildInfoFile": "./dist/tsbuildinfo",
"incremental": true,
"sourceMap": true,
"declaration": true,
"allowJs": true,
"strictNullChecks": true,
"noImplicitAny": false,
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"module": "CommonJS",
"target": "ES2021",
"baseUrl": "./src",
"paths": {
"@": ["index"],
"@/*": ["*"]
},
"noEmit": true
},
"include": [
"./src/**/*",
"./src/**/*.json",
"./tests/**/*",
"./scripts/**/*",
"./benches/**/*"
],
"ts-node": {
"require": ["tsconfig-paths/register"],
"transpileOnly": true,
"swc": true
}
}
{
"name": "@matrixai/workers",
"version": "1.3.4",
"author": "Roger Qiu",
"description": "Multithreaded Workers",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/MatrixAI/js-workers.git"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepare": "tsc -p ./tsconfig.build.json",
"build": "rimraf ./dist && tsc -p ./tsconfig.build.json",
"postversion": "npm install --package-lock-only --ignore-scripts --silent",
"ts-node": "ts-node",
"test": "jest",
"lint": "eslint '{src,tests,scripts,benches}/**/*.{js,ts}'",
"lintfix": "eslint '{src,tests,scripts,benches}/**/*.{js,ts}' --fix",
"lint-shell": "find ./src ./tests ./scripts -type f -regextype posix-extended -regex '.*\\.(sh)' -exec shellcheck {} +",
"docs": "rimraf ./docs && typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src",
"bench": "rimraf ./benches/results && ts-node ./benches"
},
"dependencies": {
"@matrixai/async-init": "^1.8.1",
"@matrixai/logger": "^3.0.0",
"@matrixai/errors": "^1.1.2",
"threads": "^1.6.5"
},
"devDependencies": {
"@swc/core": "^1.2.215",
"@types/jest": "^28.1.3",
"@types/node": "^16.11.7",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"benny": "^3.7.1",
"common-tags": "^1.8.2",
"eslint": "^8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^28.1.1",
"jest-junit": "^14.0.0",
"prettier": "^2.6.2",
"rimraf": "^3.0.2",
"systeminformation": "^5.12.1",
"ts-jest": "^28.0.5",
"ts-node": "^10.9.1",
"tsconfig-paths": "^3.9.0",
"typedoc": "^0.22.15",
"typescript": "^4.5.2"
}
}
- Operating system and version:
Linux matrix-ml-1 5.10.118 #1-NixOS SMP Wed May 25 07:18:02 UTC 2022 x86_64 GNU/Linux
Search Terms
Decorators and swc
Expected Behavior
I've got an upstream project that sets symbol properties inside a class decorator.
The generated code looks like this:
Details
Then I have code being executed under ts-node, which uses this decorator. The project has
experimentalDecorators: "true"switched on.With
swc, it turns out that the decorator constructor itself is never executed.If I put a
console.log('hello world');underneathThe message never shows.
But if I switch off
swc, it does work, and I see the message being printed on the console.This seems to mean that ts-node with swc isn't understanding decorated code, or perhaps swc itself doesn't know how to transpile with decorator code upstream.
Actual Behavior
Because the decorator constructor doesn't work, the actual behaviour is that I get undefined properties when attempting to access properties that the decorated constructor is supposed to set.
Steps to reproduce the problem
Go to this PR: MatrixAI/js-workers#4. Check out this commit: MatrixAI/js-workers@7c591cd.
Then try
npm run bench.You should see:
And the property is undefined because the constructor doesn't get executed.
Specifications
Linux matrix-ml-1 5.10.118 #1-NixOS SMP Wed May 25 07:18:02 UTC 2022 x86_64 GNU/Linux