1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const t = require("babel-types");
|
4 | const babel_generator_1 = require("babel-generator");
|
5 | const code_frame_1 = require("@babel/code-frame");
|
6 | const constant_1 = require("./constant");
|
7 | const lodash_1 = require("lodash");
|
8 | const fs = require("fs");
|
9 | const path = require("path");
|
10 | const jsx_1 = require("./jsx");
|
11 | const adapter_1 = require("./adapter");
|
12 | const options_1 = require("./options");
|
13 | const template = require('babel-template');
|
14 | function replaceJSXTextWithTextComponent(path) {
|
15 | const parent = path.findParent(p => p.isJSXElement());
|
16 | if (parent && parent.isJSXElement() && t.isJSXIdentifier(parent.node.openingElement.name) && parent.node.openingElement.name.name !== 'Text') {
|
17 | path.replaceWith(t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier('Text'), []), t.jSXClosingElement(t.jSXIdentifier('Text')), [path.isJSXText() ? t.jSXText(path.node.value) : path.node]));
|
18 | }
|
19 | }
|
20 | exports.replaceJSXTextWithTextComponent = replaceJSXTextWithTextComponent;
|
21 | function isDerivedFromProps(scope, bindingName) {
|
22 | const binding = scope.getBinding(bindingName);
|
23 | if (binding && binding.path.isVariableDeclarator()) {
|
24 | const init = binding.path.get('init');
|
25 | if (init.isMemberExpression()) {
|
26 | const { object, property } = init.node;
|
27 | if (t.isThisExpression(object) && t.isIdentifier(property, { name: 'props' })) {
|
28 | return true;
|
29 | }
|
30 | }
|
31 | if (init.isIdentifier()) {
|
32 | return isDerivedFromProps(scope, init.node.name);
|
33 | }
|
34 | }
|
35 | return false;
|
36 | }
|
37 | exports.isDerivedFromProps = isDerivedFromProps;
|
38 | function isDerivedFromThis(scope, bindingName) {
|
39 | const binding = scope.getBinding(bindingName);
|
40 | if (binding && binding.path.isVariableDeclarator()) {
|
41 | const init = binding.path.get('init');
|
42 | if (init.isThisExpression()) {
|
43 | return true;
|
44 | }
|
45 | }
|
46 | return false;
|
47 | }
|
48 | exports.isDerivedFromThis = isDerivedFromThis;
|
49 | exports.incrementId = () => {
|
50 | let id = 0;
|
51 | return () => id++;
|
52 | };
|
53 |
|
54 | exports.noop = function () { };
|
55 | function getSuperClassCode(path) {
|
56 | const obj = getSuperClassPath(path);
|
57 | if (obj) {
|
58 | const { sourceValue, resolvePath } = obj;
|
59 | try {
|
60 | const code = fs.readFileSync(resolvePath + (options_1.transformOptions.isTyped ? '.tsx' : '.js'), 'utf8');
|
61 | return {
|
62 | code,
|
63 | sourcePath: sourceValue
|
64 | };
|
65 | }
|
66 | catch (error) {
|
67 | return;
|
68 | }
|
69 | }
|
70 | }
|
71 | exports.getSuperClassCode = getSuperClassCode;
|
72 | function getSuperClassPath(path) {
|
73 | const superClass = path.node.superClass;
|
74 | if (t.isIdentifier(superClass)) {
|
75 | const binding = path.scope.getBinding(superClass.name);
|
76 | if (binding && binding.kind === 'module') {
|
77 | const bindingPath = binding.path.parentPath;
|
78 | if (bindingPath.isImportDeclaration()) {
|
79 | const source = bindingPath.node.source;
|
80 | if (source.value === constant_1.TARO_PACKAGE_NAME) {
|
81 | return;
|
82 | }
|
83 | return {
|
84 | sourceValue: source.value,
|
85 | resolvePath: pathResolver(source.value, options_1.transformOptions.sourcePath)
|
86 | };
|
87 | }
|
88 | }
|
89 | }
|
90 | }
|
91 | exports.getSuperClassPath = getSuperClassPath;
|
92 | function isContainStopPropagation(path) {
|
93 | let matched = false;
|
94 | if (path) {
|
95 | const visitor = {
|
96 | Identifier(p) {
|
97 | if (p.node.name === 'stopPropagation' &&
|
98 | p.parentPath.parentPath.isCallExpression()) {
|
99 | matched = true;
|
100 | }
|
101 | }
|
102 | };
|
103 | if (path.isIdentifier()) {
|
104 | const binding = path.scope.getBinding(path.node.name);
|
105 | if (binding) {
|
106 | binding.path.traverse(visitor);
|
107 | }
|
108 | }
|
109 | else {
|
110 | path.traverse(visitor);
|
111 | }
|
112 | }
|
113 | return matched;
|
114 | }
|
115 | exports.isContainStopPropagation = isContainStopPropagation;
|
116 | function decodeUnicode(s) {
|
117 | return unescape(s.replace(/\\(u[0-9a-fA-F]{4})/gm, '%$1'));
|
118 | }
|
119 | exports.decodeUnicode = decodeUnicode;
|
120 | function isVarName(str) {
|
121 | if (typeof str !== 'string') {
|
122 | return false;
|
123 | }
|
124 | if (str.trim() !== str) {
|
125 | return false;
|
126 | }
|
127 | try {
|
128 |
|
129 | new Function(str, 'var ' + str);
|
130 | }
|
131 | catch (e) {
|
132 | return false;
|
133 | }
|
134 | return true;
|
135 | }
|
136 | exports.isVarName = isVarName;
|
137 | function findMethodName(expression) {
|
138 | let methodName;
|
139 | if (t.isIdentifier(expression) ||
|
140 | t.isJSXIdentifier(expression)) {
|
141 | methodName = expression.name;
|
142 | }
|
143 | else if (t.isStringLiteral(expression)) {
|
144 | methodName = expression.value;
|
145 | }
|
146 | else if (t.isMemberExpression(expression) &&
|
147 | t.isIdentifier(expression.property)) {
|
148 | const { code } = babel_generator_1.default(expression);
|
149 | const ids = code.split('.');
|
150 | if (ids[0] === 'this' && ids[1] === 'props' && ids[2]) {
|
151 | methodName = code.replace('this.props.', '');
|
152 | }
|
153 | else {
|
154 | methodName = expression.property.name;
|
155 | }
|
156 | }
|
157 | else if (t.isCallExpression(expression) &&
|
158 | t.isMemberExpression(expression.callee) &&
|
159 | t.isIdentifier(expression.callee.object)) {
|
160 | methodName = expression.callee.object.name;
|
161 | }
|
162 | else if (t.isCallExpression(expression) &&
|
163 | t.isMemberExpression(expression.callee) &&
|
164 | t.isMemberExpression(expression.callee.object) &&
|
165 | t.isIdentifier(expression.callee.property) &&
|
166 | expression.callee.property.name === 'bind' &&
|
167 | t.isIdentifier(expression.callee.object.property)) {
|
168 | methodName = expression.callee.object.property.name;
|
169 | }
|
170 | else {
|
171 | throw codeFrameError(expression.loc, '当 props 为事件时(props name 以 `on` 开头),只能传入一个 this 作用域下的函数。');
|
172 | }
|
173 | return methodName;
|
174 | }
|
175 | exports.findMethodName = findMethodName;
|
176 | function setParentCondition(jsx, expr, array = false) {
|
177 | const conditionExpr = jsx.findParent(p => p.isConditionalExpression());
|
178 | const logicExpr = jsx.findParent(p => p.isLogicalExpression({ operator: '&&' }));
|
179 | if (array) {
|
180 | const ifAttrSet = new Set([
|
181 | adapter_1.Adapter.if,
|
182 | adapter_1.Adapter.else
|
183 | ]);
|
184 | const logicalJSX = jsx.findParent(p => p.isJSXElement() && p.node.openingElement.attributes.some(a => t.isJSXIdentifier(a.name) && ifAttrSet.has(a.name.name)));
|
185 | if (logicalJSX) {
|
186 | const attr = logicalJSX.node.openingElement.attributes.find(a => ifAttrSet.has(a.name.name));
|
187 | if (attr) {
|
188 | if (attr.name.name === adapter_1.Adapter.else) {
|
189 | const prevElement = logicalJSX.getPrevSibling();
|
190 | if (prevElement && prevElement.isJSXElement()) {
|
191 | const attr = prevElement.node.openingElement.attributes.find(a => a.name.name === adapter_1.Adapter.if);
|
192 | if (attr && t.isJSXExpressionContainer(attr.value)) {
|
193 | expr = t.conditionalExpression(reverseBoolean(lodash_1.cloneDeep(attr.value.expression)), expr, t.arrayExpression());
|
194 | return expr;
|
195 | }
|
196 | }
|
197 | }
|
198 | else if (t.isJSXExpressionContainer(attr.value)) {
|
199 | expr = t.conditionalExpression(lodash_1.cloneDeep(attr.value.expression), expr, t.arrayExpression());
|
200 | return expr;
|
201 | }
|
202 | }
|
203 | }
|
204 | }
|
205 | if (conditionExpr && conditionExpr.isConditionalExpression()) {
|
206 | const consequent = conditionExpr.get('consequent');
|
207 | if (consequent === jsx || jsx.findParent(p => p === consequent)) {
|
208 | expr = t.conditionalExpression(lodash_1.cloneDeep(conditionExpr.get('test').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
|
209 | }
|
210 | }
|
211 | if (logicExpr && logicExpr.isLogicalExpression({ operator: '&&' })) {
|
212 | const consequent = logicExpr.get('right');
|
213 | if (consequent === jsx || jsx.findParent(p => p === consequent)) {
|
214 | expr = t.conditionalExpression(lodash_1.cloneDeep(logicExpr.get('left').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
|
215 | }
|
216 | }
|
217 | return expr;
|
218 | }
|
219 | exports.setParentCondition = setParentCondition;
|
220 | function generateAnonymousState(scope, expression, refIds, isLogical) {
|
221 | let variableName = `anonymousState_${scope.generateUid()}`;
|
222 | let statementParent = expression.getStatementParent();
|
223 | if (!statementParent) {
|
224 | throw codeFrameError(expression.node.loc, '无法生成匿名 State,尝试先把值赋到一个变量上再把变量调换。');
|
225 | }
|
226 | const jsx = isLogical ? expression : expression.findParent(p => p.isJSXElement());
|
227 | const callExpr = jsx.findParent(p => p.isCallExpression() && isArrayMapCallExpression(p));
|
228 | const ifExpr = jsx.findParent(p => p.isIfStatement());
|
229 | const blockStatement = jsx.findParent(p => p.isBlockStatement() && p.parentPath === ifExpr);
|
230 | const expr = setParentCondition(jsx, lodash_1.cloneDeep(expression.node));
|
231 | if (!callExpr) {
|
232 | refIds.add(t.identifier(variableName));
|
233 | statementParent.insertBefore(buildConstVariableDeclaration(variableName, expr));
|
234 | if (blockStatement && blockStatement.isBlockStatement()) {
|
235 | blockStatement.traverse({
|
236 | VariableDeclarator: (path) => {
|
237 | const { id, init } = path.node;
|
238 | const isArrowFunctionInJSX = path.findParent(p => p.isJSXAttribute() ||
|
239 | (p.isAssignmentExpression() && t.isMemberExpression(p.node.left) && t.isThisExpression(p.node.left.object)
|
240 | && t.isIdentifier(p.node.left.property) && p.node.left.property.name.startsWith('')));
|
241 | if (isArrowFunctionInJSX) {
|
242 | return;
|
243 | }
|
244 |
|
245 | if (t.isIdentifier(id) && !id.name.startsWith(constant_1.LOOP_STATE) && !id.name.startsWith('_$') && init != null) {
|
246 | const newId = scope.generateDeclaredUidIdentifier('$' + id.name);
|
247 | refIds.forEach((refId) => {
|
248 | if (refId.name === variableName && !variableName.startsWith('_$')) {
|
249 | refIds.delete(refId);
|
250 | }
|
251 | });
|
252 | variableName = newId.name;
|
253 | if (adapter_1.Adapter.type === "quickapp" && variableName.startsWith('_$')) {
|
254 | const newVarName = variableName.slice(2);
|
255 | scope.rename(variableName, newVarName);
|
256 | variableName = newVarName;
|
257 | }
|
258 | refIds.add(t.identifier(variableName));
|
259 | blockStatement.scope.rename(id.name, newId.name);
|
260 | path.parentPath.replaceWith(template('ID = INIT;')({ ID: newId, INIT: init }));
|
261 | }
|
262 | }
|
263 | });
|
264 | }
|
265 | }
|
266 | else {
|
267 | variableName = `${constant_1.LOOP_STATE}_${callExpr.scope.generateUid()}`;
|
268 | const func = callExpr.node.arguments[0];
|
269 | if (t.isArrowFunctionExpression(func)) {
|
270 | if (!t.isBlockStatement(func.body)) {
|
271 | func.body = t.blockStatement([
|
272 | buildConstVariableDeclaration(variableName, expr),
|
273 | t.returnStatement(func.body)
|
274 | ]);
|
275 | }
|
276 | else {
|
277 | if (ifExpr && ifExpr.isIfStatement() && ifExpr.findParent(p => p === callExpr)) {
|
278 | const consequent = ifExpr.get('consequent');
|
279 | const test = ifExpr.get('test');
|
280 | if (consequent.isBlockStatement()) {
|
281 | if (jsx === test || jsx.findParent(p => p === test)) {
|
282 | func.body.body.unshift(buildConstVariableDeclaration(variableName, expr));
|
283 | }
|
284 | else {
|
285 | func.body.body.unshift(t.variableDeclaration('let', [t.variableDeclarator(t.identifier(variableName), t.nullLiteral())]));
|
286 | consequent.node.body.push(t.expressionStatement(t.assignmentExpression('=', t.identifier(variableName), expr)));
|
287 | }
|
288 | }
|
289 | else {
|
290 | throw codeFrameError(consequent.node, 'if 表达式的结果必须由一个花括号包裹');
|
291 | }
|
292 | }
|
293 | else {
|
294 | func.body.body.splice(func.body.body.length - 1, 0, buildConstVariableDeclaration(variableName, expr));
|
295 | }
|
296 | }
|
297 | }
|
298 | }
|
299 | const id = t.identifier(variableName);
|
300 | expression.replaceWith(id);
|
301 | return id;
|
302 | }
|
303 | exports.generateAnonymousState = generateAnonymousState;
|
304 | function isArrayMapCallExpression(callExpression) {
|
305 | return callExpression &&
|
306 | t.isCallExpression(callExpression.node) &&
|
307 | t.isMemberExpression(callExpression.node.callee) &&
|
308 | t.isIdentifier(callExpression.node.callee.property, { name: 'map' });
|
309 | }
|
310 | exports.isArrayMapCallExpression = isArrayMapCallExpression;
|
311 | function buildConstVariableDeclaration(variableName, expresion) {
|
312 | return t.variableDeclaration('const', [
|
313 | t.variableDeclarator(t.identifier(variableName), expresion)
|
314 | ]);
|
315 | }
|
316 | exports.buildConstVariableDeclaration = buildConstVariableDeclaration;
|
317 | function setTemplate(name, path, templates) {
|
318 | const parentPath = path.parentPath;
|
319 | const jsxChildren = parentPath.findParent(p => p.isJSXElement());
|
320 | if (name && !jsxChildren) {
|
321 | templates.set(name, path.node);
|
322 | }
|
323 | }
|
324 | exports.setTemplate = setTemplate;
|
325 | function isContainFunction(p) {
|
326 | let bool = false;
|
327 | p.traverse({
|
328 | CallExpression() {
|
329 | bool = true;
|
330 | }
|
331 | });
|
332 | return bool;
|
333 | }
|
334 | exports.isContainFunction = isContainFunction;
|
335 | function slash(input) {
|
336 | const isExtendedLengthPath = /^\\\\\?\\/.test(input);
|
337 | const hasNonAscii = /[^\u0000-\u0080]+/.test(input);
|
338 | const hasChinese = /[^\u4e00-\u9fa5]+/.test(input);
|
339 | if (isExtendedLengthPath || (hasNonAscii && !hasChinese)) {
|
340 | return input;
|
341 | }
|
342 | return input.replace(/\\/g, '/');
|
343 | }
|
344 | function pathResolver(source, location) {
|
345 | const extName = path.extname(source);
|
346 | const promotedPath = source;
|
347 | if (!['js', 'tsx'].includes(extName)) {
|
348 | try {
|
349 | const pathExist = fs.existsSync(path.resolve(path.dirname(location), source, 'index.js'));
|
350 | const tsxPathExist = fs.existsSync(path.resolve(path.dirname(location), source, 'index.tsx'));
|
351 | if (pathExist || tsxPathExist) {
|
352 | let p = path.join(promotedPath, 'index');
|
353 | if (!p.startsWith('.')) {
|
354 | p = './' + p;
|
355 | }
|
356 | return slash(p);
|
357 | }
|
358 | return slash(promotedPath);
|
359 | }
|
360 | catch (error) {
|
361 | return slash(promotedPath);
|
362 | }
|
363 | }
|
364 | return slash(promotedPath.split('.').slice(0, -1).join('.'));
|
365 | }
|
366 | exports.pathResolver = pathResolver;
|
367 | exports.setting = {
|
368 | sourceCode: ''
|
369 | };
|
370 | function codeFrameError(node, msg) {
|
371 | let errMsg = '';
|
372 | try {
|
373 | errMsg = code_frame_1.codeFrameColumns(exports.setting.sourceCode, node && node.type && node.loc ? node.loc : node, {
|
374 | highlightCode: true
|
375 | });
|
376 | }
|
377 | catch (error) {
|
378 | errMsg = 'failed to locate source';
|
379 | }
|
380 | return new Error(`${msg}
|
381 | -----
|
382 | ${errMsg}`);
|
383 | }
|
384 | exports.codeFrameError = codeFrameError;
|
385 | function createUUID() {
|
386 | return '$' + 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
387 | let r = Math.random() * 16 | 0;
|
388 | let v = c === 'x' ? r : (r & 0x3 | 0x8);
|
389 | return v.toString(16);
|
390 | }).replace(/-/g, '').slice(0, 8);
|
391 | }
|
392 | exports.createUUID = createUUID;
|
393 | let count = 0;
|
394 | function createRandomLetters(n) {
|
395 | const countStr = (count++).toString();
|
396 | let letters = '';
|
397 | for (const s of countStr) {
|
398 | letters += String.fromCharCode(97 + parseInt(s, 10));
|
399 | }
|
400 | const padding = n - letters.length;
|
401 | for (let i = 0; i < padding; i++) {
|
402 | letters += 'z';
|
403 | }
|
404 | return letters;
|
405 | }
|
406 | exports.createRandomLetters = createRandomLetters;
|
407 | function isBlockIfStatement(ifStatement, blockStatement) {
|
408 | return ifStatement && blockStatement &&
|
409 | ifStatement.isIfStatement() &&
|
410 | blockStatement.isBlockStatement();
|
411 | }
|
412 | exports.isBlockIfStatement = isBlockIfStatement;
|
413 | function buildCodeFrame(code) {
|
414 | return (loc) => code_frame_1.codeFrameColumns(code, loc);
|
415 | }
|
416 | exports.buildCodeFrame = buildCodeFrame;
|
417 | function isNumeric(n) {
|
418 | return !isNaN(parseFloat(n)) && isFinite(n);
|
419 | }
|
420 | exports.isNumeric = isNumeric;
|
421 | function buildJSXAttr(name, value) {
|
422 | return t.jSXAttribute(t.jSXIdentifier(name), t.jSXExpressionContainer(value));
|
423 | }
|
424 | exports.buildJSXAttr = buildJSXAttr;
|
425 | function newJSXIfAttr(jsx, value, path) {
|
426 | const element = jsx.openingElement;
|
427 | if (!t.isJSXIdentifier(element.name)) {
|
428 | return;
|
429 | }
|
430 | if (element.name.name === 'Block' || element.name.name === 'block' || !path) {
|
431 | const attrs = element.attributes;
|
432 | if (!attrs.some(a => a.name.name === adapter_1.Adapter.for)) {
|
433 | element.attributes.push(buildJSXAttr(adapter_1.Adapter.if, value));
|
434 | }
|
435 | else if (path) {
|
436 | const block = jsx_1.buildBlockElement();
|
437 | newJSXIfAttr(block, value);
|
438 | block.children.push(jsx);
|
439 | path.node = block;
|
440 | }
|
441 | }
|
442 | else {
|
443 | const block = jsx_1.buildBlockElement();
|
444 | newJSXIfAttr(block, value);
|
445 | block.children.push(jsx);
|
446 | path.node = block;
|
447 | }
|
448 | }
|
449 | exports.newJSXIfAttr = newJSXIfAttr;
|
450 | function getSlotName(name) {
|
451 | return name.slice(6).toLowerCase();
|
452 | }
|
453 | exports.getSlotName = getSlotName;
|
454 | function isContainJSXElement(path) {
|
455 | let matched = false;
|
456 | path.traverse({
|
457 | JSXElement(p) {
|
458 | matched = true;
|
459 | p.stop();
|
460 | }
|
461 | });
|
462 | return matched;
|
463 | }
|
464 | exports.isContainJSXElement = isContainJSXElement;
|
465 | function hasComplexExpression(path) {
|
466 | let matched = false;
|
467 | if (isContainJSXElement(path)) {
|
468 | return false;
|
469 | }
|
470 | if (path.isObjectExpression()) {
|
471 | return true;
|
472 | }
|
473 | if (path.isTemplateLiteral() || path.isCallExpression()) {
|
474 | return true;
|
475 | }
|
476 | if (path.isArrayExpression()) {
|
477 | const { elements } = path.node;
|
478 | if (elements.some(el => t.isObjectExpression(el) || t.isArrayExpression(el))) {
|
479 | return true;
|
480 | }
|
481 | }
|
482 | path.traverse({
|
483 | CallExpression: (p) => {
|
484 | matched = true;
|
485 | p.stop();
|
486 | },
|
487 | TemplateLiteral(p) {
|
488 | matched = true;
|
489 | p.stop();
|
490 | },
|
491 | ObjectExpression(p) {
|
492 | matched = true;
|
493 | p.stop();
|
494 | },
|
495 | ArrayExpression(p) {
|
496 | const { elements } = p.node;
|
497 | if (elements.some(el => t.isObjectExpression(el))) {
|
498 | return true;
|
499 | }
|
500 | },
|
501 | TaggedTemplateExpression(p) {
|
502 | matched = true;
|
503 | p.stop();
|
504 | },
|
505 | MemberExpression(path) {
|
506 | const jsxElement = path.findParent(p => p.isJSXExpressionContainer());
|
507 | const object = path.get('object');
|
508 | const property = path.get('property');
|
509 | const parentPath = path.parentPath;
|
510 | if (jsxElement &&
|
511 | object.isThisExpression() &&
|
512 | property.isIdentifier({ name: 'state' }) &&
|
513 | parentPath.isMemberExpression() &&
|
514 | parentPath.parentPath.isMemberExpression()) {
|
515 | const sourceCode = parentPath.parentPath.getSource();
|
516 | if (sourceCode.includes('[') && sourceCode.includes(']')) {
|
517 | matched = true;
|
518 | path.stop();
|
519 | }
|
520 | }
|
521 | }
|
522 | });
|
523 | return matched;
|
524 | }
|
525 | exports.hasComplexExpression = hasComplexExpression;
|
526 | function findFirstIdentifierFromMemberExpression(node, member) {
|
527 | let id;
|
528 | let object = node.object;
|
529 | while (true) {
|
530 | if (t.identifier(object) && !t.isMemberExpression(object)) {
|
531 | id = object;
|
532 | if (member) {
|
533 | object = member;
|
534 | }
|
535 | break;
|
536 | }
|
537 | object = object.object;
|
538 | }
|
539 | return id;
|
540 | }
|
541 | exports.findFirstIdentifierFromMemberExpression = findFirstIdentifierFromMemberExpression;
|
542 | function getArgumentName(arg) {
|
543 | if (t.isThisExpression(arg)) {
|
544 | return 'this';
|
545 | }
|
546 | else if (t.isNullLiteral(arg)) {
|
547 | return 'null';
|
548 | }
|
549 | else if (t.isStringLiteral(arg) || t.isNumericLiteral(arg)) {
|
550 | return arg.value;
|
551 | }
|
552 | else if (t.isIdentifier(arg)) {
|
553 | return arg.name;
|
554 | }
|
555 | else {
|
556 | return babel_generator_1.default(arg).code;
|
557 | }
|
558 | throw new Error(`bind 不支持传入该参数: ${arg}`);
|
559 | }
|
560 | exports.getArgumentName = getArgumentName;
|
561 | function isAllLiteral(...args) {
|
562 | return args.every(p => t.isLiteral(p));
|
563 | }
|
564 | exports.isAllLiteral = isAllLiteral;
|
565 | function reverseBoolean(expression) {
|
566 | return t.unaryExpression('!', expression);
|
567 | }
|
568 | exports.reverseBoolean = reverseBoolean;
|
569 | function isEmptyDeclarator(node) {
|
570 | if (t.isVariableDeclarator(node) &&
|
571 |
|
572 | (node.init === null ||
|
573 | t.isNullLiteral(node.init))) {
|
574 | return true;
|
575 | }
|
576 | return false;
|
577 | }
|
578 | exports.isEmptyDeclarator = isEmptyDeclarator;
|
579 | function toLetters(num) {
|
580 | let mod = num % 26;
|
581 | let pow = num / 26 | 0;
|
582 | let out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
|
583 | const letter = pow ? toLetters(pow) + out : out;
|
584 | return letter.toLowerCase();
|
585 | }
|
586 | exports.toLetters = toLetters;
|
587 | function findIdentifierFromStatement(statement) {
|
588 | if (t.isVariableDeclaration(statement)) {
|
589 | const declarator = statement.declarations.find(s => t.isIdentifier(s.id));
|
590 | if (declarator && t.isIdentifier(declarator.id)) {
|
591 | return declarator.id.name;
|
592 | }
|
593 | }
|
594 | return '__return';
|
595 | }
|
596 | exports.findIdentifierFromStatement = findIdentifierFromStatement;
|
597 | let id = 0;
|
598 | function genCompid() {
|
599 | return String(id++);
|
600 | }
|
601 | exports.genCompid = genCompid;
|
602 | function findParentLoops(callee, names, loops) {
|
603 | let indexId = null;
|
604 | let name;
|
605 | const [func] = callee.node.arguments;
|
606 | if (t.isFunctionExpression(func) || t.isArrowFunctionExpression(func)) {
|
607 | const params = func.params;
|
608 | indexId = params[1];
|
609 | name = names.get(callee);
|
610 | }
|
611 | if (indexId === null || !t.isIdentifier(indexId)) {
|
612 | indexId = t.identifier(callee.scope.generateUid('anonIdx'));
|
613 | func.params = [func.params[0], indexId];
|
614 | }
|
615 | if (!name) {
|
616 | throw codeFrameError(callee.node, '找不到循环对应的名称');
|
617 | }
|
618 | loops.elements.unshift(t.objectExpression([
|
619 | t.objectProperty(t.identifier('indexId'), indexId),
|
620 | t.objectProperty(t.identifier('name'), t.stringLiteral(name))
|
621 | ]));
|
622 | const parentCallExpr = callee.findParent(p => p.isCallExpression());
|
623 | if (parentCallExpr && parentCallExpr.isCallExpression()) {
|
624 | const callee = parentCallExpr.node.callee;
|
625 | if (t.isMemberExpression(callee) &&
|
626 | t.isIdentifier(callee.property) &&
|
627 | callee.property.name === 'map') {
|
628 | findParentLoops(parentCallExpr, names, loops);
|
629 | }
|
630 | }
|
631 | }
|
632 | exports.findParentLoops = findParentLoops;
|
633 | function setAncestorCondition(jsx, expr) {
|
634 | const ifAttrSet = new Set([
|
635 | adapter_1.Adapter.if,
|
636 | adapter_1.Adapter.else
|
637 | ]);
|
638 | const logicalJSX = jsx.findParent(p => p.isJSXElement() && p.node.openingElement.attributes.some(a => t.isJSXIdentifier(a.name) && ifAttrSet.has(a.name.name)));
|
639 | if (logicalJSX) {
|
640 | const attr = logicalJSX.node.openingElement.attributes.find(a => ifAttrSet.has(a.name.name));
|
641 | if (attr) {
|
642 | if (attr.name.name === adapter_1.Adapter.else) {
|
643 | const prevElement = logicalJSX.getPrevSibling();
|
644 | if (prevElement && prevElement.isJSXElement()) {
|
645 | const attr = prevElement.node.openingElement.attributes.find(a => a.name.name === adapter_1.Adapter.if);
|
646 | if (attr && t.isJSXExpressionContainer(attr.value)) {
|
647 | const condition = reverseBoolean(lodash_1.cloneDeep(attr.value.expression));
|
648 | expr = t.logicalExpression('&&', setAncestorCondition(logicalJSX, condition), expr);
|
649 | }
|
650 | }
|
651 | }
|
652 | else if (t.isJSXExpressionContainer(attr.value)) {
|
653 | const condition = lodash_1.cloneDeep(attr.value.expression);
|
654 | if (t.isJSXIdentifier(condition, { name: constant_1.IS_TARO_READY })) {
|
655 | return expr;
|
656 | }
|
657 | const ifStem = logicalJSX.findParent(p => p.isIfStatement());
|
658 | expr = t.logicalExpression('&&', setAncestorCondition(logicalJSX, ifStem && ifStem.isIfStatement() ? attr.value.expression : condition), expr);
|
659 | }
|
660 | }
|
661 | }
|
662 | return expr;
|
663 | }
|
664 | exports.setAncestorCondition = setAncestorCondition;
|
665 |
|
\ | No newline at end of file |