Skip to content

Commit e8f7d5a

Browse files
authored
chore: rename variable names in no-unused-props (#1160)
1 parent b45cfb6 commit e8f7d5a

File tree

1 file changed

+80
-71
lines changed

1 file changed

+80
-71
lines changed

packages/eslint-plugin-svelte/src/rules/no-unused-props.ts

Lines changed: 80 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { findVariable } from '../utils/ast-utils.js';
66
import { toRegExp } from '../utils/regexp.js';
77
import { getFilename } from '../utils/compat.js';
88

9-
type PropertyPath = string[];
9+
type PropertyPathArray = string[];
1010

1111
let isRemovedWarningShown = false;
1212

@@ -124,8 +124,8 @@ export default createRule('no-unused-props', {
124124
/**
125125
* Extracts property paths from member expressions.
126126
*/
127-
function getPropertyPath(node: TSESTree.Identifier): PropertyPath {
128-
const paths: PropertyPath = [];
127+
function getPropertyPath(node: TSESTree.Identifier): PropertyPathArray {
128+
const paths: PropertyPathArray = [];
129129
let currentNode: TSESTree.Node = node;
130130
let parentNode: TSESTree.Node | null = currentNode.parent ?? null;
131131

@@ -150,11 +150,11 @@ export default createRule('no-unused-props', {
150150
/**
151151
* Finds all property access paths for a given variable.
152152
*/
153-
function getUsedNestedPropertyNames(node: TSESTree.Identifier): PropertyPath[] {
153+
function getUsedNestedPropertyPathsArray(node: TSESTree.Identifier): PropertyPathArray[] {
154154
const variable = findVariable(context, node);
155155
if (!variable) return [];
156156

157-
const paths: PropertyPath[] = [];
157+
const pathsArray: PropertyPathArray[] = [];
158158
for (const reference of variable.references) {
159159
if (
160160
'identifier' in reference &&
@@ -163,10 +163,10 @@ export default createRule('no-unused-props', {
163163
reference.identifier.range[1] !== node.range[1])
164164
) {
165165
const referencePath = getPropertyPath(reference.identifier);
166-
paths.push(referencePath);
166+
pathsArray.push(referencePath);
167167
}
168168
}
169-
return paths;
169+
return pathsArray;
170170
}
171171

172172
/**
@@ -183,7 +183,7 @@ export default createRule('no-unused-props', {
183183
return sourceFile.fileName.includes('node_modules/typescript/lib/');
184184
}
185185

186-
function getUsedPropertiesFromPattern(pattern: TSESTree.ObjectPattern): Set<string> {
186+
function getUsedPropertyNamesFromPattern(pattern: TSESTree.ObjectPattern): Set<string> {
187187
const usedProps = new Set<string>();
188188
for (const prop of pattern.properties) {
189189
if (prop.type === 'Property' && prop.key.type === 'Identifier') {
@@ -219,41 +219,49 @@ export default createRule('no-unused-props', {
219219
/**
220220
* Recursively checks for unused properties in a type.
221221
*/
222-
function checkUnusedProperties(
223-
type: ts.Type,
224-
usedPaths: PropertyPath[],
225-
usedProps: Set<string>,
226-
reportNode: TSESTree.Node,
227-
parentPath: string[],
228-
checkedTypes: Set<string>,
229-
reportedProps: Set<string>
230-
) {
222+
function checkUnusedProperties({
223+
propsType,
224+
usedPropertyPaths,
225+
declaredPropertyNames,
226+
reportNode,
227+
parentPath,
228+
checkedPropsTypes,
229+
reportedPropertyPaths
230+
}: {
231+
propsType: ts.Type;
232+
usedPropertyPaths: string[];
233+
declaredPropertyNames: Set<string>;
234+
reportNode: TSESTree.Node;
235+
parentPath: string[];
236+
checkedPropsTypes: Set<string>;
237+
reportedPropertyPaths: Set<string>;
238+
}) {
231239
// Skip checking if the type itself is a class
232-
if (isClassType(type)) return;
240+
if (isClassType(propsType)) return;
233241

234-
const typeStr = typeChecker.typeToString(type);
235-
if (checkedTypes.has(typeStr)) return;
236-
checkedTypes.add(typeStr);
237-
if (shouldIgnoreType(type)) return;
242+
const typeStr = typeChecker.typeToString(propsType);
243+
if (checkedPropsTypes.has(typeStr)) return;
244+
checkedPropsTypes.add(typeStr);
245+
if (shouldIgnoreType(propsType)) return;
238246

239-
const properties = typeChecker.getPropertiesOfType(type);
240-
const baseTypes = type.getBaseTypes();
247+
const properties = typeChecker.getPropertiesOfType(propsType);
248+
const propsBaseTypes = propsType.getBaseTypes();
241249

242-
if (!properties.length && (!baseTypes || baseTypes.length === 0)) {
250+
if (!properties.length && (!propsBaseTypes || propsBaseTypes.length === 0)) {
243251
return;
244252
}
245253

246-
if (baseTypes) {
247-
for (const baseType of baseTypes) {
248-
checkUnusedProperties(
249-
baseType,
250-
usedPaths,
251-
usedProps,
254+
if (propsBaseTypes) {
255+
for (const propsBaseType of propsBaseTypes) {
256+
checkUnusedProperties({
257+
propsType: propsBaseType,
258+
usedPropertyPaths,
259+
declaredPropertyNames,
252260
reportNode,
253261
parentPath,
254-
checkedTypes,
255-
reportedProps
256-
);
262+
checkedPropsTypes,
263+
reportedPropertyPaths
264+
});
257265
}
258266
}
259267

@@ -267,24 +275,23 @@ export default createRule('no-unused-props', {
267275
const currentPath = [...parentPath, propName];
268276
const currentPathStr = [...parentPath, propName].join('.');
269277

270-
if (reportedProps.has(currentPathStr)) continue;
278+
if (reportedPropertyPaths.has(currentPathStr)) continue;
271279

272280
const propType = typeChecker.getTypeOfSymbol(prop);
273281

274-
const joinedUsedPaths = usedPaths.map((path) => path.join('.'));
275-
const isUsedThisInPath = joinedUsedPaths.includes(currentPathStr);
276-
const isUsedInPath = joinedUsedPaths.some((path) => {
282+
const isUsedThisInPath = usedPropertyPaths.includes(currentPathStr);
283+
const isUsedInPath = usedPropertyPaths.some((path) => {
277284
return path.startsWith(`${currentPathStr}.`);
278285
});
279286

280287
if (isUsedThisInPath && !isUsedInPath) {
281288
continue;
282289
}
283290

284-
const isUsedInProps = usedProps.has(propName);
291+
const isUsedInProps = declaredPropertyNames.has(propName);
285292

286293
if (!isUsedInPath && !isUsedInProps) {
287-
reportedProps.add(currentPathStr);
294+
reportedPropertyPaths.add(currentPathStr);
288295
context.report({
289296
node: reportNode,
290297
messageId: parentPath.length ? 'unusedNestedProp' : 'unusedProp',
@@ -296,30 +303,30 @@ export default createRule('no-unused-props', {
296303
continue;
297304
}
298305

299-
const isUsedNested = joinedUsedPaths.some((path) => {
306+
const isUsedNested = usedPropertyPaths.some((path) => {
300307
return path.startsWith(`${currentPathStr}.`);
301308
});
302309

303310
if (isUsedNested || isUsedInProps) {
304-
checkUnusedProperties(
305-
propType,
306-
usedPaths,
307-
usedProps,
311+
checkUnusedProperties({
312+
propsType: propType,
313+
usedPropertyPaths,
314+
declaredPropertyNames,
308315
reportNode,
309-
currentPath,
310-
checkedTypes,
311-
reportedProps
312-
);
316+
parentPath: currentPath,
317+
checkedPropsTypes,
318+
reportedPropertyPaths
319+
});
313320
}
314321
}
315322

316323
// Check for unused index signatures only at the root level
317324
if (parentPath.length === 0) {
318-
const indexType = type.getStringIndexType();
319-
const numberIndexType = type.getNumberIndexType();
325+
const indexType = propsType.getStringIndexType();
326+
const numberIndexType = propsType.getNumberIndexType();
320327
const hasIndexSignature = Boolean(indexType) || Boolean(numberIndexType);
321328

322-
if (hasIndexSignature && !hasRestElement(usedProps)) {
329+
if (hasIndexSignature && !hasRestElement(declaredPropertyNames)) {
323330
context.report({
324331
node: reportNode,
325332
messageId: 'unusedIndexSignature'
@@ -336,8 +343,8 @@ export default createRule('no-unused-props', {
336343
return usedProps.size === 0;
337344
}
338345

339-
function normalizeUsedPaths(paths: PropertyPath[]): PropertyPath[] {
340-
const normalized: PropertyPath[] = [];
346+
function normalizeUsedPaths(paths: PropertyPathArray[]): PropertyPathArray[] {
347+
const normalized: PropertyPathArray[] = [];
341348
for (const path of paths.sort((a, b) => a.length - b.length)) {
342349
if (path.length === 0) continue;
343350
if (normalized.some((p) => p.every((part, idx) => part === path[idx]))) {
@@ -362,13 +369,13 @@ export default createRule('no-unused-props', {
362369
const tsNode = tools.service.esTreeNodeToTSNodeMap.get(node) as ts.VariableDeclaration;
363370
if (!tsNode || !tsNode.type) return;
364371

365-
const propType = typeChecker.getTypeFromTypeNode(tsNode.type);
366-
let usedPaths: PropertyPath[] = [];
367-
let usedProps = new Set<string>();
372+
const propsType = typeChecker.getTypeFromTypeNode(tsNode.type);
373+
let usedPropertyPathsArray: PropertyPathArray[] = [];
374+
let declaredPropertyNames = new Set<string>();
368375

369376
if (node.id.type === 'ObjectPattern') {
370-
usedProps = getUsedPropertiesFromPattern(node.id);
371-
if (usedProps.size === 0) return;
377+
declaredPropertyNames = getUsedPropertyNamesFromPattern(node.id);
378+
if (declaredPropertyNames.size === 0) return;
372379
const identifiers: TSESTree.Identifier[] = [];
373380
for (const p of node.id.properties) {
374381
if (p.type !== 'Property') {
@@ -381,22 +388,24 @@ export default createRule('no-unused-props', {
381388
}
382389
}
383390
for (const identifier of identifiers) {
384-
const paths = getUsedNestedPropertyNames(identifier);
385-
usedPaths.push(...paths.map((path) => [identifier.name, ...path]));
391+
const paths = getUsedNestedPropertyPathsArray(identifier);
392+
usedPropertyPathsArray.push(...paths.map((path) => [identifier.name, ...path]));
386393
}
387394
} else if (node.id.type === 'Identifier') {
388-
usedPaths = getUsedNestedPropertyNames(node.id);
395+
usedPropertyPathsArray = getUsedNestedPropertyPathsArray(node.id);
389396
}
390397

391-
checkUnusedProperties(
392-
propType,
393-
normalizeUsedPaths(usedPaths),
394-
usedProps,
395-
node.id,
396-
[],
397-
new Set<string>(),
398-
new Set<string>()
399-
);
398+
checkUnusedProperties({
399+
propsType,
400+
usedPropertyPaths: normalizeUsedPaths(usedPropertyPathsArray).map((pathArray) => {
401+
return pathArray.join('.');
402+
}),
403+
declaredPropertyNames,
404+
reportNode: node.id,
405+
parentPath: [],
406+
checkedPropsTypes: new Set<string>(),
407+
reportedPropertyPaths: new Set<string>()
408+
});
400409
}
401410
};
402411
}

0 commit comments

Comments
 (0)