knip 6.12.0 → 6.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DependencyDeputy.js +3 -2
- package/dist/plugins/serverless-framework/index.js +1 -1
- package/dist/plugins/serverless-framework/types.d.ts +1 -1
- package/dist/plugins/vercel/index.js +4 -7
- package/dist/plugins/webpack/index.js +8 -1
- package/dist/reporters/util/util.js +7 -8
- package/dist/typescript/visitors/exports.js +23 -5
- package/dist/typescript/visitors/walk.d.ts +13 -1
- package/dist/typescript/visitors/walk.js +104 -30
- package/dist/util/create-options.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/DependencyDeputy.js
CHANGED
|
@@ -139,9 +139,10 @@ export class DependencyDeputy {
|
|
|
139
139
|
if (packageName === workspace.pkgName)
|
|
140
140
|
return true;
|
|
141
141
|
const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
|
|
142
|
-
const
|
|
142
|
+
const isDevOrTypeOnly = isDevOnly || isTypeOnly;
|
|
143
|
+
const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName, isDevOrTypeOnly));
|
|
143
144
|
const typesPackageName = !isDefinitelyTyped(packageName) && getDefinitelyTypedFor(packageName);
|
|
144
|
-
const closestWorkspaceNameForTypes = typesPackageName && workspaceNames.find(name => this.isInDependencies(name, typesPackageName,
|
|
145
|
+
const closestWorkspaceNameForTypes = typesPackageName && workspaceNames.find(name => this.isInDependencies(name, typesPackageName, isDevOrTypeOnly));
|
|
145
146
|
if (closestWorkspaceNameForTypes && !this.hasTypesIncluded.get(closestWorkspaceNameForTypes)?.has(packageName))
|
|
146
147
|
this.addReferencedDependency(closestWorkspaceNameForTypes, typesPackageName);
|
|
147
148
|
if (closestWorkspaceName) {
|
|
@@ -11,7 +11,7 @@ const handlerToEntry = (handler) => {
|
|
|
11
11
|
const resolveConfig = async (config) => {
|
|
12
12
|
if (!config.functions)
|
|
13
13
|
return [];
|
|
14
|
-
return Object.values(config.functions).
|
|
14
|
+
return Object.values(config.functions).flatMap(fn => (fn.handler ? [handlerToEntry(fn.handler)] : []));
|
|
15
15
|
};
|
|
16
16
|
const plugin = {
|
|
17
17
|
title,
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hasDependency } from '../../util/plugin.js';
|
|
2
2
|
const title = 'Vercel';
|
|
3
|
-
const enablers = '
|
|
4
|
-
const entry = ['vercel.{
|
|
5
|
-
const
|
|
6
|
-
const isEnabled = ({ cwd }) => configFiles.some(file => isFile(cwd, file));
|
|
7
|
-
const isRootOnly = true;
|
|
3
|
+
const enablers = ['@vercel/config'];
|
|
4
|
+
const entry = ['vercel.{js,mjs,cjs,ts,mts}'];
|
|
5
|
+
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
8
6
|
const plugin = {
|
|
9
7
|
title,
|
|
10
8
|
enablers,
|
|
11
9
|
isEnabled,
|
|
12
10
|
entry,
|
|
13
|
-
isRootOnly,
|
|
14
11
|
};
|
|
15
12
|
export default plugin;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { toAlias, toDeferResolve, toDeferResolveEntry, toDeferResolveProductionEntry, toDependency, } from '../../util/input.js';
|
|
2
|
-
import { isInternal, join, toAbsolute } from '../../util/path.js';
|
|
2
|
+
import { extname, isInternal, join, toAbsolute } from '../../util/path.js';
|
|
3
3
|
import { hasDependency } from '../../util/plugin.js';
|
|
4
4
|
import { getDependenciesFromConfig } from '../babel/index.js';
|
|
5
5
|
import { createRequireContextVisitor } from './visitors/requireContext.js';
|
|
@@ -7,6 +7,10 @@ const title = 'webpack';
|
|
|
7
7
|
const enablers = ['webpack', 'webpack-cli'];
|
|
8
8
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
9
9
|
const config = ['webpack.config.{js,ts,mjs,cjs,mts,cts}'];
|
|
10
|
+
const interpretLoaders = {
|
|
11
|
+
'.ts': ['ts-node', 'sucrase', '@babel/register', 'esbuild-register', '@swc/register'],
|
|
12
|
+
'.cts': ['ts-node'],
|
|
13
|
+
};
|
|
10
14
|
const hasBabelOptions = (use) => Boolean(use) &&
|
|
11
15
|
typeof use !== 'string' &&
|
|
12
16
|
'loader' in use &&
|
|
@@ -162,6 +166,9 @@ export const findWebpackDependenciesFromConfig = async (config, options) => {
|
|
|
162
166
|
const resolveConfig = async (localConfig, options) => {
|
|
163
167
|
const inputs = await findWebpackDependenciesFromConfig(localConfig, options);
|
|
164
168
|
inputs.push(toDependency('webpack-cli', { optional: true }));
|
|
169
|
+
for (const loader of interpretLoaders[extname(options.configFilePath)] ?? []) {
|
|
170
|
+
inputs.push(toDependency(loader, { optional: true }));
|
|
171
|
+
}
|
|
165
172
|
return inputs;
|
|
166
173
|
};
|
|
167
174
|
const registerVisitors = ({ ctx, registerVisitor }) => {
|
|
@@ -22,13 +22,11 @@ export const convert = (issue) => ({
|
|
|
22
22
|
pos: issue.pos,
|
|
23
23
|
});
|
|
24
24
|
const sortByPos = (a, b) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
: Number(rowA) - Number(rowB)
|
|
31
|
-
: filePathA.localeCompare(filePathB);
|
|
25
|
+
if (a.filePath !== b.filePath)
|
|
26
|
+
return a.filePath.localeCompare(b.filePath);
|
|
27
|
+
if (a.line !== b.line)
|
|
28
|
+
return (a.line ?? 0) - (b.line ?? 0);
|
|
29
|
+
return (a.col ?? 0) - (b.col ?? 0);
|
|
32
30
|
};
|
|
33
31
|
const highlightSymbol = (issue) => (_) => {
|
|
34
32
|
const { specifier, symbol } = issue;
|
|
@@ -52,7 +50,8 @@ export const getTableForType = (issues, cwd, options = { isUseColors: true }) =>
|
|
|
52
50
|
table.cell('parentSymbol', issue.parentSymbol && print(issue.parentSymbol));
|
|
53
51
|
table.cell('symbolType', issue.symbolType && issue.symbolType !== SYMBOL_TYPE.UNKNOWN && print(issue.symbolType));
|
|
54
52
|
const pos = issue.line === undefined ? '' : `:${issue.line}${issue.col === undefined ? '' : `:${issue.col}`}`;
|
|
55
|
-
const
|
|
53
|
+
const filePath = relative(cwd, issue.filePath);
|
|
54
|
+
const cell = isFileIssue ? filePath : `${filePath}${pos}`;
|
|
56
55
|
table.cell('filePath', print(cell));
|
|
57
56
|
table.cell('fixed', issue.isFixed && print('(removed)'));
|
|
58
57
|
}
|
|
@@ -3,6 +3,11 @@ import { addNsValue, addValue } from '../../util/module-graph.js';
|
|
|
3
3
|
import { extractEnumMembers, extractNamespaceMembers, getLineAndCol, getStringValue, isStringLiteral, } from './helpers.js';
|
|
4
4
|
import { EMPTY_TAGS } from './jsdoc.js';
|
|
5
5
|
const getName = (n) => (n?.type === 'Identifier' ? n.name : undefined);
|
|
6
|
+
const hasExplicitFunctionReturnType = (node) => !!node &&
|
|
7
|
+
(node.type === 'ArrowFunctionExpression' ||
|
|
8
|
+
node.type === 'FunctionExpression' ||
|
|
9
|
+
node.type === 'FunctionDeclaration') &&
|
|
10
|
+
Boolean(node.returnType);
|
|
6
11
|
export function handleExportNamed(node, s) {
|
|
7
12
|
if (s.skipExports || s.isInNamespace(node))
|
|
8
13
|
return;
|
|
@@ -34,18 +39,24 @@ export function handleExportNamed(node, s) {
|
|
|
34
39
|
const name = p.argument.name;
|
|
35
40
|
const fix = s.options.isFixExports ? [p.start, p.end, FIX_FLAGS.OBJECT_BINDING] : undefined;
|
|
36
41
|
s.addExport(name, SYMBOL_TYPE.UNKNOWN, p.argument.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
42
|
+
if (declarator.init)
|
|
43
|
+
s.collectRefsInType(declarator.init, name, false);
|
|
37
44
|
s.destructuredExports.add(name);
|
|
38
45
|
}
|
|
39
46
|
else if (p.value?.type === 'Identifier') {
|
|
40
47
|
const name = p.value.name;
|
|
41
48
|
const fix = s.options.isFixExports ? [p.start, p.end, FIX_FLAGS.OBJECT_BINDING] : undefined;
|
|
42
49
|
s.addExport(name, SYMBOL_TYPE.UNKNOWN, p.value.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
50
|
+
if (declarator.init)
|
|
51
|
+
s.collectRefsInType(declarator.init, name, false);
|
|
43
52
|
s.destructuredExports.add(name);
|
|
44
53
|
}
|
|
45
54
|
else if (p.value?.type === 'AssignmentPattern' && p.value.left?.type === 'Identifier') {
|
|
46
55
|
const name = p.value.left.name;
|
|
47
56
|
const fix = s.options.isFixExports ? [p.start, p.end, FIX_FLAGS.OBJECT_BINDING] : undefined;
|
|
48
57
|
s.addExport(name, SYMBOL_TYPE.UNKNOWN, p.value.left.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
58
|
+
if (declarator.init)
|
|
59
|
+
s.collectRefsInType(declarator.init, name, false);
|
|
49
60
|
s.destructuredExports.add(name);
|
|
50
61
|
}
|
|
51
62
|
}
|
|
@@ -55,11 +66,15 @@ export function handleExportNamed(node, s) {
|
|
|
55
66
|
if (el?.type === 'Identifier') {
|
|
56
67
|
const fix = s.options.isFixExports ? [el.start, el.end, FIX_FLAGS.NONE] : undefined;
|
|
57
68
|
s.addExport(el.name, SYMBOL_TYPE.UNKNOWN, el.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
69
|
+
if (declarator.init)
|
|
70
|
+
s.collectRefsInType(declarator.init, el.name, false);
|
|
58
71
|
s.destructuredExports.add(el.name);
|
|
59
72
|
}
|
|
60
73
|
else if (el?.type === 'RestElement' && el.argument?.type === 'Identifier') {
|
|
61
74
|
const fix = s.options.isFixExports ? [el.start, el.end, FIX_FLAGS.NONE] : undefined;
|
|
62
75
|
s.addExport(el.argument.name, SYMBOL_TYPE.UNKNOWN, el.argument.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
76
|
+
if (declarator.init)
|
|
77
|
+
s.collectRefsInType(declarator.init, el.argument.name, false);
|
|
63
78
|
s.destructuredExports.add(el.argument.name);
|
|
64
79
|
}
|
|
65
80
|
}
|
|
@@ -111,10 +126,11 @@ export function handleExportNamed(node, s) {
|
|
|
111
126
|
findSpreads(declarator.init, [name]);
|
|
112
127
|
}
|
|
113
128
|
s.addExport(name, SYMBOL_TYPE.UNKNOWN, declarator.id.start, [], fix, isReExport, jsDocTags);
|
|
114
|
-
if (declarator.id.typeAnnotation)
|
|
129
|
+
if (declarator.id.typeAnnotation) {
|
|
115
130
|
s.collectRefsInType(declarator.id.typeAnnotation, name, true);
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
}
|
|
132
|
+
else if (declarator.init) {
|
|
133
|
+
s.collectRefsInType(declarator.init, name, hasExplicitFunctionReturnType(declarator.init));
|
|
118
134
|
}
|
|
119
135
|
if (!jsDocTags.has(ALIAS_TAG) && declarator.init?.type === 'Identifier') {
|
|
120
136
|
const initName = declarator.init.name;
|
|
@@ -138,11 +154,12 @@ export function handleExportNamed(node, s) {
|
|
|
138
154
|
else if ((decl.type === 'FunctionDeclaration' || decl.type === 'TSDeclareFunction') && decl.id) {
|
|
139
155
|
const fix = s.getFix(exportStart, exportStart + 7);
|
|
140
156
|
s.addExport(decl.id.name, SYMBOL_TYPE.FUNCTION, decl.id.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
141
|
-
s.collectRefsInType(decl, decl.id.name,
|
|
157
|
+
s.collectRefsInType(decl, decl.id.name, hasExplicitFunctionReturnType(decl));
|
|
142
158
|
}
|
|
143
159
|
else if (decl.type === 'ClassDeclaration' && decl.id) {
|
|
144
160
|
const fix = s.getFix(exportStart, exportStart + 7);
|
|
145
161
|
s.addExport(decl.id.name, SYMBOL_TYPE.CLASS, decl.id.start, [], fix, false, s.getJSDocTags(exportStart));
|
|
162
|
+
s.collectRefsInType(decl, decl.id.name, true);
|
|
146
163
|
}
|
|
147
164
|
else if (decl.type === 'TSTypeAliasDeclaration') {
|
|
148
165
|
const fix = s.getTypeFix(exportStart, exportStart + 7);
|
|
@@ -216,12 +233,13 @@ export function handleExportDefault(node, s) {
|
|
|
216
233
|
if (decl.type === 'FunctionDeclaration') {
|
|
217
234
|
type = SYMBOL_TYPE.FUNCTION;
|
|
218
235
|
pos = decl.id?.start ?? decl.start;
|
|
219
|
-
s.collectRefsInType(decl, 'default',
|
|
236
|
+
s.collectRefsInType(decl, 'default', hasExplicitFunctionReturnType(decl));
|
|
220
237
|
}
|
|
221
238
|
else if (decl.type === 'ClassDeclaration') {
|
|
222
239
|
type = SYMBOL_TYPE.CLASS;
|
|
223
240
|
pos = decl.id?.start ?? decl.start;
|
|
224
241
|
members = [];
|
|
242
|
+
s.collectRefsInType(decl, 'default', true);
|
|
225
243
|
}
|
|
226
244
|
else if (decl.type === 'TSInterfaceDeclaration') {
|
|
227
245
|
type = SYMBOL_TYPE.INTERFACE;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Visitor, type Program, type Span } from 'oxc-parser';
|
|
1
|
+
import { Visitor, type Class, type Function as FunctionNode, type Program, type Span, type VariableDeclarator } from 'oxc-parser';
|
|
2
2
|
import type { PluginVisitorObject } from '../../types/config.ts';
|
|
3
3
|
import type { GetImportsAndExportsOptions } from '../../types/config.ts';
|
|
4
4
|
import type { Fix } from '../../types/exports.ts';
|
|
@@ -60,6 +60,18 @@ export interface WalkState extends WalkContext {
|
|
|
60
60
|
scopeStarts: number[];
|
|
61
61
|
scopeEnds: number[];
|
|
62
62
|
shadowScopes: Map<string, [number, number][]>;
|
|
63
|
+
localDeclarations: Map<string, FunctionNode | Class | VariableDeclarator>;
|
|
64
|
+
pendingCallRefs: Array<{
|
|
65
|
+
name: string;
|
|
66
|
+
exportName: string;
|
|
67
|
+
seen: Set<string>;
|
|
68
|
+
}>;
|
|
69
|
+
pendingMemberCallRefs: Array<{
|
|
70
|
+
objectName: string;
|
|
71
|
+
propertyName: string;
|
|
72
|
+
exportName: string;
|
|
73
|
+
seen: Set<string>;
|
|
74
|
+
}>;
|
|
63
75
|
addExport: (identifier: string, type: SymbolType, pos: number, members: ExportMember[], fix: Fix, isReExport: boolean, jsDocTags: Set<string>) => void;
|
|
64
76
|
getFix: (start: number, end: number, flags?: number) => Fix;
|
|
65
77
|
getTypeFix: (start: number, end: number) => Fix;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Visitor } from 'oxc-parser';
|
|
1
|
+
import { Visitor, visitorKeys, } from 'oxc-parser';
|
|
2
2
|
import { FIX_FLAGS, IMPORT_FLAGS, OPAQUE, SYMBOL_TYPE } from '../../constants.js';
|
|
3
3
|
import { addValue } from '../../util/module-graph.js';
|
|
4
4
|
import { isInNodeModules } from '../../util/path.js';
|
|
@@ -47,42 +47,79 @@ const _addExport = (identifier, type, pos, members, fix, isReExport, jsDocTags)
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
|
-
const _collectRefsInType = (node, exportName, signatureOnly) => {
|
|
51
|
-
if (!node
|
|
50
|
+
const _collectRefsInType = (node, exportName, signatureOnly, seen = new Set(), inBody = false) => {
|
|
51
|
+
if (!node)
|
|
52
52
|
return;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (name) {
|
|
56
|
-
const refs = state.referencedInExport.get(name);
|
|
57
|
-
if (refs)
|
|
58
|
-
refs.add(exportName);
|
|
59
|
-
else
|
|
60
|
-
state.referencedInExport.set(name, new Set([exportName]));
|
|
61
|
-
}
|
|
53
|
+
const type = node.type;
|
|
54
|
+
if (!type)
|
|
62
55
|
return;
|
|
56
|
+
switch (type) {
|
|
57
|
+
case 'TSTypeQuery':
|
|
58
|
+
if (node.exprName?.type === 'Identifier')
|
|
59
|
+
_addRefInExport(node.exprName.name, exportName);
|
|
60
|
+
return;
|
|
61
|
+
case 'TSTypeReference':
|
|
62
|
+
if (node.typeName?.type === 'Identifier')
|
|
63
|
+
_addRefInExport(node.typeName.name, exportName);
|
|
64
|
+
break;
|
|
65
|
+
case 'CallExpression': {
|
|
66
|
+
const callee = node.callee;
|
|
67
|
+
if (callee?.type === 'Identifier') {
|
|
68
|
+
state.pendingCallRefs.push({ name: callee.name, exportName, seen });
|
|
69
|
+
}
|
|
70
|
+
else if (callee?.type === 'MemberExpression' &&
|
|
71
|
+
!callee.computed &&
|
|
72
|
+
callee.object?.type === 'Identifier' &&
|
|
73
|
+
callee.property?.type === 'Identifier') {
|
|
74
|
+
state.pendingMemberCallRefs.push({
|
|
75
|
+
objectName: callee.object.name,
|
|
76
|
+
propertyName: callee.property.name,
|
|
77
|
+
exportName,
|
|
78
|
+
seen,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (!inBody) {
|
|
82
|
+
const args = node.arguments;
|
|
83
|
+
if (args) {
|
|
84
|
+
for (const arg of args) {
|
|
85
|
+
if (arg?.type === 'Identifier')
|
|
86
|
+
state.pendingCallRefs.push({ name: arg.name, exportName, seen });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case 'FunctionBody':
|
|
93
|
+
case 'BlockStatement':
|
|
94
|
+
if (signatureOnly)
|
|
95
|
+
return;
|
|
96
|
+
break;
|
|
97
|
+
case 'TSAsExpression':
|
|
98
|
+
case 'TSTypeAssertion':
|
|
99
|
+
case 'TSSatisfiesExpression':
|
|
100
|
+
if (inBody) {
|
|
101
|
+
if (node.expression)
|
|
102
|
+
_collectRefsInType(node.expression, exportName, signatureOnly, seen, inBody);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
63
106
|
}
|
|
64
|
-
|
|
107
|
+
const keys = visitorKeys[type];
|
|
108
|
+
if (!keys)
|
|
65
109
|
return;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const refs = state.referencedInExport.get(name);
|
|
69
|
-
if (refs)
|
|
70
|
-
refs.add(exportName);
|
|
71
|
-
else
|
|
72
|
-
state.referencedInExport.set(name, new Set([exportName]));
|
|
73
|
-
}
|
|
74
|
-
for (const key in node) {
|
|
75
|
-
if (key === 'type' || key === 'parent')
|
|
76
|
-
continue;
|
|
110
|
+
const childInBody = inBody || type === 'FunctionBody' || type === 'BlockStatement';
|
|
111
|
+
for (const key of keys) {
|
|
77
112
|
const val = node[key];
|
|
113
|
+
if (!val)
|
|
114
|
+
continue;
|
|
78
115
|
if (Array.isArray(val)) {
|
|
79
116
|
for (const item of val) {
|
|
80
|
-
if (item
|
|
81
|
-
_collectRefsInType(item, exportName, signatureOnly);
|
|
117
|
+
if (item)
|
|
118
|
+
_collectRefsInType(item, exportName, signatureOnly, seen, childInBody);
|
|
82
119
|
}
|
|
83
120
|
}
|
|
84
|
-
else
|
|
85
|
-
_collectRefsInType(val, exportName, signatureOnly);
|
|
121
|
+
else {
|
|
122
|
+
_collectRefsInType(val, exportName, signatureOnly, seen, childInBody);
|
|
86
123
|
}
|
|
87
124
|
}
|
|
88
125
|
};
|
|
@@ -167,12 +204,15 @@ const coreVisitorObject = {
|
|
|
167
204
|
state.nsRanges.push([node.start, node.end]);
|
|
168
205
|
},
|
|
169
206
|
ClassDeclaration(node) {
|
|
170
|
-
if (node.id?.name)
|
|
207
|
+
if (node.id?.name) {
|
|
171
208
|
state.localDeclarationTypes.set(node.id.name, SYMBOL_TYPE.CLASS);
|
|
209
|
+
state.localDeclarations.set(node.id.name, node);
|
|
210
|
+
}
|
|
172
211
|
},
|
|
173
212
|
FunctionDeclaration(node) {
|
|
174
213
|
if (node.id?.name) {
|
|
175
214
|
state.localDeclarationTypes.set(node.id.name, SYMBOL_TYPE.FUNCTION);
|
|
215
|
+
state.localDeclarations.set(node.id.name, node);
|
|
176
216
|
if (state.scopeDepth > 0)
|
|
177
217
|
_addShadow(node.id.name);
|
|
178
218
|
}
|
|
@@ -201,8 +241,10 @@ const coreVisitorObject = {
|
|
|
201
241
|
}
|
|
202
242
|
else {
|
|
203
243
|
for (const decl of node.declarations) {
|
|
204
|
-
if (decl.id.type === 'Identifier')
|
|
244
|
+
if (decl.id.type === 'Identifier') {
|
|
205
245
|
state.localDeclarationTypes.set(decl.id.name, SYMBOL_TYPE.VARIABLE);
|
|
246
|
+
state.localDeclarations.set(decl.id.name, decl);
|
|
247
|
+
}
|
|
206
248
|
}
|
|
207
249
|
}
|
|
208
250
|
},
|
|
@@ -651,6 +693,9 @@ export function walkAST(program, sourceText, filePath, ctx) {
|
|
|
651
693
|
scopeStarts: [],
|
|
652
694
|
scopeEnds: [],
|
|
653
695
|
shadowScopes: new Map(),
|
|
696
|
+
localDeclarations: new Map(),
|
|
697
|
+
pendingCallRefs: [],
|
|
698
|
+
pendingMemberCallRefs: [],
|
|
654
699
|
addExport: _addExport,
|
|
655
700
|
getFix: _getFix,
|
|
656
701
|
getTypeFix: _getTypeFix,
|
|
@@ -659,6 +704,35 @@ export function walkAST(program, sourceText, filePath, ctx) {
|
|
|
659
704
|
isInNamespace: _isInNamespace,
|
|
660
705
|
};
|
|
661
706
|
ctx.visitor.visit(program);
|
|
707
|
+
while (state.pendingCallRefs.length > 0 || state.pendingMemberCallRefs.length > 0) {
|
|
708
|
+
while (state.pendingCallRefs.length > 0) {
|
|
709
|
+
const { name, exportName, seen } = state.pendingCallRefs.pop();
|
|
710
|
+
if (seen.has(name))
|
|
711
|
+
continue;
|
|
712
|
+
const decl = state.localDeclarations.get(name);
|
|
713
|
+
if (!decl)
|
|
714
|
+
continue;
|
|
715
|
+
seen.add(name);
|
|
716
|
+
_collectRefsInType(decl, exportName, true, seen);
|
|
717
|
+
}
|
|
718
|
+
while (state.pendingMemberCallRefs.length > 0) {
|
|
719
|
+
const { objectName, propertyName, exportName, seen } = state.pendingMemberCallRefs.pop();
|
|
720
|
+
const key = `${objectName}.${propertyName}`;
|
|
721
|
+
if (seen.has(key))
|
|
722
|
+
continue;
|
|
723
|
+
const decl = state.localDeclarations.get(objectName);
|
|
724
|
+
if (decl?.type !== 'VariableDeclarator' || decl.init?.type !== 'ObjectExpression')
|
|
725
|
+
continue;
|
|
726
|
+
const prop = decl.init.properties.find(p => p.type === 'Property' && p.key?.type === 'Identifier' && p.key.name === propertyName);
|
|
727
|
+
if (prop?.type !== 'Property')
|
|
728
|
+
continue;
|
|
729
|
+
const fn = prop.value;
|
|
730
|
+
if (fn.type !== 'ArrowFunctionExpression' && fn.type !== 'FunctionExpression')
|
|
731
|
+
continue;
|
|
732
|
+
seen.add(key);
|
|
733
|
+
_collectRefsInType(fn, exportName, true, seen);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
662
736
|
for (let i = 0; i < state.memberRefsInFile.length; i += 2) {
|
|
663
737
|
const exp = state.exports.get(state.memberRefsInFile[i]);
|
|
664
738
|
if (exp) {
|
|
@@ -14,8 +14,8 @@ import { isAbsolute, join, normalize, toAbsolute, toPosix } from './path.js';
|
|
|
14
14
|
import { splitTags } from './tag.js';
|
|
15
15
|
export const createOptions = async (options) => {
|
|
16
16
|
const { args = {} } = options;
|
|
17
|
-
const pcwd = process.cwd();
|
|
18
|
-
const cwd = normalize(toPosix(
|
|
17
|
+
const pcwd = toPosix(process.cwd());
|
|
18
|
+
const cwd = normalize(toAbsolute(toPosix(options.cwd ?? args.directory ?? pcwd), pcwd));
|
|
19
19
|
const manifestPath = findFile(cwd, 'package.json');
|
|
20
20
|
const manifest = manifestPath && (await loadJSON(manifestPath));
|
|
21
21
|
if (!(manifestPath && manifest)) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "6.12.
|
|
1
|
+
export declare const version = "6.12.2";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.12.
|
|
1
|
+
export const version = '6.12.2';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knip",
|
|
3
|
-
"version": "6.12.
|
|
3
|
+
"version": "6.12.2",
|
|
4
4
|
"description": "Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"analysis",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"fdir": "^6.5.0",
|
|
81
81
|
"formatly": "^0.3.0",
|
|
82
82
|
"get-tsconfig": "4.14.0",
|
|
83
|
-
"jiti": "^2.
|
|
83
|
+
"jiti": "^2.7.0",
|
|
84
84
|
"minimist": "^1.2.8",
|
|
85
85
|
"oxc-parser": "^0.128.0",
|
|
86
86
|
"oxc-resolver": "^11.19.1",
|