Skip to content

Commit a472eb1

Browse files
authored
Merge pull request #1 from meteor/fix/check-scope-when-wrapping
Check scope before wrapping assignment benjamn#326
2 parents 367582a + d4ba96f commit a472eb1

File tree

23 files changed

+157
-4064
lines changed

23 files changed

+157
-4064
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
*.log
33
test/.cache
44
test/**/*.gz
5-
node_modules
5+
/node_modules
6+
.reify-cache
7+
.idea

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# re&middot;i&middot;fy <sub>_verb, transitive_</sub> &nbsp; [![Build Status](https://github.com/benjamn/reify/actions/workflows/node.js.yml/badge.svg)](https://github.com/benjamn/reify/actions/workflows/node.js.yml)
1+
# re&middot;i&middot;fy <sub>_verb, transitive_</sub> &nbsp; [![Build Status](https://github.com/meteor/reify/actions/workflows/node.js.yml/badge.svg)](https://github.com/meteor/reify/actions/workflows/node.js.yml)
22

33
**re&middot;i&middot;fied** <sub>past</sub> &nbsp; **re&middot;i&middot;fies** <sub>present</sub> &nbsp; **re&middot;i&middot;fy&middot;ing** <sub>participle</sub> &nbsp; **re&middot;i&middot;fi&middot;ca&middot;tion** <sub>noun</sub> &nbsp; **re&middot;i&middot;fi&middot;er** <sub>noun</sub>
44

@@ -10,17 +10,17 @@
1010
Usage
1111
---
1212

13-
1. Run `npm install --save reify` in your package or app directory. The
13+
1. Run `npm install --save @meteorjs/reify` in your package or app directory. The
1414
`--save` is important because reification only applies to modules in
15-
packages that explicitly depend on the `reify` package.
16-
2. Call `require("reify")` before importing modules that contain `import`
15+
packages that explicitly depend on the `@meteorjs/reify` package.
16+
2. Call `require("@meteorjs/reify")` before importing modules that contain `import`
1717
and `export` declarations.
1818

19-
You can also easily `reify` the Node REPL:
19+
You can also easily `@meteorjs/reify` the Node REPL:
2020

2121
```sh
2222
% node
23-
> require("reify")
23+
> require("@meteorjs/reify")
2424
{}
2525
> import { strictEqual } from "assert"
2626
> strictEqual(2 + 2, 5)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
require("reify/node");
1+
require("@meteorjs/reify/node");
22
module.exports = require("./module.js");

examples/babel-parser-example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"node": ">=4"
2525
},
2626
"dependencies": {
27-
"reify": "^0.18.1"
27+
"@meteorjs/reify": "0.23.0-beta.0"
2828
},
2929
"reify": {
3030
"parser": "reify/lib/parsers/babel.js"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
require("reify/node");
1+
require("@meteorjs/reify/node");
22
module.exports = require("./module.js");

examples/custom-cache-example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"node": ">=4"
2525
},
2626
"dependencies": {
27-
"reify": "^0.5.1"
27+
"@meteorjs/reify": "0.23.0-beta.0"
2828
},
2929
"reify": {
3030
"cache-directory": ".reify-custom-cache"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
require("reify/node");
1+
require("@meteorjs/reify/node");
22
module.exports = require("./module.js");

examples/top-level-example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"node": ">=4"
2525
},
2626
"dependencies": {
27-
"reify": "^0.5.1"
27+
"@meteorjs/reify": "0.23.0-beta.0"
2828
},
2929
"reify": {
3030
"parser": "reify/lib/parsers/top-level.js"

lib/assignment-visitor.js

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,26 +80,59 @@ function assignmentHelper(visitor, path, childName) {
8080
const assignedNames = utils.getNamesFromPattern(child);
8181
const nameCount = assignedNames.length;
8282

83-
// Wrap assignments to exported identifiers with `module.runSetters`.
83+
let scope = null;
84+
function inModuleScope(name) {
85+
if (scope === null) {
86+
scope = path.getScope();
87+
}
88+
89+
return !scope || scope.find_owner(name).parent === null;
90+
}
91+
92+
let modifiedExports = [];
93+
94+
// Identify which exports if any are modified by the assignment.
8495
for (let i = 0; i < nameCount; ++i) {
85-
if (visitor.exportedLocalNames[assignedNames[i]] === true) {
86-
wrap(visitor, path);
87-
break;
96+
let name = assignedNames[i];
97+
if (
98+
visitor.exportedLocalNames[name] &&
99+
inModuleScope(name)
100+
) {
101+
modifiedExports.push(...visitor.exportedLocalNames[name]);
88102
}
89103
}
104+
105+
// Wrap assignments to exported identifiers with `module.runSetters`.
106+
if (modifiedExports.length > 0) {
107+
wrap(visitor, path, modifiedExports);
108+
}
90109
}
91110

92-
function wrap(visitor, path) {
111+
function wrap(visitor, path, names) {
93112
const value = path.getValue();
94113

95114
if (visitor.magicString !== null) {
115+
let end = ')';
116+
if (names) {
117+
end = `,[${names.map(n => `"${n}"`).join(',')}])`;
118+
}
119+
96120
visitor.magicString.prependRight(
97121
value.start,
98122
visitor.moduleAlias + ".runSetters("
99-
).appendLeft(value.end, ")");
123+
).appendLeft(value.end, end);
100124
}
101125

102126
if (visitor.modifyAST) {
127+
let args = [value];
128+
if (names) {
129+
let array = {
130+
type: "ArrayExpression",
131+
elements: names.map(n => ({ type: "StringLiteral", value: n }))
132+
};
133+
args.push(array);
134+
}
135+
103136
path.replace({
104137
type: "CallExpression",
105138
callee: {
@@ -113,7 +146,7 @@ function wrap(visitor, path) {
113146
name: "runSetters"
114147
}
115148
},
116-
arguments: [value]
149+
arguments: args
117150
});
118151
}
119152
}

lib/fast-path.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
const assert = require("assert");
77
const utils = require("./utils.js");
8+
const periscopic = require('periscopic');
89
const brandKey = "reify-fast-path";
910
const brand = typeof Symbol === "function"
1011
? Symbol.for(brandKey)
@@ -15,6 +16,7 @@ class FastPath {
1516
assert.notStrictEqual(ast, null);
1617
assert.strictEqual(typeof ast, "object");
1718
this.stack = [ast];
19+
this._scope = null;
1820
}
1921

2022
static isInstance(value) {
@@ -102,6 +104,21 @@ class FastPath {
102104
return getStackAt(this, 1);
103105
}
104106

107+
getScope() {
108+
if (!this._scope) {
109+
this._scope = periscopic.analyze(this.stack[0]);
110+
}
111+
112+
let node;
113+
let pos = 0;
114+
while (node = getNodeAt(this, pos++)) {
115+
let scope = this._scope.map.get(node);
116+
if (scope) {
117+
return scope;
118+
}
119+
}
120+
}
121+
105122
replace(newValue) {
106123
const s = this.stack;
107124
const len = s.length;

0 commit comments

Comments
 (0)