Skip to content

Commit

Permalink
Refactor dep graph (#626)
Browse files Browse the repository at this point in the history
  • Loading branch information
webpro committed May 10, 2024
1 parent 29a0bdc commit 004ae3b
Show file tree
Hide file tree
Showing 54 changed files with 346 additions and 95 deletions.
20 changes: 18 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
"noUnusedImports": "error"
},
"complexity": {
"useLiteralKeys": "off",
"useSimplifiedLogicExpression": "error"
"useLiteralKeys": "off"
},
"nursery": {
"noRestrictedImports": {
Expand Down Expand Up @@ -90,6 +89,23 @@
}
}
}
},
{
"include": ["packages/knip/fixtures"],
"organizeImports": {
"enabled": false
},
"linter": {
"rules": {
"correctness": {
"noUnusedVariables": "off",
"noUnusedImports": "off"
},
"style": {
"useImportType": "off"
}
}
}
}
]
}
5 changes: 5 additions & 0 deletions packages/knip/fixtures/class-members/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { MyClass } from './members';
import { AbstractClassGen, ExtendedClassGen } from './iterator-generator';
import { AbstractClass, ExtendedClass } from './iterator';

AbstractClassGen;
ExtendedClassGen;
AbstractClass;
ExtendedClass;

const instance = new MyClass();

