Skip to content

Commit 201a933

Browse files
leebyroncoreyfarrell
authored andcommitted
fix: Ensure correct scope references after traversal (#192)
* test: Add tests illustrating scope issue * fix: Re-crawl scope after traversal to fix references
1 parent 8e827c6 commit 201a933

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

fixtures/with-changed-scope.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { noop } from 'lodash'
2+
noop(noop() ? noop : noop)

package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@babel/core": "^7.2.2",
1919
"@babel/preset-env": "^7.2.3",
2020
"@babel/register": "^7.0.0",
21+
"babel-plugin-lodash": "^3.3.4",
2122
"chai": "^4.2.0",
2223
"coveralls": "^3.0.2",
2324
"cross-env": "^5.2.0",

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ function makeVisitor ({ types: t }) {
7070
inputSourceMap
7171
})
7272
this.__dv__.enter(path)
73+
// Istanbul visitor may replace Identifiers and require re-crawling
74+
// scope before continuing with other babel plugins.
75+
path.scope.crawl()
7376
},
7477
exit (path) {
7578
if (!this.__dv__) {

test/babel-plugin-istanbul.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,55 @@ describe('babel-plugin-istanbul', function () {
171171
resultAfter.code.should.match(/statementMap/)
172172
})
173173
})
174+
175+
describe('should leave scope with correct references', function () {
176+
it('leaves scope references as Identifiers', function () {
177+
// This is a unit test which inspects the root cause of the problem:
178+
// scope references that are replaced to no longer be Identifiers
179+
babel.transformFileSync('./fixtures/with-changed-scope.js', {
180+
babelrc: false,
181+
configFile: false,
182+
plugins: [
183+
[makeVisitor({ types: babel.types }), {
184+
include: ['fixtures/with-changed-scope.js']
185+
}],
186+
function testScope (t) {
187+
return {
188+
visitor: {
189+
ImportSpecifier (path) {
190+
const fileScope = path.hub.file.scope
191+
const localBinding = fileScope.getBinding(path.node.local.name)
192+
for (const localReference of localBinding.referencePaths) {
193+
localReference.type.should.equal('Identifier')
194+
}
195+
}
196+
}
197+
}
198+
}
199+
]
200+
})
201+
})
202+
203+
it('creates valid syntax with other transforming plugins', function () {
204+
// This is a minimal end-to-end test which illustrates how scope
205+
// reference alteration impacts the assumptions of other plugins
206+
const result = babel.transformFileSync(
207+
'./fixtures/with-changed-scope.js', {
208+
babelrc: false,
209+
configFile: false,
210+
plugins: [
211+
[makeVisitor({ types: babel.types }), {
212+
include: ['fixtures/with-changed-scope.js']
213+
}],
214+
'babel-plugin-lodash'
215+
]
216+
})
217+
218+
function testSyntaxError () {
219+
babel.parse(result.code)
220+
}
221+
222+
testSyntaxError.should.not.throw()
223+
})
224+
})
174225
})

0 commit comments

Comments
 (0)