1 | 'use strict';
|
2 |
|
3 | const PLUS_CODE = 43;
|
4 | const MINUS_CODE = 45;
|
5 |
|
6 | const plugin = {
|
7 | name: 'assignment',
|
8 |
|
9 | assignmentOperators: new Set([
|
10 | '=',
|
11 | '*=',
|
12 | '**=',
|
13 | '/=',
|
14 | '%=',
|
15 | '+=',
|
16 | '-=',
|
17 | '<<=',
|
18 | '>>=',
|
19 | '>>>=',
|
20 | '&=',
|
21 | '^=',
|
22 | '|=',
|
23 | ]),
|
24 | updateOperators: [PLUS_CODE, MINUS_CODE],
|
25 | assignmentPrecedence: 0.9,
|
26 |
|
27 | init(jsep) {
|
28 | const updateNodeTypes = [jsep.IDENTIFIER, jsep.MEMBER_EXP];
|
29 | plugin.assignmentOperators.forEach(op => jsep.addBinaryOp(op, plugin.assignmentPrecedence, true));
|
30 |
|
31 | jsep.hooks.add('gobble-token', function gobbleUpdatePrefix(env) {
|
32 | const code = this.code;
|
33 | if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {
|
34 | this.index += 2;
|
35 | env.node = {
|
36 | type: 'UpdateExpression',
|
37 | operator: code === PLUS_CODE ? '++' : '--',
|
38 | argument: this.gobbleTokenProperty(this.gobbleIdentifier()),
|
39 | prefix: true,
|
40 | };
|
41 | if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) {
|
42 | this.throwError(`Unexpected ${env.node.operator}`);
|
43 | }
|
44 | }
|
45 | });
|
46 |
|
47 | jsep.hooks.add('after-token', function gobbleUpdatePostfix(env) {
|
48 | if (env.node) {
|
49 | const code = this.code;
|
50 | if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {
|
51 | if (!updateNodeTypes.includes(env.node.type)) {
|
52 | this.throwError(`Unexpected ${env.node.operator}`);
|
53 | }
|
54 | this.index += 2;
|
55 | env.node = {
|
56 | type: 'UpdateExpression',
|
57 | operator: code === PLUS_CODE ? '++' : '--',
|
58 | argument: env.node,
|
59 | prefix: false,
|
60 | };
|
61 | }
|
62 | }
|
63 | });
|
64 |
|
65 | jsep.hooks.add('after-expression', function gobbleAssignment(env) {
|
66 | if (env.node) {
|
67 |
|
68 |
|
69 |
|
70 | updateBinariesToAssignments(env.node);
|
71 | }
|
72 | });
|
73 |
|
74 | function updateBinariesToAssignments(node) {
|
75 | if (plugin.assignmentOperators.has(node.operator)) {
|
76 | node.type = 'AssignmentExpression';
|
77 | updateBinariesToAssignments(node.left);
|
78 | updateBinariesToAssignments(node.right);
|
79 | }
|
80 | else if (!node.operator) {
|
81 | Object.values(node).forEach((val) => {
|
82 | if (val && typeof val === 'object') {
|
83 | updateBinariesToAssignments(val);
|
84 | }
|
85 | });
|
86 | }
|
87 | }
|
88 | },
|
89 | };
|
90 |
|
91 | module.exports = plugin;
|
92 |
|