Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | 37x 37x 37x 37x 375x 375x 12x 12x 12x 12x 363x 363x 15x 15x 15x 15x 15x 348x 348x 338x 6x 2x 4x 4x 4x 4x 4x 332x 7x 17x 17x 17x 17x 17x 17x 15x 17x 34x 32x 32x 32x 17x 17x 325x 154x 154x 154x 154x 154x 11x 11x 11x 11x 11x 160x 160x 160x 160x 160x 325x 9x 9x 9x 9x 4x 4x 4x 4x 316x 10x 10x 10x 10x 9x 9x 9x 9x 312x 37x | // 把简单的api转换成ast
// todo await
const recast = require('recast-yx');
const parse = require('./parse');
const visit = recast.types.visit;
const filterProps = require('./filter-prop.js');
function getSelector(selectorCode, parseOptions, expando) {
const selector = { nodeType: '', structure: {} };
if (typeof selectorCode != 'string') {
// 如果是通过builders造出来的ast结构,比如return语句
selector.nodeType = selectorCode.type;
filterProps(selectorCode, selector.structure, '', expando);
selector.type = selectorCode.type; // 兼容只用type匹配的选择器
return selector;
} else {
selectorCode = selectorCode
.replace(/\$_\$/g, expando)
.replace(/\$\$\$/g, expando.slice(0, -1) + '$3')
.replace(/\/\$_\/\$/g, '$_$')
.replace(/\/\$\/\$\/\$/g, '$$$$$$')
}
if (selectorCode.match(/^{((.|\s)+(:|\(\))(.|\s)+)+}$/)) {
// 如果是对象字面量
let ast = parse(`var o = ${selectorCode}`);
ast = ast.program.body[0].declarations[0].init;
selector.nodeType = 'ObjectExpression';
filterProps(ast, selector.structure);
return selector;
}
let seletorAst;
try {
seletorAst = parse(selectorCode, parseOptions);
if (seletorAst.program.body.length == 0) {
// 开头的字符串会被解析成directive
if (seletorAst.program.directives.length) {
return {
nodeType: 'StringLiteral',
structure: {
value: selectorCode ? selectorCode.slice(1, -1) : ''
}
}
} else Eif (seletorAst.program.comments.length) {
let ast = seletorAst.program.comments[0]
selector.nodeType = ast.type;
filterProps(ast, selector.structure);
return selector;
}
} else if (seletorAst.program.body[0] && seletorAst.program.body[0].type == 'LabeledStatement') {
throw new Error('Missing semicolon')
}
} catch(e) {
// 可能是对象属性
try {
seletorAst = parse(`({${selectorCode}})`, parseOptions);
seletorAst = seletorAst.program.body[0].expression.properties[0]
} catch(e) {
seletorAst = null;
}
// 可能是类属性
let clsSelectorAst = null;
try {
clsSelectorAst = parse(`class a$_$ { ${selectorCode} }`, parseOptions)
clsSelectorAst = clsSelectorAst.program.body[0].body.body[0]
} catch(e) {
//
}
const result = [seletorAst, clsSelectorAst]
.filter(s => !!s)
.map(sel => {
const selector = {
nodeType: sel.type,
structure: {}
}
filterProps(sel, selector.structure)
return selector;
})
if (result.length) {
return result;
} else E{
throw new Error('parse error!' + e.message);
}
}
visit(seletorAst, {
visitExpressionStatement(path) {
const expression = path.value.expression;
Iif (!expression) return;
selector.nodeType = expression.type;
filterProps(expression, selector.structure);
this.abort();
},
visitStatement(path) {
const expression = path.value;
Iif (!expression) return;
selector.nodeType = expression.type;
filterProps(expression, selector.structure);
this.abort();
},
visitDeclaration(path) {
const declaration = path.value;
Iif (!declaration) return;
selector.nodeType = declaration.type;
filterProps(declaration, selector.structure);
this.abort();
}
});
if (selector.nodeType == 'AssignmentExpression') {
// class中的属性
try {
const selectorAstList = [selector]
const classPropSelector = { nodeType: '', structure: {} };
const classPropSelectorAst = parse(`class A { ${selectorCode } }`, parseOptions).program.body[0].body.body[0]
classPropSelector.nodeType = classPropSelectorAst.type;
filterProps(classPropSelectorAst, classPropSelector.structure);
selectorAstList.push(classPropSelector);
return selectorAstList;
} catch(e) {
//
}
} else if (selector.nodeType == 'MemberExpression') {
try {
const selectorAstList = [selector]
const classPropSelector = { nodeType: '', structure: {} };
const classPropSelectorAst = parse(`type a = ${selectorCode}`, parseOptions).program.body[0].typeAnnotation.typeName
classPropSelector.nodeType = classPropSelectorAst.type;
filterProps(classPropSelectorAst, classPropSelector.structure);
selectorAstList.push(classPropSelector);
return selectorAstList;
} catch(e) {
// maybe selectorCode = this.xxx
}
}
return selector;
}
module.exports = getSelector; |