@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.
- package/LICENSE +202 -0
- package/dist/ast.d.ts +16 -0
- package/dist/ast.js +91 -0
- package/dist/codegen.d.ts +14 -0
- package/dist/codegen.js +322 -0
- package/dist/compile.d.ts +13 -0
- package/dist/compile.js +108 -0
- package/dist/decodeHtml.d.ts +2 -0
- package/dist/decodeHtml.js +131 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +19 -0
- package/dist/identifier.d.ts +7 -0
- package/dist/identifier.js +35 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +40 -0
- package/dist/namedChars.json +2233 -0
- package/dist/options.d.ts +88 -0
- package/dist/options.js +2 -0
- package/dist/parserOptions.d.ts +7 -0
- package/dist/parserOptions.js +63 -0
- package/dist/runtimeHelpers.d.ts +13 -0
- package/dist/runtimeHelpers.js +32 -0
- package/dist/template/codegen.d.ts +19 -0
- package/dist/template/codegen.js +381 -0
- package/dist/transform.d.ts +73 -0
- package/dist/transform.js +518 -0
- package/dist/transforms/transformClass.d.ts +5 -0
- package/dist/transforms/transformClass.js +162 -0
- package/dist/transforms/transformComponent.d.ts +11 -0
- package/dist/transforms/transformComponent.js +179 -0
- package/dist/transforms/transformElement.d.ts +9 -0
- package/dist/transforms/transformElement.js +191 -0
- package/dist/transforms/transformExpression.d.ts +5 -0
- package/dist/transforms/transformExpression.js +283 -0
- package/dist/transforms/transformIdentifier.d.ts +2 -0
- package/dist/transforms/transformIdentifier.js +95 -0
- package/dist/transforms/transformKey.d.ts +4 -0
- package/dist/transforms/transformKey.js +18 -0
- package/dist/transforms/transformRef.d.ts +3 -0
- package/dist/transforms/transformRef.js +126 -0
- package/dist/transforms/transformRoot.d.ts +2 -0
- package/dist/transforms/transformRoot.js +42 -0
- package/dist/transforms/transformSlot.d.ts +3 -0
- package/dist/transforms/transformSlot.js +144 -0
- package/dist/transforms/transformStyle.d.ts +5 -0
- package/dist/transforms/transformStyle.js +156 -0
- package/dist/transforms/transformTag.d.ts +2 -0
- package/dist/transforms/transformTag.js +15 -0
- package/dist/transforms/utils.d.ts +25 -0
- package/dist/transforms/utils.js +133 -0
- package/dist/transforms/vBind.d.ts +2 -0
- package/dist/transforms/vBind.js +49 -0
- package/dist/transforms/vFor.d.ts +35 -0
- package/dist/transforms/vFor.js +299 -0
- package/dist/transforms/vHtml.d.ts +2 -0
- package/dist/transforms/vHtml.js +35 -0
- package/dist/transforms/vIf.d.ts +13 -0
- package/dist/transforms/vIf.js +139 -0
- package/dist/transforms/vModel.d.ts +2 -0
- package/dist/transforms/vModel.js +178 -0
- package/dist/transforms/vOn.d.ts +8 -0
- package/dist/transforms/vOn.js +166 -0
- package/dist/transforms/vSlot.d.ts +16 -0
- package/dist/transforms/vSlot.js +274 -0
- 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;
|