智能照明系统APP-本地串口
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
LightingSystemApp-serial/.svn/pristine/bc/bc376e278ec9349c48a554f3fb5...

201 lines
5.3 KiB

const t = require('@babel/types')
const {
VAR_ORIGINAL,
IDENTIFIER_FOR,
METHOD_RENDER_LIST
} = require('../../constants')
const {
getMapCallExpression
} = require('./statements')
const {
hasOwn,
genCode,
traverseKey,
processMemberExpression,
getForIndexIdentifier,
isSimpleObjectExpression
} = require('../../util')
const getMemberExpr = require('./member-expr')
const origVisitor = {
noScope: true,
Identifier (path) {
if (
!path.node.$mpProcessed &&
path.node.name === this.forItem &&
path.isReferencedIdentifier()
) {
const forItemIdentifier = t.identifier(this.forItem)
forItemIdentifier.$mpProcessed = true
path.replaceWith(
t.memberExpression(forItemIdentifier, t.identifier(VAR_ORIGINAL))
)
}
},
FunctionExpression (path) {
const callee = path.parentPath.node.callee
if (t.isIdentifier(callee) && callee.name === METHOD_RENDER_LIST) {
path.traverse(origVisitor, {
forItem: this.forItem
})
path.skip()
}
}
}
function isRefrence (forItem, code) {
if (forItem === code) {
return true
}
return code.indexOf(forItem + '.') === 0
}
function replaceRefrence (forItem, code) {
if (forItem === code) {
return ''
}
return code.replace(forItem + '.', '')
}
function getForExtra (forItem, forIndex, path, state) {
const arg0 = path.node.arguments[0]
const isNumeric = t.isNumericLiteral(arg0)
const isString = t.isStringLiteral(arg0)
let forCode = genCode(processMemberExpression(arg0, state), true)
const forKey = traverseKey(path.node)
const origForKeyCode = t.isIdentifier(forKey) && forKey.name
let forKeyCode = ''
if (forKey) {
forKeyCode = genCode(processMemberExpression(forKey, state), true)
if (isRefrence(forItem, forKeyCode)) {
forKeyCode = replaceRefrence(forItem, forKeyCode)
}
}
const forExtraElements = []
if (state.scoped.length) {
const scoped = state.scoped.find(scoped => isRefrence(scoped.forItem, forCode))
if (scoped) {
forCode = replaceRefrence(scoped.forItem, forCode)
forExtraElements.push(...scoped.forExtra)
}
}
let forCodeElem = t.stringLiteral(forCode)
if (isNumeric) {
forCodeElem = t.numericLiteral(arg0.value)
} else if (isString) {
forCodeElem = t.stringLiteral('#s#' + forCode)
}
if (forItem === origForKeyCode) { // 以自身为 key,则依据 forIndex 查找 ['list','',__i0__],['list','',index]
forExtraElements.push(
t.arrayExpression(
[
forCodeElem,
t.stringLiteral(''),
t.identifier(forIndex)
]
)
)
} else {
forExtraElements.push(
t.arrayExpression(
[
forCodeElem,
t.stringLiteral(forIndex === forKeyCode ? '' : forKeyCode),
forKey || t.identifier(forIndex)
]
)
)
}
return forExtraElements
}
module.exports = function traverseRenderList (path, state) {
const functionExpression = path.get('arguments.1')
const params = functionExpression.node.params
const forItem = params[0].name
let forIndex = params.length > 1 && params[1].name
if (!forIndex) {
if (!hasOwn(state.options, '$forIndexId')) {
state.options.$forIndexId = 0
}
forIndex = getForIndexIdentifier(state.options.$forIndexId++)
params.push(t.identifier(forIndex))
}
const forStateScoped = {
context: forItem,
forItem,
forIndex,
forExtra: getForExtra(forItem, forIndex, path, state),
propertyArray: [],
declarationArray: []
}
const forState = {
inFor: true,
context: state.context,
options: state.options,
errors: state.errors,
tips: state.tips,
scoped: [forStateScoped].concat(state.scoped),
identifierArray: state.identifierArray,
propertyArray: [],
declarationArray: [],
computedProperty: {},
initExpressionStatementArray: state.initExpressionStatementArray
}
functionExpression.traverse(require('./visitor'), forState)
const forPath = path.get('arguments.0')
if (forStateScoped.propertyArray.length) {
// for => map
forPath.replaceWith(
getMemberExpr(
forPath,
IDENTIFIER_FOR,
getMapCallExpression(
forPath.node,
forStateScoped.propertyArray,
forStateScoped.declarationArray,
[], // eventPropertyArray
forItem,
forIndex
),
forState
)
)
functionExpression.traverse(origVisitor, {
forItem
})
const keys = Object.keys(forState.computedProperty)
if (keys.length) {
keys.forEach(key => {
const property = forState.computedProperty[key]
if (t.isMemberExpression(property) && property.object.name === forItem) {
property.object = t.memberExpression(t.identifier(forItem), t.identifier(VAR_ORIGINAL))
forState.options.replaceCodes[key] = `'+${genCode(property, true)}+'`
}
})
}
} else if (forPath.isCallExpression() || (forPath.isObjectExpression() && !isSimpleObjectExpression(forPath.node))) {
forPath.replaceWith(getMemberExpr(forPath, IDENTIFIER_FOR, forPath.node, forState))
} else {
forPath.traverse(require('./visitor'), forState)
}
forState.propertyArray.forEach(property => {
state.propertyArray.push(property)
})
forState.declarationArray.forEach(declaration => {
state.declarationArray.push(declaration)
})
}