@dcloudio/uni-mp-compiler 0.0.1-nvue3.3030820220125001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +202 -0
  2. package/dist/ast.d.ts +16 -0
  3. package/dist/ast.js +91 -0
  4. package/dist/codegen.d.ts +14 -0
  5. package/dist/codegen.js +322 -0
  6. package/dist/compile.d.ts +13 -0
  7. package/dist/compile.js +108 -0
  8. package/dist/decodeHtml.d.ts +2 -0
  9. package/dist/decodeHtml.js +131 -0
  10. package/dist/errors.d.ts +16 -0
  11. package/dist/errors.js +19 -0
  12. package/dist/identifier.d.ts +7 -0
  13. package/dist/identifier.js +35 -0
  14. package/dist/index.d.ts +12 -0
  15. package/dist/index.js +40 -0
  16. package/dist/namedChars.json +2233 -0
  17. package/dist/options.d.ts +88 -0
  18. package/dist/options.js +2 -0
  19. package/dist/parserOptions.d.ts +7 -0
  20. package/dist/parserOptions.js +63 -0
  21. package/dist/runtimeHelpers.d.ts +13 -0
  22. package/dist/runtimeHelpers.js +32 -0
  23. package/dist/template/codegen.d.ts +19 -0
  24. package/dist/template/codegen.js +381 -0
  25. package/dist/transform.d.ts +73 -0
  26. package/dist/transform.js +518 -0
  27. package/dist/transforms/transformClass.d.ts +5 -0
  28. package/dist/transforms/transformClass.js +162 -0
  29. package/dist/transforms/transformComponent.d.ts +11 -0
  30. package/dist/transforms/transformComponent.js +179 -0
  31. package/dist/transforms/transformElement.d.ts +9 -0
  32. package/dist/transforms/transformElement.js +191 -0
  33. package/dist/transforms/transformExpression.d.ts +5 -0
  34. package/dist/transforms/transformExpression.js +283 -0
  35. package/dist/transforms/transformIdentifier.d.ts +2 -0
  36. package/dist/transforms/transformIdentifier.js +95 -0
  37. package/dist/transforms/transformKey.d.ts +4 -0
  38. package/dist/transforms/transformKey.js +18 -0
  39. package/dist/transforms/transformRef.d.ts +3 -0
  40. package/dist/transforms/transformRef.js +126 -0
  41. package/dist/transforms/transformRoot.d.ts +2 -0
  42. package/dist/transforms/transformRoot.js +42 -0
  43. package/dist/transforms/transformSlot.d.ts +3 -0
  44. package/dist/transforms/transformSlot.js +144 -0
  45. package/dist/transforms/transformStyle.d.ts +5 -0
  46. package/dist/transforms/transformStyle.js +156 -0
  47. package/dist/transforms/transformTag.d.ts +2 -0
  48. package/dist/transforms/transformTag.js +15 -0
  49. package/dist/transforms/utils.d.ts +25 -0
  50. package/dist/transforms/utils.js +133 -0
  51. package/dist/transforms/vBind.d.ts +2 -0
  52. package/dist/transforms/vBind.js +49 -0
  53. package/dist/transforms/vFor.d.ts +35 -0
  54. package/dist/transforms/vFor.js +299 -0
  55. package/dist/transforms/vHtml.d.ts +2 -0
  56. package/dist/transforms/vHtml.js +35 -0
  57. package/dist/transforms/vIf.d.ts +13 -0
  58. package/dist/transforms/vIf.js +139 -0
  59. package/dist/transforms/vModel.d.ts +2 -0
  60. package/dist/transforms/vModel.js +178 -0
  61. package/dist/transforms/vOn.d.ts +8 -0
  62. package/dist/transforms/vOn.js +166 -0
  63. package/dist/transforms/vSlot.d.ts +16 -0
  64. package/dist/transforms/vSlot.js +274 -0
  65. package/package.json +36 -0