export class Parent {
Expand Down
11 changes: 11 additions & 0 deletions packages/knip/fixtures/commonjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ const templateStringExternal = value => {
const templateStringInternal = value => {
const baz = require(`./dir/mod1`);
const { identifier } = require(`./dir/mod1`);

baz;
identifier;
};

const requireResolve = value => {
Expand All @@ -27,6 +30,7 @@ const requireResolve = value => {

const requireExportedShorthandsHeuristic = value => {
const { identifier9, identifier10 } = require('./dir/mod3');
[identifier9, identifier10];
};

const staticResolve = () => {
Expand All @@ -36,3 +40,10 @@ const staticResolve = () => {
const dynamicResolve = () => {
return require.resolve(path.join(process.cwd(), 'package.json'));
};

renamed;
defaultName;
named;
all;
staticResolve;
add;
1 change: 1 addition & 0 deletions packages/knip/fixtures/compilers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import identifier from './module.mdx';
identifier;
1 change: 1 addition & 0 deletions packages/knip/fixtures/custom-paths-workspaces/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import anything from '~/my-module';
anything;
2 changes: 2 additions & 0 deletions packages/knip/fixtures/custom-paths-workspaces/my-module.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import index from '@lib';
import fn from '@lib/fn';
index;
fn;
3 changes: 3 additions & 0 deletions packages/knip/fixtures/custom-paths-workspaces/ws/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import main from 'lib/main';
import lang from '#util-foo/lang';
import svg from '~images/logo.svg';
main;
lang;
svg;
1 change: 1 addition & 0 deletions packages/knip/fixtures/duplicate-exports-alias/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import { isAlias } from './helpers';
isAlias;
2 changes: 2 additions & 0 deletions packages/knip/fixtures/enum-members/members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ export enum MyEnum {
}

const myNumber: MyEnum.C_UsedInternal = 1;

type Used = EntryEnum;
14 changes: 14 additions & 0 deletions packages/knip/fixtures/exports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,24 @@ import {
} from './named-exports';
import type { MyNum, MyString, MyInterface } from './types';

num;
str;
functionName;
className;
generatorFunctionName;
name1;
name4;
exportedA;
exportedB;

type Used = MyNum | MyString | MyInterface;

const dynamic = await import('./dynamic-import');
dynamic;

async function main() {
const { used } = await import('./dynamic-import');
used;
}

export const entryFileExport = exportedResult;
Expand Down
9 changes: 9 additions & 0 deletions packages/knip/fixtures/exports/my-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import defaultNamedGenFn from './default-named-generator-function';
import _default from './default.js';
import * as MyNamespace from './my-namespace.js';

defaultArrowFn;
defaultClass;
defaultFn;
defaultGenFn;
defaultNamedClass;
defaultNamedFn;
defaultNamedGenFn;
_default;

const nsNumber = MyNamespace.nsNumber;
const nsFunction = MyNamespace.nsFunction;

Expand Down
1 change: 1 addition & 0 deletions packages/knip/fixtures/exports/odd.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import one = require('./export-is');
one;
3 changes: 3 additions & 0 deletions packages/knip/fixtures/import-equals/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ import * as NS from './my-module.js';
import local = require('./local.js');
import external = require('external');
import something = NS.something;
local;
external;
something;
22 changes: 22 additions & 0 deletions packages/knip/fixtures/imports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ async function main() {
import('./side-effects-call');
await import('./await-import-call');
const { default: defaultName, identifier11: renamedIdentifier, identifier12 } = await import('./object-bindings');

[defaultName, renamedIdentifier, identifier12];
}

const dynamicImport = (value: string) => {
Expand All @@ -42,6 +44,8 @@ function promiseAll() {
import('./import-a'),
import('./dir/import-b'),
]);

[identifierA, identifierB];
},
};
}
Expand Down Expand Up @@ -72,3 +76,21 @@ export default fn({
child3: import('./import-e'),
},
});

[
topLevel,
top,
dynamic,
defaultName1,
defaultName2,
defaultName3,
defaultName4,
defaultName5,
renamed,
renamed2,
renamed3,
renamedIdentifier,
renamedIdentifier2,
namedC,
identifier14,
];
3 changes: 2 additions & 1 deletion packages/knip/fixtures/include-entry-exports/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { y } from './mod';

y;
export default 1;

export type EntryType = {};
// biome-ignore lint/suspicious/noEmptyInterface: <explanation>
export interface EntryInterface {}
export enum EntryEnum {}
1 change: 1 addition & 0 deletions packages/knip/fixtures/pathless/src/dir/module-a.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import same from 'same';
same;

export default 1;
1 change: 1 addition & 0 deletions packages/knip/fixtures/pathless/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import one from 'dir/module-a';
import same from 'same';
same;

export default one;
4 changes: 4 additions & 0 deletions packages/knip/fixtures/paths/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ import index from '@lib';
import fn from '@lib/fn';
import js from 'xyz/main.js';
import anything from '~/my-module';
index;
fn;
js;
anything;
2 changes: 2 additions & 0 deletions packages/knip/fixtures/plugins/eleventy3/.eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const eleventyNavigationPlugin = require('@11ty/eleventy-navigation');
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const path = require('path');
const highlighter = require('./src/_plugins/syntax-highlighter');
path;
highlighter;

module.exports = function (eleventyConfig) {
eleventyConfig.addGlobalData('site_name', 'example');
Expand Down
1 change: 1 addition & 0 deletions packages/knip/fixtures/plugins/webpack/src/app.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import dep from './app-dep';
dep;
1 change: 1 addition & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/1-first.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const first = 1;
1 change: 1 addition & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/2-second.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const second = 2;
2 changes: 2 additions & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/3-barrel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './1-first';
export * from './2-second';
2 changes: 2 additions & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/4-collect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import * as NS from './3-barrel';
export { NS as aliased };
3 changes: 3 additions & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { aliased } from './4-collect';

aliased.first;
3 changes: 3 additions & 0 deletions packages/knip/fixtures/re-exports-aliased-ns/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@fixtures/re-exports-aliased-ns"
}
1 change: 1 addition & 0 deletions packages/knip/fixtures/re-exports-ns-member/member-ab.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const memberA = 1;
export const memberB = 1;
export const unusedMemberA = 1;
1 change: 1 addition & 0 deletions packages/knip/fixtures/re-exports-ns-member/member-cd.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const memberC = 1;
export const memberD = 1;
export const unusedMemberC = 1;
2 changes: 1 addition & 1 deletion packages/knip/fixtures/re-exports-renamed/fileA.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const afoo = 'foo';
export const A = 'A';
2 changes: 1 addition & 1 deletion packages/knip/fixtures/re-exports-renamed/fileB.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * as A from './fileA.js';
export * as B from './fileA.js';
5 changes: 3 additions & 2 deletions packages/knip/fixtures/re-exports-renamed/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import { A as x } from './fileB.js';
console.log(x.afoo);
import { B as C } from './fileB.js';

C.A;
1 change: 0 additions & 1 deletion packages/knip/fixtures/subpath-import/entry.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
import dep from '#dep';

dep;
1 change: 0 additions & 1 deletion packages/knip/fixtures/subpath-patterns/src/entry.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
import used from '#internals/used';

used;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import same from 'src/same';
import one from '@/dir/module-a';
same;

export default one;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unresolved from 'not/found';
import five from '@/dir/module-e';
unresolved;

export default five;
3 changes: 2 additions & 1 deletion packages/knip/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ export const main = async (unresolvedConfiguration: CommandLineOptions) => {
const handleReferencedDependency = getHandler(collector, deputy, chief);

const updateImports = (importedModule: SerializableImports, importItems: SerializableImports) => {
for (const id of importItems.identifiers) importedModule.identifiers.add(id);
for (const id of importItems.refs) importedModule.refs.add(id);
for (const id of importItems.importedAs) importedModule.importedAs.add(id);
for (const id of importItems.importedNs) importedModule.importedNs.add(id);
for (const id of importItems.isReExportedBy) importedModule.isReExportedBy.add(id);
for (const id of importItems.isReExportedNs) importedModule.isReExportedNs.add(id);
Expand Down
2 changes: 2 additions & 0 deletions packages/knip/src/types/imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type ts from 'typescript';
export interface ImportNode {
specifier: string;
identifier: string | undefined;
alias?: string | undefined;
namespace?: string | undefined;
pos: number | undefined;
symbol?: ts.Symbol;
isTypeOnly?: boolean;
Expand Down
13 changes: 7 additions & 6 deletions packages/knip/src/types/serializable-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import type { IssueSymbol, SymbolType } from './issues.js';

type FilePath = string;
type Specifier = string;
type Identifier = string;
type Identifiers = Set<Identifier>;
type Reference = string;
type References = Set<Reference>;
type Tags = Set<string>;

export type SerializableImports = {
specifier: Specifier;
identifiers: Identifiers;
refs: References;
hasStar: boolean;
importedAs: Set<[string, string]>;
importedNs: Set<string>;
isReExport: boolean;
isReExportedBy: Set<string>;
Expand All @@ -24,7 +25,7 @@ export type SerializableImportMap = Record<FilePath, SerializableImports>;
export type UnresolvedImport = { specifier: string; pos?: number; line?: number; col?: number };

export interface SerializableExport {
identifier: Identifier;
identifier: Reference;
pos: number;
line: number;
col: number;
Expand All @@ -37,7 +38,7 @@ export interface SerializableExport {
}

export type SerializableExportMember = {
identifier: Identifier;
identifier: Reference;
pos: number;
line: number;
col: number;
Expand All @@ -48,7 +49,7 @@ export type SerializableExportMember = {
jsDocTags: Tags;
};

export type SerializableExports = Record<Identifier, SerializableExport>;
export type SerializableExports = Record<Reference, SerializableExport>;

export type SerializableFile = {
internalImportCache?: SerializableImportMap;
Expand Down
5 changes: 4 additions & 1 deletion packages/knip/src/typescript/ast-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,12 @@ export const isDestructuring = (node: ts.Node) =>
export const getDestructuredIds = (name: ts.ObjectBindingPattern) =>
name.elements.map(element => element.name.getText());

export const isConsiderReferencedNS = (node: ts.Identifier) =>
export const isConsiderReferenced = (node: ts.Identifier) =>
ts.isShorthandPropertyAssignment(node.parent) ||
(ts.isCallExpression(node.parent) && node.parent.arguments.includes(node)) ||
ts.isSpreadAssignment(node.parent) ||
ts.isExportAssignment(node.parent) ||
(ts.isVariableDeclaration(node.parent) && node.parent.initializer === node);

export const isTopLevel = (node: ts.Node) =>
ts.isSourceFile(node.parent) || (node.parent && ts.isSourceFile(node.parent.parent));

0 comments on commit 004ae3b

Please sign in to comment.