diff --git a/packages/babel-sugar-inject-h/src/index.js b/packages/babel-sugar-inject-h/src/index.js index 43ad368..62d8660 100644 --- a/packages/babel-sugar-inject-h/src/index.js +++ b/packages/babel-sugar-inject-h/src/index.js @@ -1,4 +1,4 @@ -import syntaxJsx from '@babel/plugin-syntax-jsx' +import syntaxJsx from "@babel/plugin-syntax-jsx"; /** * Check if first parameter is `h` @@ -7,9 +7,9 @@ import syntaxJsx from '@babel/plugin-syntax-jsx' * @returns boolean */ const firstParamIsH = (t, path) => { - const params = path.get('params') - return params.length && t.isIdentifier(params[0]) && params[0].node.name === 'h' -} + const params = path.get("params"); + return params.length && t.isIdentifier(params[0]) && params[0].node.name === "h"; +}; /** * Check if body contains JSX @@ -20,17 +20,17 @@ const firstParamIsH = (t, path) => { const hasJSX = (t, path) => { const JSXChecker = { hasJSX: false, - } + }; path.traverse( { JSXElement() { - this.hasJSX = true + this.hasJSX = true; }, }, - JSXChecker, - ) - return JSXChecker.hasJSX -} + JSXChecker + ); + return JSXChecker.hasJSX; +}; /** * Check if is inside a JSX expression @@ -40,45 +40,54 @@ const hasJSX = (t, path) => { */ const isInsideJSXExpression = (t, path) => { if (!path.parentPath) { - return false + return false; } if (t.isJSXExpressionContainer(path.parentPath)) { - return true + return true; + } + return isInsideJSXExpression(t, path.parentPath); +}; + +/** + * generate code after inject h + * @param {*} t + * @param {*} path + * @param {*} isRender + * @returns void + */ +const generateCode = (t, path, isRender) => { + if (firstParamIsH(t, path) || !hasJSX(t, path) || isInsideJSXExpression(t, path)) { + return; } - return isInsideJSXExpression(t, path.parentPath) -} -export default babel => { - const t = babel.types + path.get("body").unshiftContainer("body", t.variableDeclaration("const", [t.variableDeclarator(t.identifier("h"), isRender ? t.memberExpression(t.identifier("arguments"), t.numericLiteral(0), true) : t.memberExpression(t.thisExpression(), t.identifier("$createElement")))])); +}; + +export default (babel) => { + const t = babel.types; return { inherits: syntaxJsx, visitor: { Program(path1) { path1.traverse({ - 'ObjectMethod|ClassMethod'(path) { - if (firstParamIsH(t, path) || !hasJSX(t, path) || isInsideJSXExpression(t, path)) { - return + "ObjectMethod|ClassMethod"(path) { + const isRender = path.node.key.name === "render"; + generateCode(t, path, isRender); + }, + ObjectProperty(path) { + const isRender = "render" === path.node.key.name; + const isFunctionExpression = "FunctionExpression" === path.node.value.type; + if (isFunctionExpression && isRender) { + path.traverse({ + FunctionExpression(path) { + generateCode(t, path, true); + }, + }); } - - const isRender = path.node.key.name === 'render' - - path - .get('body') - .unshiftContainer( - 'body', - t.variableDeclaration('const', [ - t.variableDeclarator( - t.identifier('h'), - isRender - ? t.memberExpression(t.identifier('arguments'), t.numericLiteral(0), true) - : t.memberExpression(t.thisExpression(), t.identifier('$createElement')), - ), - ]), - ) - } - }) - } + }, + }); + }, }, - } -} + }; +};