Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement @babel/plugin-bugfix-safari-id-destructuring-collision-in-f…
…unction-expression (#13842) * fix: register function expression id after params * implement bugfix plugin * add more testcases * fix: do not skip pattern binding referencing id * update compat-table * add bugfix plugin to preset-env * update Babel 8 test fixtures * Update packages/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/README.md * chore: bundle bugfix plugin * address review comments * add runtime version check * update compat table * fix syntax error * update test fixtures * revert bugfixes targets update * update Babel 8 test fixtures
- Loading branch information
Showing
195 changed files
with
732 additions
and
311 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
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
3 changes: 3 additions & 0 deletions
3
...s/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/.npmignore
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 |
19 changes: 19 additions & 0 deletions
19
...lugin-bugfix-safari-id-destructuring-collision-in-function-expression/README.md
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-safari-id-destructuring-collision-in-function-expression | ||
|
||
> Rename destructuring parameter to workaround a [Safari bug](https://bugs.webkit.org/show_bug.cgi?id=220517). | ||
See our website [@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression](https://babeljs.io/docs/en/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression) for more information. | ||
|
||
## Install | ||
|
||
Using npm: | ||
|
||
```sh | ||
npm install --save-dev @babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression | ||
``` | ||
|
||
or using yarn: | ||
|
||
```sh | ||
yarn add @babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression --dev | ||
``` |
40 changes: 40 additions & 0 deletions
40
...babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/package.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,40 @@ | ||
{ | ||
"name": "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression", | ||
"version": "0.0.0", | ||
"description": "Rename destructuring parameter to workaround https://bugs.webkit.org/show_bug.cgi?id=220517", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/babel/babel.git", | ||
"directory": "packages/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression" | ||
}, | ||
"homepage": "https://babel.dev/docs/en/next/babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression", | ||
"license": "MIT", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"main": "./lib/index.js", | ||
"exports": { | ||
".": [ | ||
"./lib/index.js" | ||
] | ||
}, | ||
"keywords": [ | ||
"babel-plugin", | ||
"bugfix" | ||
], | ||
"dependencies": { | ||
"@babel/helper-plugin-utils": "workspace:^7.14.5" | ||
}, | ||
"peerDependencies": { | ||
"@babel/core": "^7.0.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "workspace:*", | ||
"@babel/helper-plugin-test-runner": "workspace:*", | ||
"@babel/traverse": "workspace:*" | ||
}, | ||
"engines": { | ||
"node": ">=6.9.0" | ||
}, | ||
"author": "The Babel Team (https://babel.dev/team)" | ||
} |
25 changes: 25 additions & 0 deletions
25
...babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/src/index.ts
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,25 @@ | ||
import { declare } from "@babel/helper-plugin-utils"; | ||
import type { PluginPass } from "@babel/core"; | ||
import type { Visitor } from "@babel/traverse"; | ||
import { shouldTransform } from "./util"; | ||
|
||
export default declare(api => { | ||
api.assertVersion("^7.15.0"); | ||
|
||
return { | ||
name: "plugin-bugfix-safari-id-destructuring-collision-in-function-expression", | ||
|
||
visitor: { | ||
FunctionExpression(path) { | ||
const name = shouldTransform(path); | ||
if (name) { | ||
// Now we have (function a([a]) {}) | ||
const { scope } = path; | ||
// invariant: path.node.id is always an Identifier here | ||
const newParamName = scope.generateUid(name); | ||
scope.rename(name, newParamName); | ||
} | ||
}, | ||
} as Visitor<PluginPass>, | ||
}; | ||
}); |
41 changes: 41 additions & 0 deletions
41
.../babel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/src/util.ts
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,41 @@ | ||
import type { FunctionExpression } from "@babel/types"; | ||
import type { NodePath } from "@babel/traverse"; | ||
|
||
/** | ||
* Check whether a function expression can be affected by | ||
* https://bugs.webkit.org/show_bug.cgi?id=220517 | ||
* @param path The function expression NodePath | ||
* @returns the name of function id if it should be transformed, otherwise returns false | ||
*/ | ||
export function shouldTransform( | ||
path: NodePath<FunctionExpression>, | ||
): string | false { | ||
const { node } = path; | ||
const functionId = node.id; | ||
if (!functionId) return false; | ||
|
||
const name = functionId.name; | ||
// On collision, `getOwnBinding` returns the param binding | ||
// with the id binding be registered as constant violation | ||
const paramNameBinding = path.scope.getOwnBinding(name); | ||
const constantViolations = paramNameBinding.constantViolations; | ||
if (constantViolations.length === 0) { | ||
// the function scope has no such collided bindings | ||
return false; | ||
} | ||
const firstViolation = constantViolations[0]; | ||
|
||
if (firstViolation.node !== node) { | ||
// the violation does not happen in id | ||
// e.g. (function a() { var a; }) | ||
return false; | ||
} | ||
|
||
if (paramNameBinding.identifier === paramNameBinding.path.node) { | ||
// the param binding is a simple parameter | ||
// e.g. (function a(a) {}) | ||
return false; | ||
} | ||
|
||
return name; | ||
} |
1 change: 1 addition & 0 deletions
1
...tructuring-collision-in-function-expression/test/fixtures/basic/avoid-collision/input.mjs
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 @@ | ||
(function a([a, _a]) { a + _a }) |
3 changes: 3 additions & 0 deletions
3
...ructuring-collision-in-function-expression/test/fixtures/basic/avoid-collision/output.mjs
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 @@ | ||
(function a([_a2, _a]) { | ||
_a2 + _a; | ||
}); |
3 changes: 3 additions & 0 deletions
3
...ari-id-destructuring-collision-in-function-expression/test/fixtures/basic/basic/input.mjs
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 @@ | ||
(function a([a]) { a }); | ||
(function a({ ...a }) { a }); | ||
(function a({ a }) { a }); |
14 changes: 14 additions & 0 deletions
14
...ri-id-destructuring-collision-in-function-expression/test/fixtures/basic/basic/output.mjs
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,14 @@ | ||
(function a([_a]) { | ||
_a; | ||
}); | ||
|
||
(function a({ ..._a2 | ||
}) { | ||
_a2; | ||
}); | ||
|
||
(function a({ | ||
a: _a3 | ||
}) { | ||
_a3; | ||
}); |
3 changes: 3 additions & 0 deletions
3
...ugfix-safari-id-destructuring-collision-in-function-expression/test/fixtures/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,3 @@ | ||
{ | ||
"plugins": ["bugfix-safari-id-destructuring-collision-in-function-expression"] | ||
} |
3 changes: 3 additions & 0 deletions
3
...abel-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/test/index.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,3 @@ | ||
import runner from "@babel/helper-plugin-test-runner"; | ||
|
||
runner(import.meta.url); |
56 changes: 56 additions & 0 deletions
56
...-plugin-bugfix-safari-id-destructuring-collision-in-function-expression/test/util.test.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,56 @@ | ||
import { parseSync, traverse } from "@babel/core"; | ||
import { shouldTransform } from "../src/util.ts"; | ||
|
||
function getPath(input, parserOpts = {}) { | ||
let targetPath; | ||
traverse( | ||
parseSync(input, { | ||
parserOpts, | ||
filename: "example.js", | ||
configFile: false, | ||
}), | ||
{ | ||
FunctionExpression(path) { | ||
targetPath = path; | ||
path.stop(); | ||
}, | ||
}, | ||
); | ||
return targetPath; | ||
} | ||
|
||
describe("shouldTransform", () => { | ||
const positiveCases = [ | ||
"(function a([a]) {})", | ||
"({ b: function a([a]) {} })", | ||
"(function a({a}) {})", | ||
"(function a(...a) {})", | ||
"(function a({ ...a }) {})", | ||
"(function a([a = 1]) {})", | ||
"(function a(b, { a: [,...a] }) {})", | ||
]; | ||
|
||
const negativeCases = [ | ||
"(function () {})", | ||
"(function a() {})", | ||
"(function a(a) {})", | ||
"(function a() { var a })", | ||
"(function b([a]) { var a })", | ||
"(function b([a]) { function a() {} })", | ||
"(function a(x = a) {})", | ||
"(function a() { var { a } = {}; })", | ||
"(function b([a]) { var { a } = {}; })", | ||
"(function a({ [a]: b }) {})", | ||
]; | ||
|
||
describe("the following cases should be transformed", () => { | ||
test.each(positiveCases)("%p", input => { | ||
expect(shouldTransform(getPath(input))).toBe("a"); | ||
}); | ||
}); | ||
describe("the following cases should not be transformed", () => { | ||
test.each(negativeCases)("%p", input => { | ||
expect(shouldTransform(getPath(input))).toBe(false); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.