Skip to content

Commit

Permalink
Add support for constructor call specifiers (first: new URL)
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed Sep 13, 2023
1 parent a51a77c commit 8cb1072
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 0 deletions.
Empty file.
Empty file.
15 changes: 15 additions & 0 deletions fixtures/imports-constructor-call/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// import.meta.url: URL in browsers, file: protocol in Node.js etc.

// new URL('./exists.js');
new URL('https://example.org/url1.js');
new URL('file1.js', import.meta.url);
new URL('./file2.js', import.meta.url);
new URL('file3.js', 'https://example.org');
const baseUrl = 'https://example.org';
new URL('/', baseUrl);
new URL(baseUrl);

// TODO Implement?
new Worker('worker1.js');
new Worker(new URL('worker2.js', import.meta.url));
new Worker('./worker3.js');
3 changes: 3 additions & 0 deletions fixtures/imports-constructor-call/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "imports-constructor-call"
}
Empty file.
4 changes: 4 additions & 0 deletions src/typescript/ast-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export function isPropertyAccessCall(node: ts.Node, identifier: string): node is
);
}

export function isConstructorCall(node: ts.Node, identifier: string): node is ts.CallExpression {
return ts.isNewExpression(node) && node.expression.getText() === identifier;
}

export function getAccessExpressionName(node: ts.PropertyAccessExpression | ts.ElementAccessExpression) {
return 'argumentExpression' in node ? stripQuotes(node.argumentExpression.getText()) : node.name.getText();
}
Expand Down
21 changes: 21 additions & 0 deletions src/typescript/visitors/imports/constructorCall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ts from 'typescript';
import { isConstructorCall } from '../../ast-helpers.js';
import { importVisitor as visit } from '../index.js';

export default visit(
() => true,
node => {
// Pattern: new URL('specifier', import.meta.url)
if (isConstructorCall(node, 'URL')) {
if (
node.arguments.length === 2 &&
ts.isStringLiteralLike(node.arguments[0]) &&
ts.isPropertyAccessExpression(node.arguments[1]) &&
node.arguments[1].getText() === 'import.meta.url'
) {
const specifier = node.arguments[0].text;
if (specifier) return { specifier };
}
}
}
);
2 changes: 2 additions & 0 deletions src/typescript/visitors/imports/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ts from 'typescript';
import constructorCall from './constructorCall.js';
import importCall from './importCall.js';
import importDeclaration from './importDeclaration.js';
import importEqualsDeclaration from './importEqualsDeclaration.js';
Expand All @@ -8,6 +9,7 @@ import reExportDeclaration from './reExportDeclaration.js';
import requireCall from './requireCall.js';

const visitors = [
constructorCall,
importCall,
importDeclaration,
importEqualsDeclaration,
Expand Down
21 changes: 21 additions & 0 deletions tests/imports-constructor-call.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { main } from '../src/index.js';
import { resolve } from '../src/util/path.js';
import baseArguments from './helpers/baseArguments.js';
import baseCounters from './helpers/baseCounters.js';

const cwd = resolve('fixtures/imports-constructor-call');

test('Support various constructor calls', async () => {
const { counters } = await main({
...baseArguments,
cwd,
});

assert.deepEqual(counters, {
...baseCounters,
processed: 4,
total: 4,
});
});

0 comments on commit 8cb1072

Please sign in to comment.