wip
This commit is contained in:
committed by
Justin Ridgewell
parent
cc6959e1fa
commit
3faca62a77
@@ -1,4 +1,15 @@
|
||||
export default function ({ types: t }) {
|
||||
const nilIdentifier = t.identifier("undefined");
|
||||
|
||||
function setOptionalTransformed(node) {
|
||||
t.assertMemberExpression(node); // Dev
|
||||
node._optionalTransformed = true;
|
||||
}
|
||||
|
||||
function isOptionalTransformed(node) {
|
||||
t.assertMemberExpression(node); // Dev
|
||||
return node._optionalTransformed === true;
|
||||
}
|
||||
|
||||
function createCondition(ref, access, nextProperty, bailout) {
|
||||
|
||||
@@ -23,8 +34,87 @@ export default function ({ types: t }) {
|
||||
return {
|
||||
visitor: {
|
||||
|
||||
AssignmentExpression(path, state) {
|
||||
const { left } = path.node;
|
||||
|
||||
if (!isNodeOptional(left) || isOptionalTransformed(left)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.optionalTemp) {
|
||||
const id = path.scope.generateUidIdentifier();
|
||||
|
||||
state.optionalTemp = id;
|
||||
path.scope.push({ id });
|
||||
}
|
||||
|
||||
const { object, property } = left;
|
||||
|
||||
const isChainNil = t.BinaryExpression(
|
||||
"!=",
|
||||
createCondition(
|
||||
state.optionalTemp,
|
||||
object,
|
||||
property,
|
||||
nilIdentifier,
|
||||
),
|
||||
nilIdentifier,
|
||||
);
|
||||
|
||||
// FIXME(sven): if will be a ConditionalExpression for childs, only top level will be ifStatement
|
||||
const remplacement = t.ifStatement(isChainNil, t.blockStatement([t.expressionStatement(path.node)]));
|
||||
|
||||
setOptionalTransformed(left);
|
||||
|
||||
path.traverse({
|
||||
MemberExpression({ node }) {
|
||||
setOptionalTransformed(node);
|
||||
},
|
||||
});
|
||||
|
||||
path.parentPath.replaceWith(remplacement);
|
||||
},
|
||||
|
||||
UnaryExpression(path, state) {
|
||||
const { operator, argument } = path.node;
|
||||
|
||||
if (operator !== "delete") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isNodeOptional(argument) || isOptionalTransformed(argument)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.optionalTemp) {
|
||||
const id = path.scope.generateUidIdentifier();
|
||||
|
||||
state.optionalTemp = id;
|
||||
path.scope.push({ id });
|
||||
}
|
||||
|
||||
const { object, property } = argument;
|
||||
|
||||
const isChainNil = t.BinaryExpression(
|
||||
"!=",
|
||||
createCondition(
|
||||
state.optionalTemp,
|
||||
object,
|
||||
property,
|
||||
nilIdentifier,
|
||||
),
|
||||
nilIdentifier,
|
||||
);
|
||||
|
||||
const remplacement = t.ifStatement(isChainNil, t.blockStatement([t.expressionStatement(path.node)]));
|
||||
|
||||
setOptionalTransformed(argument);
|
||||
|
||||
path.parentPath.replaceWith(remplacement);
|
||||
},
|
||||
|
||||
MemberExpression(path, state) {
|
||||
if (!isNodeOptional(path.node)) {
|
||||
if (!isNodeOptional(path.node) || isOptionalTransformed(path.node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,15 +128,9 @@ export default function ({ types: t }) {
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(path.parent)) {
|
||||
|
||||
const remplacement = createCondition(
|
||||
t.identifier("temp_here_please"),
|
||||
object,
|
||||
property,
|
||||
t.identifier("undefined"),
|
||||
);
|
||||
|
||||
path.parentPath.replaceWith(remplacement);
|
||||
return;
|
||||
} else if (t.isUnaryExpression(path.parent)) {
|
||||
return;
|
||||
} else if (t.isCallExpression(path.parent)) {
|
||||
|
||||
const remplacement = createCondition(
|
||||
@@ -56,6 +140,7 @@ export default function ({ types: t }) {
|
||||
t.callExpression(t.identifier("Function"), []),
|
||||
);
|
||||
|
||||
setOptionalTransformed(path.node);
|
||||
path.replaceWith(remplacement);
|
||||
} else {
|
||||
|
||||
@@ -63,9 +148,10 @@ export default function ({ types: t }) {
|
||||
state.optionalTemp,
|
||||
object,
|
||||
property,
|
||||
t.identifier("undefined"),
|
||||
nilIdentifier,
|
||||
);
|
||||
|
||||
setOptionalTransformed(path.node);
|
||||
path.replaceWith(remplacement);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user