Skip to content

Commit d212da8

Browse files
authored
fix(analyze): ignore conmments for imports detection (#155)
1 parent c29618f commit d212da8

File tree

2 files changed

+66
-28
lines changed

2 files changed

+66
-28
lines changed

src/analyze.ts

+33-25
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,17 @@ const EXPORT_DEFAULT_RE = /\bexport\s+default\s+/g;
8484
const TYPE_RE = /^\s*?type\s/;
8585

8686
export function findStaticImports(code: string): StaticImport[] {
87-
return matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" });
87+
return _filterStatement(
88+
_tryGetLocations(code, "import"),
89+
matchAll(ESM_STATIC_IMPORT_RE, code, { type: "static" }),
90+
);
8891
}
8992

9093
export function findDynamicImports(code: string): DynamicImport[] {
91-
return matchAll(DYNAMIC_IMPORT_RE, code, { type: "dynamic" });
94+
return _filterStatement(
95+
_tryGetLocations(code, "import"),
96+
matchAll(DYNAMIC_IMPORT_RE, code, { type: "dynamic" }),
97+
);
9298
}
9399

94100
export function findTypeImports(code: string): TypeImport[] {
@@ -217,17 +223,14 @@ export function findExports(code: string): ESMExport[] {
217223
if (exports.length === 0) {
218224
return [];
219225
}
220-
const exportLocations = _tryGetExportLocations(code);
226+
const exportLocations = _tryGetLocations(code, "export");
221227
if (exportLocations && exportLocations.length === 0) {
222228
return [];
223229
}
224230

225231
return (
226-
exports
227-
// Filter false positive export matches
228-
.filter(
229-
(exp) => !exportLocations || _isExportStatement(exportLocations, exp),
230-
)
232+
// Filter false positive export matches
233+
_filterStatement(exportLocations, exports)
231234
// Prevent multiple exports of same function, only keep latest iteration of signatures
232235
.filter((exp, index, exports) => {
233236
const nextExport = exports[index + 1];
@@ -266,17 +269,14 @@ export function findTypeExports(code: string): ESMExport[] {
266269
if (exports.length === 0) {
267270
return [];
268271
}
269-
const exportLocations = _tryGetExportLocations(code);
272+
const exportLocations = _tryGetLocations(code, "export");
270273
if (exportLocations && exportLocations.length === 0) {
271274
return [];
272275
}
273276

274277
return (
275-
exports
276-
// Filter false positive export matches
277-
.filter(
278-
(exp) => !exportLocations || _isExportStatement(exportLocations, exp),
279-
)
278+
// Filter false positive export matches
279+
_filterStatement(exportLocations, exports)
280280
// Prevent multiple exports of same function, only keep latest iteration of signatures
281281
.filter((exp, index, exports) => {
282282
const nextExport = exports[index + 1];
@@ -359,23 +359,31 @@ interface TokenLocation {
359359
end: number;
360360
}
361361

362-
function _isExportStatement(exportsLocation: TokenLocation[], exp: ESMExport) {
363-
return exportsLocation.some((location) => {
364-
// AST token inside the regex match
365-
return exp.start <= location.start && exp.end >= location.end;
366-
// AST Token start or end is within the regex match
367-
// return (exp.start <= location.start && location.start <= exp.end) ||
368-
// (exp.start <= location.end && location.end <= exp.end)
362+
function _filterStatement<T extends TokenLocation>(
363+
locations: TokenLocation[] | undefined,
364+
statements: T[],
365+
): T[] {
366+
return statements.filter((exp) => {
367+
return (
368+
!locations ||
369+
locations.some((location) => {
370+
// AST token inside the regex match
371+
return exp.start <= location.start && exp.end >= location.end;
372+
// AST Token start or end is within the regex match
373+
// return (exp.start <= location.start && location.start <= exp.end) ||
374+
// (exp.start <= location.end && location.end <= exp.end)
375+
})
376+
);
369377
});
370378
}
371379

372-
function _tryGetExportLocations(code: string) {
380+
function _tryGetLocations(code: string, label: string) {
373381
try {
374-
return _getExportLocations(code);
382+
return _getLocations(code, label);
375383
} catch {}
376384
}
377385

378-
function _getExportLocations(code: string) {
386+
function _getLocations(code: string, label: string) {
379387
const tokens = tokenizer(code, {
380388
ecmaVersion: "latest",
381389
sourceType: "module",
@@ -385,7 +393,7 @@ function _getExportLocations(code: string) {
385393
});
386394
const locations: TokenLocation[] = [];
387395
for (const token of tokens) {
388-
if (token.type.label === "export") {
396+
if (token.type.label === label) {
389397
locations.push({
390398
start: token.start,
391399
end: token.end,

test/imports.test.ts

+33-3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,32 @@ staticTests['import { foo, type Foo } from "foo"'] = {
136136
namedImports: { foo: "foo" },
137137
};
138138

139+
staticTests[
140+
`
141+
// import { foo } from "foo"
142+
import { too } from "too"
143+
144+
/**
145+
* import { zoo } from "zoo"
146+
*/
147+
148+
const start = '/*'
149+
import { ioo } from "ioo"
150+
const end = '*/'
151+
`
152+
] = [
153+
{
154+
specifier: "too",
155+
type: "static",
156+
namedImports: { too: "too" },
157+
},
158+
{
159+
specifier: "ioo",
160+
type: "static",
161+
namedImports: { ioo: "ioo" },
162+
},
163+
];
164+
139165
// -- Dynamic import --
140166
const dynamicTests = {
141167
'const { test, /* here */, another, } = await import ( "module-name" );': {
@@ -153,6 +179,8 @@ const dynamicTests = {
153179
'import("abc").then(r => r.default)': {
154180
expression: '"abc"',
155181
},
182+
'// import("abc").then(r => r.default)': [],
183+
'/* import("abc").then(r => r.default) */': [],
156184
};
157185

158186
const TypeTests = {
@@ -237,10 +265,12 @@ describe("findDynamicImports", () => {
237265
for (const [input, test] of Object.entries(dynamicTests)) {
238266
it(input.replace(/\n/g, "\\n"), () => {
239267
const matches = findDynamicImports(input);
240-
expect(matches.length).to.equal(1);
268+
expect(matches.length).to.equal(Array.isArray(test) ? test.length : 1);
241269
const match = matches[0];
242-
expect(match.type).to.equal("dynamic");
243-
expect(match.expression.trim()).to.equal(test.expression);
270+
if (match) {
271+
expect(match.type).to.equal("dynamic");
272+
expect(match.expression.trim()).to.equal(test.expression);
273+
}
244274
});
245275
}
246276
});

0 commit comments

Comments
 (0)