Split the simple-access transforms out of the module transform into a general helper.
This commit is contained in:
parent
0125c03303
commit
9dfcf0f116
@ -9,6 +9,7 @@
|
|||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-helper-module-imports": "7.0.0-beta.2",
|
"babel-helper-module-imports": "7.0.0-beta.2",
|
||||||
|
"babel-helper-simple-access": "7.0.0-beta.2",
|
||||||
"babel-template": "7.0.0-beta.2",
|
"babel-template": "7.0.0-beta.2",
|
||||||
"babel-types": "7.0.0-beta.2",
|
"babel-types": "7.0.0-beta.2",
|
||||||
"lodash": "^4.2.0"
|
"lodash": "^4.2.0"
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
import assert from "assert";
|
||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
import template from "babel-template";
|
import template from "babel-template";
|
||||||
|
import simplifyAccess from "babel-helper-simple-access";
|
||||||
|
|
||||||
import type { ModuleMetadata } from "./";
|
import type { ModuleMetadata } from "./";
|
||||||
|
|
||||||
@ -44,6 +46,12 @@ export default function rewriteLiveReferences(
|
|||||||
exported, // local name => exported name list
|
exported, // local name => exported name list
|
||||||
});
|
});
|
||||||
|
|
||||||
|
simplifyAccess(
|
||||||
|
programPath,
|
||||||
|
// NOTE(logan): The 'Array.from' calls are to make this code with in loose mode.
|
||||||
|
new Set([...Array.from(imported.keys()), ...Array.from(exported.keys())]),
|
||||||
|
);
|
||||||
|
|
||||||
// Rewrite reads/writes from imports and exports to have the correct behavior.
|
// Rewrite reads/writes from imports and exports to have the correct behavior.
|
||||||
programPath.traverse(rewriteReferencesVisitor, {
|
programPath.traverse(rewriteReferencesVisitor, {
|
||||||
seen: new WeakSet(),
|
seen: new WeakSet(),
|
||||||
@ -188,57 +196,6 @@ const rewriteReferencesVisitor = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
UpdateExpression: {
|
|
||||||
exit(path) {
|
|
||||||
const { scope, imported, exported } = this;
|
|
||||||
|
|
||||||
const arg = path.get("argument");
|
|
||||||
if (!arg.isIdentifier()) return;
|
|
||||||
const localName = arg.node.name;
|
|
||||||
|
|
||||||
if (!imported.has(localName) && !exported.has(localName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// redeclared in this scope
|
|
||||||
if (scope.getBinding(localName) !== path.scope.getBinding(localName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const exportedNames = exported.get(localName) || [];
|
|
||||||
|
|
||||||
if (exportedNames.length > 0 || imported.has(localName)) {
|
|
||||||
if (
|
|
||||||
path.node.prefix ||
|
|
||||||
(path.parentPath.isExpressionStatement() &&
|
|
||||||
!path.isCompletionRecord())
|
|
||||||
) {
|
|
||||||
// ++i => (i += 1);
|
|
||||||
path.replaceWith(
|
|
||||||
t.assignmentExpression("+=", arg.node, t.numericLiteral(1)),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const varName = path.scope.generateDeclaredUidIdentifier("old");
|
|
||||||
|
|
||||||
const assignment = t.binaryExpression(
|
|
||||||
path.node.operator.slice(0, 1),
|
|
||||||
varName,
|
|
||||||
t.numericLiteral(1),
|
|
||||||
);
|
|
||||||
|
|
||||||
// i++ => (_tmp = i, i = _tmp + 1, _tmp)
|
|
||||||
path.replaceWith(
|
|
||||||
t.sequenceExpression([
|
|
||||||
t.assignmentExpression("=", varName, arg.node),
|
|
||||||
t.assignmentExpression("=", arg.node, assignment),
|
|
||||||
varName,
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
AssignmentExpression: {
|
AssignmentExpression: {
|
||||||
exit(path) {
|
exit(path) {
|
||||||
const {
|
const {
|
||||||
@ -267,23 +224,14 @@ const rewriteReferencesVisitor = {
|
|||||||
const exportedNames = exported.get(localName) || [];
|
const exportedNames = exported.get(localName) || [];
|
||||||
const importData = imported.get(localName);
|
const importData = imported.get(localName);
|
||||||
if (exportedNames.length > 0 || importData) {
|
if (exportedNames.length > 0 || importData) {
|
||||||
|
assert(path.node.operator === "=", "Path was not simplified");
|
||||||
|
|
||||||
const assignment = path.node;
|
const assignment = path.node;
|
||||||
|
|
||||||
if (importData) {
|
if (importData) {
|
||||||
assignment.left =
|
assignment.left =
|
||||||
buildImportReference(importData) || assignment.left;
|
buildImportReference(importData) || assignment.left;
|
||||||
|
|
||||||
if (path.node.operator !== "=") {
|
|
||||||
const op = path.node.operator.slice(0, -1);
|
|
||||||
path.node.operator = "=";
|
|
||||||
|
|
||||||
assignment.right = t.binaryExpression(
|
|
||||||
op,
|
|
||||||
assignment.left,
|
|
||||||
assignment.right,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
assignment.right = t.sequenceExpression([
|
assignment.right = t.sequenceExpression([
|
||||||
assignment.right,
|
assignment.right,
|
||||||
buildImportThrow(localName),
|
buildImportThrow(localName),
|
||||||
|
|||||||
3
packages/babel-helper-simple-access/.npmignore
Normal file
3
packages/babel-helper-simple-access/.npmignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
src
|
||||||
|
test
|
||||||
|
*.log
|
||||||
18
packages/babel-helper-simple-access/README.md
Normal file
18
packages/babel-helper-simple-access/README.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# babel-helper-simple-assignment
|
||||||
|
|
||||||
|
There are many cases where it is hard to perform transformations because a
|
||||||
|
piece of code using complex structures. Say you want to rewrite all accesses
|
||||||
|
to a given variable, and there are cases like
|
||||||
|
|
||||||
|
```
|
||||||
|
i += 1
|
||||||
|
--i;
|
||||||
|
```
|
||||||
|
|
||||||
|
It is difficult to work with.
|
||||||
|
|
||||||
|
This helper can handle converting these to simple access patterns of
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
TODO
|
||||||
15
packages/babel-helper-simple-access/package.json
Normal file
15
packages/babel-helper-simple-access/package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "babel-helper-simple-access",
|
||||||
|
"version": "7.0.0-beta.2",
|
||||||
|
"description": "Babel helper for ensuring that access to a given value is performed through simple accesses",
|
||||||
|
"author": "Logan Smyth <loganfsmyth@gmail.com>",
|
||||||
|
"homepage": "https://babeljs.io/",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-simple-access",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"babel-template": "7.0.0-beta.2",
|
||||||
|
"babel-types": "7.0.0-beta.2",
|
||||||
|
"lodash": "^4.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
87
packages/babel-helper-simple-access/src/index.js
Normal file
87
packages/babel-helper-simple-access/src/index.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import * as t from "babel-types";
|
||||||
|
|
||||||
|
export default function simplifyAccess(path: NodePath, bindingNames) {
|
||||||
|
path.traverse(simpleAssignmentVisitor, {
|
||||||
|
scope: path.scope,
|
||||||
|
bindingNames,
|
||||||
|
seen: new WeakSet(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const simpleAssignmentVisitor = {
|
||||||
|
UpdateExpression: {
|
||||||
|
exit(path) {
|
||||||
|
const { scope, bindingNames } = this;
|
||||||
|
|
||||||
|
const arg = path.get("argument");
|
||||||
|
if (!arg.isIdentifier()) return;
|
||||||
|
const localName = arg.node.name;
|
||||||
|
|
||||||
|
if (!bindingNames.has(localName)) return;
|
||||||
|
|
||||||
|
// redeclared in this scope
|
||||||
|
if (scope.getBinding(localName) !== path.scope.getBinding(localName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
path.node.prefix ||
|
||||||
|
(path.parentPath.isExpressionStatement() && !path.isCompletionRecord())
|
||||||
|
) {
|
||||||
|
// ++i => (i += 1);
|
||||||
|
path.replaceWith(
|
||||||
|
t.assignmentExpression("+=", arg.node, t.numericLiteral(1)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const varName = path.scope.generateDeclaredUidIdentifier("old");
|
||||||
|
|
||||||
|
const assignment = t.binaryExpression(
|
||||||
|
path.node.operator.slice(0, 1),
|
||||||
|
varName,
|
||||||
|
t.numericLiteral(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
// i++ => (_tmp = i, i = _tmp + 1, _tmp)
|
||||||
|
path.replaceWith(
|
||||||
|
t.sequenceExpression([
|
||||||
|
t.assignmentExpression("=", varName, arg.node),
|
||||||
|
t.assignmentExpression("=", arg.node, assignment),
|
||||||
|
varName,
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
AssignmentExpression: {
|
||||||
|
exit(path) {
|
||||||
|
const { scope, seen, bindingNames } = this;
|
||||||
|
|
||||||
|
if (path.node.operator === "=") return;
|
||||||
|
|
||||||
|
if (seen.has(path.node)) return;
|
||||||
|
seen.add(path.node);
|
||||||
|
|
||||||
|
const left = path.get("left");
|
||||||
|
if (!left.isIdentifier()) return;
|
||||||
|
|
||||||
|
// Simple update-assign foo += 1;
|
||||||
|
// => exports.foo = (foo += 1);
|
||||||
|
const localName = left.node.name;
|
||||||
|
|
||||||
|
if (!bindingNames.has(localName)) return;
|
||||||
|
|
||||||
|
// redeclared in this scope
|
||||||
|
if (scope.getBinding(localName) !== path.scope.getBinding(localName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.node.right = t.binaryExpression(
|
||||||
|
path.node.operator.slice(0, -1),
|
||||||
|
path.node.left,
|
||||||
|
path.node.right,
|
||||||
|
);
|
||||||
|
path.node.operator = "=";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -8,7 +8,7 @@ define(["exports"], function (_exports) {
|
|||||||
var test = 2;
|
var test = 2;
|
||||||
_exports.test = test;
|
_exports.test = test;
|
||||||
_exports.test = test = 5;
|
_exports.test = test = 5;
|
||||||
_exports.test = test += 1;
|
_exports.test = test = test + 1;
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var test = 2;
|
var test = 2;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ exports.f = exports.e = exports.c = exports.a = exports.test = void 0;
|
|||||||
var test = 2;
|
var test = 2;
|
||||||
exports.test = test;
|
exports.test = test;
|
||||||
exports.test = test = 5;
|
exports.test = test = 5;
|
||||||
exports.test = test += 1;
|
exports.test = test = test + 1;
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var test = 2;
|
var test = 2;
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
var test = 2;
|
var test = 2;
|
||||||
_exports.test = test;
|
_exports.test = test;
|
||||||
_exports.test = test = 5;
|
_exports.test = test = 5;
|
||||||
_exports.test = test += 1;
|
_exports.test = test = test + 1;
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var test = 2;
|
var test = 2;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user