feat: optional chaing

This commit is contained in:
Sven SAULEAU
2017-04-24 21:15:15 +02:00
committed by Justin Ridgewell
parent 5cc1cbf3bc
commit 00f58b9bfa
10 changed files with 98 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
import createTemplate from "babel-template";
import traverse from "babel-traverse";
const nullOrUndefinedCheck = createTemplate(`
typeof CHECK !== "undefined" && CHECK !== null
? NEXT
: null
`);
function isOptional(path) {
return path.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 }) {
return {
visitor: {
MemberExpression(path) {
if (isOptional(path)) {
let { object } = path.node;
while (
t.isMemberExpression(object)
&& isOptional({ node: object })
) {
object = createCheck(
object,
object.object
);
}
path.replaceWith(
createCheck(path.node, object)
);
path.stop();
}
},
},
};
}