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 376x 376x 12x 12x 12x 12x 364x 364x 15x 15x 15x 15x 15x 349x 349x 338x 6x 2x 4x 4x 4x 4x 4x 332x 7x 18x 18x 18x 18x 18x 18x 16x 18x 36x 34x 34x 34x 18x 18x 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; |