@@ -0,0 +1,518 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createStructuralDirectiveTransform = exports.createTransformContext = exports.traverseChildren = exports.traverseNode = exports.transform = exports.isScopedSlotVFor = exports.isVForScope = exports.isVIfScope = exports.isRootScope = void 0;
7
+ const shared_1 = require("@vue/shared");
8
+ const types_1 = require("@babel/types");
9
+ const compiler_core_1 = require("@vue/compiler-core");
10
+ const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
11
+ const identifier_1 = __importDefault(require("./identifier"));
12
+ const runtimeHelpers_1 = require("./runtimeHelpers");
13
+ const ast_1 = require("./ast");
14
+ const utils_1 = require("./transforms/utils");
15
+ const codegen_1 = require("./codegen");
16
+ function isRootScope(scope) {
17
+ return !isVIfScope(scope) && !isVForScope(scope);
18
+ }
19
+ exports.isRootScope = isRootScope;
20
+ function isVIfScope(scope) {
21
+ return (!!scope.condition ||
22
+ scope.name === 'else');
23
+ }
24
+ exports.isVIfScope = isVIfScope;
25
+ function isVForScope(scope) {
26
+ return !!scope.source;
27
+ }
28
+ exports.isVForScope = isVForScope;
29
+ function isScopedSlotVFor({ source }) {
30
+ if (source.type !== 8 /* COMPOUND_EXPRESSION */) {
31
+ return false;
32
+ }
33
+ const first = source.children[0];
34
+ return (first.type === 4 /* SIMPLE_EXPRESSION */ &&
35
+ first.content.includes(utils_1.SCOPED_SLOT_IDENTIFIER));
36
+ }
37
+ exports.isScopedSlotVFor = isScopedSlotVFor;
38
+ function transform(root, options) {
39
+ const context = createTransformContext(root, options);
40
+ traverseNode(root, context);
41
+ root.renderData = createRenderDataExpr(context.scope.properties, context);
42
+ // finalize meta information
43
+ root.helpers = [...context.helpers.keys()];
44
+ root.components = [...context.components];
45
+ root.imports = context.imports;
46
+ root.cached = context.cached;
47
+ return context;
48
+ }
49
+ exports.transform = transform;
50
+ function traverseNode(node, context) {
51
+ context.currentNode = node;
52
+ // apply transform plugins
53
+ const { nodeTransforms } = context;
54
+ const exitFns = [];
55
+ for (let i = 0; i < nodeTransforms.length; i++) {
56
+ const onExit = nodeTransforms[i](node, context);
57
+ if (onExit) {
58
+ if ((0, shared_1.isArray)(onExit)) {
59
+ exitFns.push(...onExit);
60
+ }
61
+ else {
62
+ exitFns.push(onExit);
63
+ }
64
+ }
65
+ if (!context.currentNode) {
66
+ // node was removed
67
+ return;
68
+ }
69
+ else {
70
+ // node may have been replaced
71
+ node = context.currentNode;
72
+ }
73
+ }
74
+ switch (node.type) {
75
+ case 3 /* COMMENT */:
76
+ // context.helper(CREATE_COMMENT)
77
+ break;
78
+ case 5 /* INTERPOLATION */:
79
+ context.helper(compiler_core_1.TO_DISPLAY_STRING);
80
+ break;
81
+ // for container types, further traverse downwards
82
+ case 9 /* IF */:
83
+ for (let i = 0; i < node.branches.length; i++) {
84
+ traverseNode(node.branches[i], context);
85
+ }
86
+ break;
87
+ case 10 /* IF_BRANCH */:
88
+ case 11 /* FOR */:
89
+ case 1 /* ELEMENT */:
90
+ case 0 /* ROOT */:
91
+ traverseChildren(node, context);
92
+ break;
93
+ }
94
+ // exit transforms
95
+ context.currentNode = node;
96
+ let i = exitFns.length;
97
+ while (i--) {
98
+ exitFns[i]();
99
+ }
100
+ }
101
+ exports.traverseNode = traverseNode;
102
+ function traverseChildren(parent, context) {
103
+ let i = 0;
104
+ const nodeRemoved = () => {
105
+ i--;
106
+ };
107
+ for (; i < parent.children.length; i++) {
108
+ const child = parent.children[i];
109
+ if ((0, shared_1.isString)(child))
110
+ continue;
111
+ context.parent = parent;
112
+ context.childIndex = i;
113
+ context.onNodeRemoved = nodeRemoved;
114
+ traverseNode(child, context);
115
+ }
116
+ }
117
+ exports.traverseChildren = traverseChildren;
118
+ function defaultOnError(error) {
119
+ throw error;
120
+ }
121
+ function defaultOnWarn(msg) {
122
+ console.warn(`[Vue warn] ${msg.message}`);
123
+ }
124
+ function createTransformContext(rootNode, { root = '', filename = '', isTS = false, inline = false, hashId = null, scopeId = null, filters = [], bindingCssVars = [], bindingMetadata = shared_1.EMPTY_OBJ, cacheHandlers = false, prefixIdentifiers = false, skipTransformIdentifier = false, renderDataSpread = false, nodeTransforms = [], directiveTransforms = {}, miniProgram = {
125
+ class: {
126
+ array: true,
127
+ },
128
+ slot: {
129
+ fallbackContent: false,
130
+ dynamicSlotNames: true,
131
+ },
132
+ directive: '',
133
+ }, isBuiltInComponent = shared_1.NOOP, isCustomElement = shared_1.NOOP, expressionPlugins = [], onError = defaultOnError, onWarn = defaultOnWarn, }) {
134
+ var _a;
135
+ const rootScope = {
136
+ id: new identifier_1.default(),
137
+ identifiers: [],
138
+ properties: [],
139
+ parent: null,
140
+ };
141
+ function findVIfParentScope() {
142
+ for (let i = scopes.length - 1; i >= 0; i--) {
143
+ const scope = scopes[i];
144
+ if (isVForScope(scope) || isRootScope(scope)) {
145
+ return scope;
146
+ }
147
+ }
148
+ return rootScope;
149
+ }
150
+ function createScope(id, initScope) {
151
+ return (0, shared_1.extend)({
152
+ id,
153
+ properties: [],
154
+ parent: scopes[scopes.length - 1],
155
+ get identifiers() {
156
+ return Object.keys(identifiers);
157
+ },
158
+ }, initScope);
159
+ }
160
+ const vueIds = [];
161
+ const identifiers = Object.create(null);
162
+ const scopes = [rootScope];
163
+ const miniProgramComponents = (0, uni_cli_shared_1.findMiniProgramUsingComponents)({
164
+ filename,
165
+ componentsDir: (_a = miniProgram.component) === null || _a === void 0 ? void 0 : _a.dir,
166
+ inputDir: root,
167
+ });
168
+ // const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
169
+ const context = {
170
+ // options
171
+ // 暂不提供根据文件名生成递归组件
172
+ selfName: '',
173
+ miniProgram,
174
+ isTS,
175
+ inline,
176
+ hashId,
177
+ scopeId,
178
+ filters,
179
+ bindingCssVars,
180
+ bindingMetadata,
181
+ cacheHandlers,
182
+ prefixIdentifiers,
183
+ nodeTransforms,
184
+ directiveTransforms,
185
+ expressionPlugins,
186
+ skipTransformIdentifier,
187
+ renderDataSpread,
188
+ isBuiltInComponent,
189
+ isCustomElement,
190
+ onError,
191
+ onWarn,
192
+ // state
193
+ parent: null,
194
+ childIndex: 0,
195
+ helpers: new Map(),
196
+ components: new Set(),
197
+ imports: [],
198
+ bindingComponents: Object.create(null),
199
+ cached: 0,
200
+ identifiers,
201
+ scope: rootScope,
202
+ scopes: {
203
+ vFor: 0,
204
+ vueId: 0,
205
+ },
206
+ get currentScope() {
207
+ return scopes[scopes.length - 1];
208
+ },
209
+ currentNode: rootNode,
210
+ vueIds,
211
+ get currentVueId() {
212
+ return vueIds[vueIds.length - 1];
213
+ },
214
+ inVOnce: false,
215
+ get inVFor() {
216
+ let parent = scopes[scopes.length - 1];
217
+ while (parent) {
218
+ if (isVForScope(parent) && !isScopedSlotVFor(parent)) {
219
+ return true;
220
+ }
221
+ parent = parent.parent;
222
+ }
223
+ return false;
224
+ },
225
+ // methods
226
+ getScopeIndex(scope) {
227
+ return scopes.indexOf(scope);
228
+ },
229
+ popScope() {
230
+ return scopes.pop();
231
+ },
232
+ addVIfScope(initScope) {
233
+ const vIfScope = createScope(scopes[scopes.length - 1].id, (0, shared_1.extend)(initScope, { parentScope: findVIfParentScope() }));
234
+ scopes.push(vIfScope);
235
+ return vIfScope;
236
+ },
237
+ addVForScope(initScope) {
238
+ const vForScope = createScope(new identifier_1.default(), initScope);
239
+ scopes.push(vForScope);
240
+ return vForScope;
241
+ },
242
+ helper(name) {
243
+ const count = context.helpers.get(name) || 0;
244
+ context.helpers.set(name, count + 1);
245
+ return name;
246
+ },
247
+ removeHelper(name) {
248
+ const count = context.helpers.get(name);
249
+ if (count) {
250
+ const currentCount = count - 1;
251
+ if (!currentCount) {
252
+ context.helpers.delete(name);
253
+ }
254
+ else {
255
+ context.helpers.set(name, currentCount);
256
+ }
257
+ }
258
+ },
259
+ helperString(name) {
260
+ return `_${compiler_core_1.helperNameMap[context.helper(name)]}`;
261
+ },
262
+ replaceNode(node) {
263
+ context.parent.children[context.childIndex] = context.currentNode = node;
264
+ },
265
+ removeNode(node) {
266
+ if (!context.parent) {
267
+ throw new Error(`Cannot remove root node.`);
268
+ }
269
+ const list = context.parent.children;
270
+ const removalIndex = node
271
+ ? list.indexOf(node)
272
+ : context.currentNode
273
+ ? context.childIndex
274
+ : -1;
275
+ /* istanbul ignore if */
276
+ if (removalIndex < 0) {
277
+ throw new Error(`node being removed is not a child of current parent`);
278
+ }
279
+ if (!node || node === context.currentNode) {
280
+ // current node removed
281
+ context.currentNode = null;
282
+ context.onNodeRemoved();
283
+ }
284
+ else {
285
+ // sibling node removed
286
+ if (context.childIndex > removalIndex) {
287
+ context.childIndex--;
288
+ context.onNodeRemoved();
289
+ }
290
+ }
291
+ context.parent.children.splice(removalIndex, 1);
292
+ },
293
+ onNodeRemoved: () => { },
294
+ addIdentifiers(exp) {
295
+ if ((0, shared_1.isString)(exp)) {
296
+ addId(exp);
297
+ }
298
+ else if (exp.identifiers) {
299
+ exp.identifiers.forEach(addId);
300
+ }
301
+ else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
302
+ addId(exp.content);
303
+ }
304
+ },
305
+ removeIdentifiers(exp) {
306
+ if ((0, shared_1.isString)(exp)) {
307
+ removeId(exp);
308
+ }
309
+ else if (exp.identifiers) {
310
+ exp.identifiers.forEach(removeId);
311
+ }
312
+ else if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
313
+ removeId(exp.content);
314
+ }
315
+ },
316
+ cache(exp, isVNode = false) {
317
+ return createCacheExpression(context.cached++, exp, isVNode);
318
+ },
319
+ isMiniProgramComponent(name) {
320
+ return miniProgramComponents.includes(name);
321
+ },
322
+ };
323
+ function addId(id) {
324
+ const { identifiers } = context;
325
+ if (identifiers[id] === undefined) {
326
+ identifiers[id] = 0;
327
+ }
328
+ identifiers[id]++;
329
+ }
330
+ function removeId(id) {
331
+ context.identifiers[id]--;
332
+ }
333
+ return context;
334
+ }
335
+ exports.createTransformContext = createTransformContext;
336
+ function createCacheExpression(index, value, isVNode = false) {
337
+ return {
338
+ type: 20 /* JS_CACHE_EXPRESSION */,
339
+ index,
340
+ value,
341
+ isVNode,
342
+ loc: compiler_core_1.locStub,
343
+ };
344
+ }
345
+ function createStructuralDirectiveTransform(name, fn) {
346
+ const matches = (0, shared_1.isString)(name)
347
+ ? (n) => n === name
348
+ : (n) => name.test(n);
349
+ return (node, context) => {
350
+ if (node.type === 1 /* ELEMENT */) {
351
+ const { props } = node;
352
+ // structural directive transforms are not concerned with slots
353
+ // as they are handled separately in vSlot.ts
354
+ // if (node.tagType === ElementTypes.TEMPLATE && props.some(isVSlot)) {
355
+ // return
356
+ // }
357
+ const exitFns = [];
358
+ for (let i = 0; i < props.length; i++) {
359
+ const prop = props[i];
360
+ if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
361
+ // structural directives are removed to avoid infinite recursion
362
+ // also we remove them *before* applying so that it can further
363
+ // traverse itself in case it moves the node around
364
+ props.splice(i, 1);
365
+ i--;
366
+ const onExit = fn(node, prop, context);
367
+ if (onExit)
368
+ exitFns.push(onExit);
369
+ }
370
+ }
371
+ return exitFns;
372
+ }
373
+ };
374
+ }
375
+ exports.createStructuralDirectiveTransform = createStructuralDirectiveTransform;
376
+ function createRenderDataExpr(properties, context) {
377
+ const objExpr = (0, ast_1.createObjectExpression)(properties);
378
+ if (!hasSpreadElement(objExpr)) {
379
+ return objExpr;
380
+ }
381
+ // filters: ['test']
382
+ // v-if="text.aa()"
383
+ if (context.filters.length) {
384
+ transformFilterObjectSpreadExpr(objExpr, context);
385
+ }
386
+ if (context.renderDataSpread) {
387
+ return objExpr;
388
+ }
389
+ return transformObjectSpreadExpr(objExpr, context);
390
+ }
391
+ function hasSpreadElement(expr) {
392
+ return expr.properties.some((prop) => {
393
+ if ((0, types_1.isSpreadElement)(prop)) {
394
+ return true;
395
+ }
396
+ else {
397
+ const returnStatement = parseReturnStatement(prop);
398
+ if (returnStatement) {
399
+ return hasSpreadElement(returnStatement.argument);
400
+ }
401
+ }
402
+ });
403
+ }
404
+ // 目前硬编码识别 _f,应该读取 context.helperString
405
+ const returnObjExprMap = {
406
+ _f: 1,
407
+ _w: 0, // _w(()=>{return {}})
408
+ };
409
+ function parseReturnStatement(prop) {
410
+ if ((0, types_1.isObjectProperty)(prop) &&
411
+ (0, types_1.isCallExpression)(prop.value) &&
412
+ (0, types_1.isIdentifier)(prop.value.callee)) {
413
+ const { name } = prop.value.callee;
414
+ if ((0, shared_1.hasOwn)(returnObjExprMap, name)) {
415
+ return prop.value.arguments[returnObjExprMap[name]].body.body[0];
416
+ }
417
+ }
418
+ }
419
+ function transformObjectPropertyExpr(prop, context) {
420
+ // vFor,withScopedSlot
421
+ const returnStatement = parseReturnStatement(prop);
422
+ if (returnStatement) {
423
+ const objExpr = returnStatement.argument;
424
+ if (hasSpreadElement(objExpr)) {
425
+ returnStatement.argument = transformObjectSpreadExpr(objExpr, context);
426
+ }
427
+ }
428
+ return prop;
429
+ }
430
+ function transformObjectSpreadExpr(objExpr, context) {
431
+ const properties = objExpr.properties;
432
+ const args = [];
433
+ let objExprProperties = [];
434
+ properties.forEach((prop) => {
435
+ if ((0, types_1.isObjectProperty)(prop)) {
436
+ objExprProperties.push(transformObjectPropertyExpr(prop, context));
437
+ }
438
+ else {
439
+ if (objExprProperties.length) {
440
+ args.push((0, types_1.objectExpression)(objExprProperties));
441
+ }
442
+ args.push(transformConditionalExpression(prop.argument, context));
443
+ objExprProperties = [];
444
+ }
445
+ });
446
+ if (objExprProperties.length) {
447
+ args.push((0, types_1.objectExpression)(objExprProperties));
448
+ }
449
+ if (args.length === 1) {
450
+ return args[0];
451
+ }
452
+ return (0, types_1.callExpression)((0, types_1.identifier)(context.helperString(runtimeHelpers_1.EXTEND)), args);
453
+ }
454
+ function transformConditionalExpression(expr, context) {
455
+ const { consequent, alternate } = expr;
456
+ if ((0, types_1.isObjectExpression)(consequent) && hasSpreadElement(consequent)) {
457
+ expr.consequent = transformObjectSpreadExpr(consequent, context);
458
+ }
459
+ if ((0, types_1.isObjectExpression)(alternate)) {
460
+ if (hasSpreadElement(alternate)) {
461
+ expr.alternate = transformObjectSpreadExpr(alternate, context);
462
+ }
463
+ }
464
+ else if ((0, types_1.isConditionalExpression)(alternate)) {
465
+ transformConditionalExpression(alternate, context);
466
+ }
467
+ return expr;
468
+ }
469
+ function transformFilterObjectSpreadExpr(objExpr, context) {
470
+ const properties = objExpr.properties;
471
+ properties.forEach((prop) => {
472
+ if ((0, types_1.isObjectProperty)(prop)) {
473
+ transformFilterObjectPropertyExpr(prop, context);
474
+ }
475
+ else {
476
+ prop.argument = transformFilterConditionalExpression(prop.argument, context);
477
+ }
478
+ });
479
+ }
480
+ function transformFilterObjectPropertyExpr(prop, context) {
481
+ // vFor, withScopedSlot
482
+ const returnStatement = parseReturnStatement(prop);
483
+ if (returnStatement) {
484
+ const objExpr = returnStatement.argument;
485
+ if (hasSpreadElement(objExpr)) {
486
+ transformFilterObjectSpreadExpr(objExpr, context);
487
+ }
488
+ }
489
+ }
490
+ function transformFilterConditionalExpression(expr, context) {
491
+ const { test, consequent, alternate } = expr;
492
+ if ((0, types_1.isObjectExpression)(consequent) && hasSpreadElement(consequent)) {
493
+ transformFilterObjectSpreadExpr(consequent, context);
494
+ }
495
+ if ((0, types_1.isObjectExpression)(alternate)) {
496
+ if (hasSpreadElement(alternate)) {
497
+ transformFilterObjectSpreadExpr(alternate, context);
498
+ }
499
+ }
500
+ else if ((0, types_1.isConditionalExpression)(alternate)) {
501
+ expr.alternate = transformFilterConditionalExpression(alternate, context);
502
+ }
503
+ const testCode = (0, codegen_1.genBabelExpr)(test);
504
+ // filter test
505
+ if (context.filters.find((filter) => testCode.includes(filter + '.'))) {
506
+ // test.aa() ? {a:1} : {b:2} => {...{a:1},...{b:2}}
507
+ const properties = [];
508
+ if (!(0, types_1.isObjectExpression)(consequent) || consequent.properties.length) {
509
+ properties.push((0, types_1.spreadElement)(consequent));
510
+ }
511
+ if (!(0, types_1.isObjectExpression)(expr.alternate) ||
512
+ expr.alternate.properties.length) {
513
+ properties.push((0, types_1.spreadElement)(expr.alternate));
514
+ }
515
+ return (0, types_1.objectExpression)(properties);
516
+ }
517
+ return expr;
518
+ }
@@ -0,0 +1,5 @@
1
+ import { DirectiveNode, AttributeNode } from '@vue/compiler-core';
2
+ import { TransformContext } from '../transform';
3
+ export declare function isClassBinding({ arg }: DirectiveNode): boolean | undefined;
4
+ export declare function findStaticClassIndex(props: (AttributeNode | DirectiveNode)[]): number;
5
+ export declare function rewriteClass(index: number, classBindingProp: DirectiveNode, props: (AttributeNode | DirectiveNode)[], context: TransformContext): void;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rewriteClass = exports.findStaticClassIndex = exports.isClassBinding = void 0;
4
+ const types_1 = require("@babel/types");
5
+ const compiler_core_1 = require("@vue/compiler-core");
6
+ const ast_1 = require("../ast");
7
+ const codegen_1 = require("../codegen");
8
+ const runtimeHelpers_1 = require("../runtimeHelpers");
9
+ const utils_1 = require("./utils");
10
+ function isClassBinding({ arg }) {
11
+ return (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && arg.content === 'class');
12
+ }
13
+ exports.isClassBinding = isClassBinding;
14
+ function findStaticClassIndex(props) {
15
+ return props.findIndex((prop) => prop.name === 'class');
16
+ }
17
+ exports.findStaticClassIndex = findStaticClassIndex;
18
+ function rewriteClass(index, classBindingProp, props, context) {
19
+ if (!classBindingProp.exp) {
20
+ return;
21
+ }
22
+ const expr = (0, ast_1.parseExpr)(classBindingProp.exp, context);
23
+ if (!expr) {
24
+ return;
25
+ }
26
+ let classBindingExpr = expr;
27
+ if ((0, types_1.isObjectExpression)(expr)) {
28
+ classBindingExpr = createClassBindingByObjectExpression(rewriteClassObjectExpression(expr, classBindingProp.loc, context));
29
+ }
30
+ else if ((0, types_1.isArrayExpression)(expr)) {
31
+ classBindingExpr = createClassBindingByArrayExpression(rewriteClassArrayExpression(expr, context));
32
+ }
33
+ else {
34
+ classBindingExpr = (0, ast_1.parseExpr)(rewriteClassExpression(classBindingProp.exp, context).content, context);
35
+ }
36
+ const staticClassPropIndex = findStaticClassIndex(props);
37
+ if (staticClassPropIndex > -1) {
38
+ const staticClass = props[staticClassPropIndex].value
39
+ .content;
40
+ if (staticClass) {
41
+ if (!(0, types_1.isArrayExpression)(classBindingExpr)) {
42
+ classBindingExpr = (0, types_1.arrayExpression)([classBindingExpr]);
43
+ }
44
+ const staticClassLiterals = parseStaticClass(staticClass);
45
+ if (index > staticClassPropIndex) {
46
+ classBindingExpr.elements.unshift(...staticClassLiterals);
47
+ }
48
+ else {
49
+ classBindingExpr.elements.push(...staticClassLiterals);
50
+ }
51
+ }
52
+ }
53
+ if (!context.miniProgram.class.array) {
54
+ classBindingExpr = parseClassBindingArrayExpr(classBindingExpr);
55
+ }
56
+ classBindingProp.exp = (0, compiler_core_1.createSimpleExpression)((0, codegen_1.genBabelExpr)(classBindingExpr));
57
+ }
58
+ exports.rewriteClass = rewriteClass;
59
+ /**
60
+ * 目前 mp-toutiao, mp-alipay, mp-lark 不支持数组绑定class,故统一转换为字符串相加
61
+ * @param classBindingExpr
62
+ * @returns
63
+ */
64
+ function parseClassBindingArrayExpr(classBindingExpr) {
65
+ if (!(0, types_1.isArrayExpression)(classBindingExpr)) {
66
+ return classBindingExpr;
67
+ }
68
+ let binaryExpr;
69
+ classBindingExpr.elements.forEach((expr) => {
70
+ if ((0, types_1.isArrayExpression)(expr)) {
71
+ expr = parseClassBindingArrayExpr(expr);
72
+ }
73
+ if (!binaryExpr) {
74
+ binaryExpr = (0, types_1.parenthesizedExpression)(expr);
75
+ }
76
+ else {
77
+ binaryExpr = (0, types_1.binaryExpression)('+', (0, types_1.binaryExpression)('+', binaryExpr, (0, types_1.stringLiteral)(' ')), expr);
78
+ }
79
+ });
80
+ return binaryExpr;
81
+ }
82
+ function parseStaticClass(staticClass) {
83
+ // 已经在 parse 阶段格式化了多余空格等
84
+ return staticClass.split(' ').map((clazz) => (0, types_1.stringLiteral)(clazz));
85
+ }
86
+ function rewriteClassExpression(expr, context) {
87
+ return (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([
88
+ context.helperString(runtimeHelpers_1.NORMALIZE_CLASS) + '(',
89
+ expr,
90
+ ')',
91
+ ]), context);
92
+ }
93
+ function rewriteClassArrayExpression(expr, context) {
94
+ expr.elements.forEach((prop, index) => {
95
+ if (!(0, types_1.isStringLiteral)(prop)) {
96
+ const code = (0, codegen_1.genBabelExpr)((0, types_1.arrayExpression)([(0, types_1.isSpreadElement)(prop) ? prop.argument : prop]));
97
+ expr.elements[index] = (0, types_1.identifier)(rewriteClassExpression((0, compiler_core_1.createSimpleExpression)(code.slice(1, -1), false), context).content);
98
+ }
99
+ });
100
+ return expr;
101
+ }
102
+ function rewriteClassObjectExpression(expr, loc, context) {
103
+ expr.properties.forEach((prop, index) => {
104
+ if ((0, types_1.isSpreadElement)(prop)) {
105
+ // <view :class="{...obj}"/>
106
+ // <view class="{{[a]}}"/>
107
+ const newExpr = (0, utils_1.rewriteSpreadElement)(runtimeHelpers_1.NORMALIZE_CLASS, prop, loc, context);
108
+ if (newExpr) {
109
+ expr.properties[index] = (0, types_1.objectProperty)(newExpr, (0, types_1.booleanLiteral)(true), true);
110
+ }
111
+ }
112
+ else if ((0, types_1.isObjectProperty)(prop)) {
113
+ const { key, value, computed } = prop;
114
+ if (computed) {
115
+ // {[handle(computedKey)]:1} => {[a]:1}
116
+ prop.key = (0, utils_1.parseExprWithRewrite)((0, codegen_1.genBabelExpr)(key), loc, context, key);
117
+ }
118
+ if ((0, utils_1.isStaticLiteral)(value)) {
119
+ return;
120
+ }
121
+ else {
122
+ const newExpr = (0, utils_1.parseExprWithRewriteClass)((0, codegen_1.genBabelExpr)(value), loc, context, value);
123
+ if (newExpr) {
124
+ prop.value = newExpr;
125
+ }
126
+ }
127
+ }
128
+ });
129
+ return expr;
130
+ }
131
+ function createClassBindingByArrayExpression(expr) {
132
+ const elements = [];
133
+ expr.elements.forEach((prop) => {
134
+ if ((0, types_1.isStringLiteral)(prop) || (0, types_1.isIdentifier)(prop)) {
135
+ elements.push(prop);
136
+ }
137
+ });
138
+ return (0, types_1.arrayExpression)(elements);
139
+ }
140
+ function createClassBindingByObjectExpression(expr) {
141
+ const elements = [];
142
+ expr.properties.forEach((prop) => {
143
+ if ((0, types_1.isObjectProperty)(prop)) {
144
+ const { value } = prop;
145
+ if ((0, ast_1.isUndefined)(value)) {
146
+ // remove {a:undefined}
147
+ return;
148
+ }
149
+ if ((0, types_1.isLiteral)(value)) {
150
+ // {a:true,b:1,c:0} => ['a','b']
151
+ if ((0, ast_1.isTrueExpr)(value)) {
152
+ elements.push(prop.computed
153
+ ? prop.key
154
+ : (0, ast_1.parseStringLiteral)(prop.key));
155
+ }
156
+ return;
157
+ }
158
+ elements.push((0, types_1.logicalExpression)('&&', value, prop.computed ? prop.key : (0, ast_1.parseStringLiteral)(prop.key)));
159
+ }
160
+ });
161
+ return (0, types_1.arrayExpression)(elements);
162
+ }
@@ -0,0 +1,11 @@
1
+ import { ComponentNode, DirectiveNode, ElementNode } from '@vue/compiler-core';
2
+ import { NodeTransform, TransformContext } from '../transform';
3
+ export declare const transformComponent: NodeTransform;
4
+ /**
5
+ * 重写组件 props 绑定
6
+ * @param node
7
+ * @param context
8
+ */
9
+ export declare function rewriteBinding({ tag, props }: ComponentNode, context: TransformContext): void;
10
+ export declare function isPropsBinding({ arg }: DirectiveNode): boolean | undefined;
11
+ export declare function rewritePropsBinding(dir: DirectiveNode, node: ElementNode, context: TransformContext): void;