Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add bugfix plugin for spread in
super()
- Loading branch information
1 parent
f074690
commit 90730e4
Showing
26 changed files
with
432 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
src | ||
test | ||
*.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining | ||
|
||
> Transform optional chaining operators to workaround a [v8 bug](https://crbug.com/v8/11558). | ||
See our website [@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining](https://babeljs.io/docs/en/babel-plugin-bugfix-v8-spread-parameters-in-optional-chaining) for more information. | ||
|
||
## Install | ||
|
||
Using npm: | ||
|
||
```sh | ||
npm install --save-dev @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining | ||
``` | ||
|
||
or using yarn: | ||
|
||
```sh | ||
yarn add @babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining --dev | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "@babel/plugin-bugfix-super-spread", | ||
"version": "7.13.12", | ||
"description": "Transform super() calls with spread arguments without compiling classes", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/babel/babel.git", | ||
"directory": "packages/babel-plugin-bugfix-super-spread" | ||
}, | ||
"homepage": "https://babel.dev/docs/en/next/babel-plugin-bugfix-super-spread", | ||
"license": "MIT", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"main": "lib/index.js", | ||
"exports": { | ||
".": [ | ||
"./lib/index.js" | ||
] | ||
}, | ||
"keywords": [ | ||
"babel-plugin", | ||
"bugfix" | ||
], | ||
"dependencies": { | ||
"@babel/helper-plugin-utils": "workspace:^7.13.0", | ||
"@babel/helper-replace-supers": "workspace:^7.13.12" | ||
}, | ||
"peerDependencies": { | ||
"@babel/core": "^7.13.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "workspace:*", | ||
"@babel/helper-plugin-test-runner": "workspace:*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
import { declare } from "@babel/helper-plugin-utils"; | ||
import ReplaceSupers from "@babel/helper-replace-supers"; | ||
|
||
const last = arr => arr[arr.length - 1]; | ||
|
||
export default declare(({ assertVersion, types: t, template, assumption }) => { | ||
assertVersion(7); | ||
|
||
const constantSuper = assumption("constantSuper"); | ||
|
||
const constructorContextVisitor = { | ||
ThisExpression(path, state) { | ||
state.this.push(path); | ||
}, | ||
Super(path, state) { | ||
if (path.parentPath.isCallExpression()) { | ||
state.superCalls.push(path.parentPath); | ||
|
||
if (path.parent.arguments.some(arg => t.isSpreadElement(arg))) { | ||
state.superSpreads.add(path.parent); | ||
} | ||
} else { | ||
state.super.push(path.parentPath); | ||
} | ||
}, | ||
Function(path) { | ||
if (!path.isArrowFunctionExpression()) path.skip(); | ||
}, | ||
}; | ||
|
||
const constructorReturnVisitor = { | ||
ReturnStatement(path, state) { | ||
state.return.push(path); | ||
}, | ||
Function(path) { | ||
path.skip(); | ||
}, | ||
}; | ||
|
||
return { | ||
name: "bugfix-super-spread", | ||
|
||
visitor: { | ||
Class(path, file) { | ||
if (!path.node.superClass) return; | ||
|
||
const constructorPath = path | ||
.get("body.body") | ||
.find(el => el.isClassMethod({ kind: "constructor" })); | ||
if (!constructorPath) return; | ||
|
||
const state = { | ||
this: [], | ||
super: [], | ||
superCalls: [], | ||
superSpreads: new Set(), | ||
return: [], | ||
noScope: true, | ||
}; | ||
constructorPath.traverse(constructorContextVisitor, state); | ||
if (state.superSpreads.size === 0) return; | ||
constructorPath.traverse(constructorReturnVisitor, state); | ||
|
||
const superId = path.scope.generateUidIdentifierBasedOnNode( | ||
path.node.superClass, | ||
); | ||
path.scope.push({ id: superId }); | ||
path.set( | ||
"superClass", | ||
t.assignmentExpression( | ||
"=", | ||
t.cloneNode(superId), | ||
path.node.superClass, | ||
), | ||
); | ||
|
||
const thisId = constructorPath.scope.generateUidIdentifier("this"); | ||
constructorPath.scope.push({ id: thisId }); | ||
|
||
for (const path of state.superCalls) { | ||
if (state.superSpreads.has(path.node)) { | ||
const args = t.arrayExpression(path.node.arguments); | ||
const newTarget = t.metaProperty( | ||
t.identifier("new"), | ||
t.identifier("target"), | ||
); | ||
|
||
path.replaceWith( | ||
template.ast` | ||
${t.cloneNode(thisId)} = Reflect.construct( | ||
${t.cloneNode(superId)}, | ||
${args}, | ||
${newTarget} | ||
) | ||
`, | ||
); | ||
} else { | ||
path.replaceWith( | ||
template.ast` | ||
${t.cloneNode(thisId)} = ${path.node}`, | ||
); | ||
} | ||
} | ||
|
||
for (const path of state.this) { | ||
path.replaceWith(t.cloneNode(thisId)); | ||
} | ||
|
||
for (const path of state.return) { | ||
if (!path.node.argument) { | ||
path.set("argument", t.cloneNode(thisId)); | ||
} else { | ||
path.set( | ||
"argument", | ||
t.callExpression(file.addHelper("possibleConstructorReturn"), [ | ||
t.cloneNode(thisId), | ||
path.node.argument, | ||
]), | ||
); | ||
} | ||
} | ||
const bodyPath = constructorPath.get("body"); | ||
if (!last(bodyPath.get("body")).isReturnStatement()) { | ||
bodyPath.pushContainer( | ||
"body", | ||
t.returnStatement(t.cloneNode(thisId)), | ||
); | ||
} | ||
|
||
let classId = path.node.id; | ||
new ReplaceSupers({ | ||
methodPath: constructorPath, | ||
superRef: superId, | ||
thisRef: thisId, | ||
constantSuper: constantSuper, | ||
file: file, | ||
refToPreserve: classId, | ||
getObjectRef() { | ||
if (!classId) { | ||
classId = path.scope.generateUidIdentifier("class"); | ||
path.set("id", classId); | ||
} | ||
return classId; | ||
}, | ||
}).replace(); | ||
}, | ||
}, | ||
}; | ||
}); |
8 changes: 8 additions & 0 deletions
8
...es/babel-plugin-bugfix-super-spread/test/fixtures/assumption-constantSuper/basic/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
class A extends B { | ||
constructor() { | ||
super(1, ...foo, 2); | ||
this.x; | ||
super.x(); | ||
super.y = 3; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...s/babel-plugin-bugfix-super-spread/test/fixtures/assumption-constantSuper/basic/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
var _B; | ||
|
||
class A extends (_B = B) { | ||
constructor() { | ||
var _this; | ||
|
||
_this = Reflect.construct(_B, [1, ...foo, 2], new.target); | ||
_this.x; | ||
|
||
_B.prototype.x.call(_this); | ||
|
||
_this.y = 3; | ||
return _this; | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
...ages/babel-plugin-bugfix-super-spread/test/fixtures/assumption-constantSuper/options.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"plugins": ["bugfix-super-spread"], | ||
"assumptions": { | ||
"constantSuper": true | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/babel-plugin-bugfix-super-spread/test/fixtures/basic/basic/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class A extends B { | ||
constructor() { | ||
super(1, ...foo, 2); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/babel-plugin-bugfix-super-spread/test/fixtures/basic/basic/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var _B; | ||
|
||
class A extends (_B = B) { | ||
constructor() { | ||
var _this; | ||
|
||
_this = Reflect.construct(_B, [1, ...foo, 2], new.target); | ||
return _this; | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
packages/babel-plugin-bugfix-super-spread/test/fixtures/basic/in-arrow/input.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class A extends B { | ||
constructor() { | ||
() => super(...args); | ||
() => this; | ||
() => super.foo; | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
packages/babel-plugin-bugfix-super-spread/test/fixtures/basic/in-arrow/output.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
var _B; | ||
|
||
class A extends (_B = B) { | ||
constructor() { | ||
var _this; | ||
|
||
() => _this = Reflect.construct(_B, [...args], new.target); | ||
|
||
() => _this; | ||
|
||
() => babelHelpers.get(babelHelpers.getPrototypeOf(A.prototype), "foo", _this); | ||
|
||
return _this; | ||
} | ||
|
||
} |
Oops, something went wrong.