refactor: improved transformation logic

This commit is contained in:
Sven SAULEAU 2017-04-29 18:35:15 +02:00 committed by Justin Ridgewell
parent 72259ca5d3
commit 64ff5a080d
4 changed files with 43 additions and 56 deletions

View File

@ -1,61 +1,44 @@
import createTemplate from "babel-template";
import traverse from "babel-traverse";
const nullOrUndefinedCheck = createTemplate(`
typeof CHECK !== "undefined" && CHECK !== null
? NEXT
: null
`);
function isNodeOptional(node) {
return node.optional === true;
}
const nullOrUndefinedCheckVisitor = {
noScope: true,
Identifier(path, replacements) {
if (path.node.name in replacements) {
path.replaceInline(replacements[path.node.name]);
}
},
};
function createCheck(node, object) {
const template = nullOrUndefinedCheck();
traverse(template, nullOrUndefinedCheckVisitor, null, {
CHECK: object,
NEXT: node,
});
return template;
}
export default function ({ types: t }) {
function createCondition(ref, access, nextProperty) {
return t.conditionalExpression(
createCheckAgainstNull(
t.AssignmentExpression("=", ref, access)
),
t.memberExpression(ref, nextProperty),
t.NullLiteral()
);
}
function createCheckAgainstNull(left) {
return t.BinaryExpression("!=", left, t.NullLiteral());
}
function isNodeOptional(node) {
return node.optional === true;
}
return {
visitor: {
MemberExpression(path) {
if (isNodeOptional(path.node)) {
let { object } = path.node;
do {
object = createCheck(
object,
object.object
);
} while (t.isMemberExpression(object) && isNodeOptional(object));
path.replaceWith(
createCheck(path.node, object)
);
path.stop();
MemberExpression(path, state) {
if (!isNodeOptional(path.node)) {
return;
}
const { object, property } = path.node;
if (!state.optionalTemp) {
const id = path.scope.generateUidIdentifier();
state.optionalTemp = id;
path.scope.push({ id });
}
path.replaceWith(
createCondition(state.optionalTemp, object, property)
);
},
},
};

View File

@ -1 +1,3 @@
typeof foo !== "undefined" && foo !== null ? foo.bar : null;
var _temp;
(_temp = foo) != null ? _temp.bar : null;

View File

@ -1 +1,3 @@
typeof (typeof foo !== "undefined" && foo !== null ? foo.bar : null) !== "undefined" && (typeof foo !== "undefined" && foo !== null ? foo.bar : null) !== null ? foo.bar.vroum : null;
var _temp;
((_temp = ((_temp = a) != null ? _temp.b : null).c) != null ? _temp.d : null).e;