SyntaxError: 'super' keyword unexpected here
- Dominant language
- Go
- Stars
- 40.1k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
Hi @evanw ,
I was trying to upgrade a codebase which is using `esbuild` to produce compiled output.
After upgrading the `c12` package which also upgraded `exsolve`, esbuild produces wrong code for the `node10` target.
Here is an excerpt of `exsolve` to reproduce the issue on [esbuild try](https://esbuild.github.io/try/#YgAwLjI4LjEALS1idW5kbGUgLS1taW5pZnk9ZmFsc2UgLS1wbGF0Zm9ybT1ub2RlIGluZGV4Lm1qcyAtLW91dGZpbGU9ZGlzdC9pbmRleC5qcyAtLXRhcmdldD1ub2RlMTAAZQBpbmRleC5tanMAZnVuY3Rpb24gbWFrZU5vZGVFcnJvcldpdGhDb2RlKEJhc2UsIGtleSkgewoJCQljbGFzcyBOb2RlRXJyb3IgZXh0ZW5kcyBCYXNlIHsKCQkJCWNvZGUgPSBrZXk7CgkJCQljb25zdHJ1Y3RvciguLi5hcmdzKSB7CgkJCQkJYXNzZXJ0Lm9rKGFyZ3MubGVuZ3RoID09PSAwLCBgQ29kZTogJHtrZXl9OyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzIGxlbmd0aCAoJHthcmdzLmxlbmd0aH0pIGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlZCBvbmVzICgke2V4cGVjdGVkTGVuZ3RofSkuYCk7CgkJCQkJc3VwZXIobWVzc2FnZSk7CgkJCQl9CgkJCQlnZXQgWyJjb25zdHJ1Y3RvciJdKCkgewoJCQkJCXJldHVybiBCYXNlOwoJCQkJfQoJCQkJZ2V0IFtrSXNOb2RlRXJyb3JdKCkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQkJdG9TdHJpbmcoKSB7CgkJCQkJcmV0dXJuIGAke3RoaXMubmFtZX0gWyR7a2V5fV06ICR7dGhpcy5tZXNzYWdlfWA7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIE5vZGVFcnJvcjsKfQptYWtlTm9kZUVycm9yV2l0aENvZGUoRXJyb3IsIDApOw)
index.mjs
```javascript
function makeNodeErrorWithCode(Base, key) {
class NodeError extends Base {
code = key;
constructor(...args) {
assert.ok(args.length === 0, `Code: ${key}; The provided arguments length (${args.length}) does not match the required ones (${expectedLength}).`);
super(message);
}
get ["constructor"]() {
return Base;
}
get [kIsNodeError]() {
return true;
}
toString() {
return `${this.name} [${key}]: ${this.message}`;
}
}
return NodeError;
}
makeNodeErrorWithCode(Error, 0);
```
When you run `esbuild` with
```shell
npx esbuild --bundle --minify=false --platform=node index.mjs --outfile=dist/index.js --target=node10
```
it is transpiled to the following
dist/index.js
```javascript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// index.mjs
function makeNodeErrorWithCode(Base, key) {
class NodeError extends Base {
get ["constructor"]() {
var __super = (...args) => {
super(...args);
__publicField(this, "code", key);
return this;
};
return Base;
}
constructor(...args2) {
assert.ok(args2.length === 0, `Code: ${key}; The provided arguments length (${args2.length}) does not match the required ones (${expectedLength}).`);
__super(message);
}
get [kIsNodeError]() {
return true;
}
toString() {
return `${this.name} [${key}]: ${this.message}`;
}
}
return NodeError;
}
makeNodeErrorWithCode(Error, 0);
```
Now when you try to run this with `node ./dist/index.js`, you get the following error:
```shell
super(...args);
^^^^^
SyntaxError: 'super' keyword unexpected here
```
It looks like this block
```javascript
var __super = (...args) => {
super(...args);
__publicField(this, "code", key);
return this;
};
```
is placed in the wrong location.
It should be placed into the `constructor` instead.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the issue with the linked esbuild try case or with index.mjs and the node10 command, then inspect the generated dist/index.js. Trace the lowering of the class field and computed constructor getter, focusing on where the __super helper is emitted. Done means the generated node10 output keeps super inside a valid class constructor context and runs without the reported SyntaxError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, javascript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100