From 7dd065196954630decf6dbda0b8ffdac94c66656 Mon Sep 17 00:00:00 2001 From: Lars Kappert Date: Fri, 15 Mar 2024 11:44:55 +0100 Subject: [PATCH] Skip work, gc file manager --- packages/knip/src/PrincipalFactory.ts | 1 + packages/knip/src/ProjectPrincipal.ts | 5 ++++- packages/knip/src/index.ts | 1 + .../knip/src/typescript/SourceFileManager.ts | 16 ++++++++++++---- packages/knip/src/typescript/createHosts.ts | 7 +++---- .../knip/src/typescript/resolveModuleNames.ts | 3 ++- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/knip/src/PrincipalFactory.ts b/packages/knip/src/PrincipalFactory.ts index ffe98c4fd..afa092b02 100644 --- a/packages/knip/src/PrincipalFactory.ts +++ b/packages/knip/src/PrincipalFactory.ts @@ -17,6 +17,7 @@ export type PrincipalOptions = { pkgName: string; isGitIgnored: (path: string) => boolean; isIsolateWorkspaces: boolean; + isSkipLibs: boolean; }; const mapToAbsolutePaths = (paths: NonNullable, cwd: string): Paths => diff --git a/packages/knip/src/ProjectPrincipal.ts b/packages/knip/src/ProjectPrincipal.ts index c7cb03dac..33551ce78 100644 --- a/packages/knip/src/ProjectPrincipal.ts +++ b/packages/knip/src/ProjectPrincipal.ts @@ -70,6 +70,7 @@ export class ProjectPrincipal { extensions: Set; syncCompilers: SyncCompilers; asyncCompilers: AsyncCompilers; + isSkipLibs: boolean; // @ts-expect-error Don't want to ignore this, but we're not touching this until after init() backend: { @@ -83,7 +84,7 @@ export class ProjectPrincipal { findReferences?: ts.LanguageService['findReferences']; - constructor({ compilerOptions, cwd, compilers, isGitIgnored }: PrincipalOptions) { + constructor({ compilerOptions, cwd, compilers, isGitIgnored, isSkipLibs }: PrincipalOptions) { this.cwd = cwd; this.isGitIgnored = isGitIgnored; @@ -99,6 +100,7 @@ export class ProjectPrincipal { this.extensions = new Set([...DEFAULT_EXTENSIONS, ...getCompilerExtensions(compilers)]); this.syncCompilers = syncCompilers; this.asyncCompilers = asyncCompilers; + this.isSkipLibs = isSkipLibs; } init() { @@ -109,6 +111,7 @@ export class ProjectPrincipal { compilerOptions: this.compilerOptions, entryPaths: this.entryPaths, compilers: [this.syncCompilers, this.asyncCompilers], + isSkipLibs: this.isSkipLibs, }); this.backend = { diff --git a/packages/knip/src/index.ts b/packages/knip/src/index.ts index bcbf48461..46672bc54 100644 --- a/packages/knip/src/index.ts +++ b/packages/knip/src/index.ts @@ -168,6 +168,7 @@ export const main = async (unresolvedConfiguration: CommandLineOptions) => { pkgName, isGitIgnored, isIsolateWorkspaces, + isSkipLibs: !isReportClassMembers, }); const worker = new WorkspaceWorker({ diff --git a/packages/knip/src/typescript/SourceFileManager.ts b/packages/knip/src/typescript/SourceFileManager.ts index f4526527e..47e567385 100644 --- a/packages/knip/src/typescript/SourceFileManager.ts +++ b/packages/knip/src/typescript/SourceFileManager.ts @@ -1,15 +1,22 @@ import ts from 'typescript'; import { debugLog } from '../util/debug.js'; -import { extname, isInternal } from '../util/path.js'; +import { extname, isInNodeModules, isInternal } from '../util/path.js'; import type { SyncCompilers, AsyncCompilers } from '../compilers/types.js'; +interface SourceFileManagerOptions { + isSkipLibs: boolean; + compilers: [SyncCompilers, AsyncCompilers]; +} + export class SourceFileManager { + isSkipLibs: boolean; sourceFileCache = new Map(); snapshotCache = new Map(); - syncCompilers?: SyncCompilers; - asyncCompilers?: AsyncCompilers; + syncCompilers: SyncCompilers; + asyncCompilers: AsyncCompilers; - installCompilers(compilers: [SyncCompilers, AsyncCompilers]) { + constructor({ compilers, isSkipLibs }: SourceFileManagerOptions) { + this.isSkipLibs = isSkipLibs; this.syncCompilers = compilers[0]; this.asyncCompilers = compilers[1]; } @@ -22,6 +29,7 @@ export class SourceFileManager { } getSourceFile(filePath: string) { + if (this.isSkipLibs && isInNodeModules(filePath)) return undefined; if (this.sourceFileCache.has(filePath)) return this.sourceFileCache.get(filePath); const contents = ts.sys.readFile(filePath); if (typeof contents !== 'string') { diff --git a/packages/knip/src/typescript/createHosts.ts b/packages/knip/src/typescript/createHosts.ts index f577a77ef..261071118 100644 --- a/packages/knip/src/typescript/createHosts.ts +++ b/packages/knip/src/typescript/createHosts.ts @@ -15,12 +15,11 @@ type CreateHostsOptions = { compilerOptions: ts.CompilerOptions; entryPaths: Set; compilers: [SyncCompilers, AsyncCompilers]; + isSkipLibs: boolean; }; -const fileManager = new SourceFileManager(); - -export const createHosts = ({ cwd, compilerOptions, entryPaths, compilers }: CreateHostsOptions) => { - fileManager.installCompilers(compilers); +export const createHosts = ({ cwd, compilerOptions, entryPaths, compilers, isSkipLibs }: CreateHostsOptions) => { + const fileManager = new SourceFileManager({ compilers, isSkipLibs }); const virtualFileExtensions = getCompilerExtensions(compilers); const sys = createCustomSys(cwd, virtualFileExtensions); const resolveModuleNames = createCustomModuleResolver(sys, compilerOptions, virtualFileExtensions); diff --git a/packages/knip/src/typescript/resolveModuleNames.ts b/packages/knip/src/typescript/resolveModuleNames.ts index b49633b86..16cc15e34 100644 --- a/packages/knip/src/typescript/resolveModuleNames.ts +++ b/packages/knip/src/typescript/resolveModuleNames.ts @@ -2,7 +2,7 @@ import { existsSync } from 'node:fs'; import { isBuiltin } from 'node:module'; import ts from 'typescript'; import { sanitizeSpecifier } from '../util/modules.js'; -import { basename, dirname, extname, format, isAbsolute, isInternal, join } from '../util/path.js'; +import { basename, dirname, extname, format, isAbsolute, isInNodeModules, isInternal, join } from '../util/path.js'; import { isDeclarationFileExtension } from './ast-helpers.js'; import { ensureRealFilePath, isVirtualFilePath } from './utils.js'; @@ -66,6 +66,7 @@ export function createCustomModuleResolver( // No need to try and resolve builtins, bail out if (isBuiltin(sanitizedSpecifier)) return undefined; + if (isInNodeModules(name)) return undefined; const tsResolvedModule = ts.resolveModuleName( sanitizedSpecifier,