Skip to content

Commit d0367fa

Browse files
committed
[Fix] Ignore hashbang and BOM while parsing
ESLint does this outside their espree parser, so we need to do it as well. Just like ESLint, the code will convert hashbang to comments and strip off the BOM completely before handing the content to the parser.
1 parent 517fcb7 commit d0367fa

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 1;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/usr/bin/env node
2+
import {foo} from './hashbang-child.js';

tests/src/rules/no-unused-modules.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ describe('dynamic imports', () => {
307307
`,
308308
filename: testFilePath('./unused-modules-reexport-crash/src/index.tsx'),
309309
parser: parsers.TS_NEW,
310-
options: [{
310+
options: [{
311311
unusedExports: true,
312312
ignoreExports: ['**/magic/**'],
313313
}],
@@ -1302,3 +1302,21 @@ describe('support ES2022 Arbitrary module namespace identifier names', () => {
13021302
),
13031303
});
13041304
});
1305+
1306+
describe('parser ignores hashbang and BOM', () => {
1307+
ruleTester.run('no-unused-modules', rule, {
1308+
valid: [
1309+
test({
1310+
options: unusedExportsOptions,
1311+
code: 'export const foo = 1;\n',
1312+
filename: testFilePath('./no-unused-modules/hashbang-child.js'),
1313+
}),
1314+
test({
1315+
options: unusedExportsOptions,
1316+
code: `\uFEFF#!/usr/bin/env node\nimport {foo} from './hashbang-child.js';\n`,
1317+
filename: testFilePath('./no-unused-modules/hashbang-parent.js'),
1318+
}),
1319+
],
1320+
invalid: [],
1321+
});
1322+
});

utils/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
55

66
## Unreleased
77

8+
### Fixed
9+
- [Fix] Ignore hashbang and BOM while parsing ([#2431], thanks [@silverwind])
10+
811
## v2.7.3 - 2022-01-26
912

1013
### Fixed
@@ -115,6 +118,7 @@ Yanked due to critical issue with cache key resulting from #839.
115118
### Fixed
116119
- `unambiguous.test()` regex is now properly in multiline mode
117120

121+
[#2431]: https://github.com/import-js/eslint-plugin-import/pull/2431
118122
[#2350]: https://github.com/import-js/eslint-plugin-import/issues/2350
119123
[#2343]: https://github.com/import-js/eslint-plugin-import/pull/2343
120124
[#2261]: https://github.com/import-js/eslint-plugin-import/pull/2261

utils/parse.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ function makeParseReturn(ast, visitorKeys) {
4242
return ast;
4343
}
4444

45+
function stripUnicodeBOM(text) {
46+
return text.charCodeAt(0) === 0xFEFF ? text.slice(1) : text;
47+
}
48+
49+
function transformHashbang(text) {
50+
return text.replace(/^#!([^\r\n]+)/u, (_, captured) => `//${captured}`);
51+
}
52+
4553
exports.default = function parse(path, content, context) {
4654

4755
if (context == null) throw new Error('need context to parse properly');
@@ -78,6 +86,10 @@ exports.default = function parse(path, content, context) {
7886
// require the parser relative to the main module (i.e., ESLint)
7987
const parser = moduleRequire(parserPath);
8088

89+
// replicate bom strip and hashbang transform of ESLint
90+
// https://github.com/eslint/eslint/blob/b93af98b3c417225a027cabc964c38e779adb945/lib/linter/linter.js#L779
91+
content = transformHashbang(stripUnicodeBOM(String(content)));
92+
8193
if (typeof parser.parseForESLint === 'function') {
8294
let ast;
8395
try {

0 commit comments

Comments
 (0)