1 | "use strict";
|
2 |
|
3 | const utils = require("./utils.js");
|
4 | const Visitor = require("./visitor.js");
|
5 |
|
6 | class AssignmentVisitor extends Visitor {
|
7 | reset(rootPath, options) {
|
8 | this.exportedLocalNames = options.exportedLocalNames;
|
9 | this.magicString = options.magicString;
|
10 | this.modifyAST = !! options.modifyAST;
|
11 | this.moduleAlias = options.moduleAlias;
|
12 |
|
13 | if (this.exportedLocalNames === void 0) {
|
14 | this.exportedLocalNames = Object.create(null);
|
15 | }
|
16 |
|
17 | if (this.magicString === void 0) {
|
18 | this.magicString = null;
|
19 | }
|
20 |
|
21 | if (this.magicString) {
|
22 | const identifiers = Object.keys(this.exportedLocalNames);
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | identifiers.push("eval");
|
28 |
|
29 |
|
30 |
|
31 | this.possibleIndexes = utils.findLikelyIndexes(
|
32 | this.magicString.original,
|
33 | identifiers
|
34 | );
|
35 | }
|
36 | }
|
37 |
|
38 | visitAssignmentExpression(path) {
|
39 | return assignmentHelper(this, path, "left");
|
40 | }
|
41 |
|
42 | visitCallExpression(path) {
|
43 | const callee = path.getValue().callee;
|
44 |
|
45 | if (callee.type === "MemberExpression" &&
|
46 | isId(callee.object, this.moduleAlias) &&
|
47 | isId(callee.property, "runSetters")) {
|
48 |
|
49 | return false;
|
50 | }
|
51 |
|
52 | this.visitChildren(path);
|
53 |
|
54 | if (isId(callee, "eval")) {
|
55 | wrap(this, path);
|
56 | }
|
57 | }
|
58 |
|
59 | visitUpdateExpression(path) {
|
60 | return assignmentHelper(this, path, "argument");
|
61 | }
|
62 | };
|
63 |
|
64 | function isId(node, name) {
|
65 | if (!node || node.type !== "Identifier") {
|
66 | return false;
|
67 | }
|
68 |
|
69 | if (name) {
|
70 | return node.name === name;
|
71 | }
|
72 |
|
73 | return true;
|
74 | }
|
75 |
|
76 | function assignmentHelper(visitor, path, childName) {
|
77 | visitor.visitChildren(path);
|
78 |
|
79 | const child = path.getValue()[childName];
|
80 | const assignedNames = utils.getNamesFromPattern(child);
|
81 | const nameCount = assignedNames.length;
|
82 |
|
83 |
|
84 | for (let i = 0; i < nameCount; ++i) {
|
85 | if (visitor.exportedLocalNames[assignedNames[i]] === true) {
|
86 | wrap(visitor, path);
|
87 | break;
|
88 | }
|
89 | }
|
90 | }
|
91 |
|
92 | function wrap(visitor, path) {
|
93 | const value = path.getValue();
|
94 |
|
95 | if (visitor.magicString !== null) {
|
96 | visitor.magicString.prependRight(
|
97 | value.start,
|
98 | visitor.moduleAlias + ".runSetters("
|
99 | ).appendLeft(value.end, ")");
|
100 | }
|
101 |
|
102 | if (visitor.modifyAST) {
|
103 | path.replace({
|
104 | type: "CallExpression",
|
105 | callee: {
|
106 | type: "MemberExpression",
|
107 | object: {
|
108 | type: "Identifier",
|
109 | name: visitor.moduleAlias,
|
110 | },
|
111 | property: {
|
112 | type: "Identifier",
|
113 | name: "runSetters"
|
114 | }
|
115 | },
|
116 | arguments: [value]
|
117 | });
|
118 | }
|
119 | }
|
120 |
|
121 | module.exports = AssignmentVisitor;
|