export function parseLoopBody (
body: NodePath<t.BlockStatement>,
jsxDeclarations: Set<NodePath<t.Node>>,
// @TODO
// 把 templates 换成 Map 可以支持 shalow variables declared
// 现在先用 ESLint 的 no-shalow 顶着
templates: Map<string, t.JSXElement>,
loopScopes: Set<string>,
finalReturnElement: t.JSXElement,
returnedPaths: NodePath<t.Node>[]
) {
const bodyScope = body.scope
body.traverse({
JSXElement (jsxElementPath) {
const parentNode = jsxElementPath.parent
const parentPath = jsxElementPath.parentPath
const isFinalReturn = jsxElementPath.getFunctionParent().isClassMethod()
const isJSXChildren = t.isJSXElement(parentNode)
if (!isJSXChildren) {
let statementParent = jsxElementPath.getStatementParent()
if (
!(
statementParent.isVariableDeclaration() ||
statementParent.isExpressionStatement()
)
) {
statementParent = statementParent.findParent(
s => s.isVariableDeclaration() || s.isExpressionStatement()
) as NodePath<t.Statement>
}
jsxDeclarations.add(statementParent)
if (t.isVariableDeclarator(parentNode)) {
if (statementParent) {
const name = findIdentifierFromStatement(statementParent.node as t.VariableDeclaration)
// setTemplate(name, path, templates)
name && templates.set(name, jsxElementPath.node)
}
} else if (t.isLogicalExpression(parentNode)) {
const { left, operator } = parentNode
if (operator === '&&') {
if (t.isExpression(left)) {
newJSXIfAttr(jsxElementPath.node, left)
parentPath.replaceWith(jsxElementPath.node)
if (statementParent) {
const name = findIdentifierFromStatement(statementParent.node as t.VariableDeclaration)
setTemplate(name, jsxElementPath, templates)
// name && templates.set(name, path.node)
}
}
}
} else if (t.isConditionalExpression(parentNode)) {
const { test, consequent, alternate } = parentNode
const block = buildBlockElement()
if (t.isJSXElement(consequent) && t.isLiteral(alternate)) {
const { value, confident } = parentPath.get('alternate').evaluate()
if (confident && !value) {
newJSXIfAttr(block, test)
block.children = [ jsxElementPath.node ]
// newJSXIfAttr(jsxElementPath.node, test)
parentPath.replaceWith(block)
if (statementParent) {
const name = findIdentifierFromStatement(
statementParent.node as t.VariableDeclaration
)
setTemplate(name, jsxElementPath, templates)
// name && templates.set(name, path.node)
}
}
} else if (t.isLiteral(consequent) && t.isJSXElement(consequent)) {
if (t.isNullLiteral(consequent)) {
newJSXIfAttr(block, reverseBoolean(test))
// newJSXIfAttr(jsxElementPath.node, reverseBoolean(test))
parentPath.replaceWith(block)
if (statementParent) {
const name = findIdentifierFromStatement(
statementParent.node as t.VariableDeclaration
)
setTemplate(name, jsxElementPath, templates)
// name && templates.set(name, path.node)
}
}
} else if (t.isJSXElement(consequent) && t.isJSXElement(alternate)) {
const block2 = buildBlockElement()
block.children = [consequent]
newJSXIfAttr(block, test)
setJSXAttr(block2, Adapter.else)
block2.children = [alternate]
const parentBlock = buildBlockElement()
parentBlock.children = [block, block2]
parentPath.replaceWith(parentBlock)
if (statementParent) {
const name = findIdentifierFromStatement(
statementParent.node as t.VariableDeclaration
)
setTemplate(name, jsxElementPath, templates)
}
} else {
// console.log('todo')
}
} else if (t.isReturnStatement(parentNode)) {
//.........这里部分代码省略.........
请发表评论