Skip to content

fix(eslint-plugin): [no-unused-vars] incorporate upstream changes around caught errors report messages #9532

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 22, 2024
82 changes: 44 additions & 38 deletions packages/eslint-plugin/src/rules/no-unused-vars.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { ScopeVariable } from '@typescript-eslint/scope-manager';
import type {
Definition,
ScopeVariable,
} from '@typescript-eslint/scope-manager';
import {
DefinitionType,
PatternVisitor,
Expand Down Expand Up @@ -181,6 +184,38 @@ export default createRule<Options, MessageIds>({
return options;
})();

/**
* Determines what variable type a def is.
* @param def the declaration to check
* @returns a simple name for the types of variables that this rule supports
*/
function defToVariableType(def: Definition): VariableType {
/*
* This `destructuredArrayIgnorePattern` error report works differently from the catch
* clause and parameter error reports. _Both_ the `varsIgnorePattern` and the
* `destructuredArrayIgnorePattern` will be checked for array destructuring. However,
* for the purposes of the report, the currently defined behavior is to only inform the
* user of the `destructuredArrayIgnorePattern` if it's present (regardless of the fact
* that the `varsIgnorePattern` would also apply). If it's not present, the user will be
* informed of the `varsIgnorePattern`, assuming that's present.
*/
if (
options.destructuredArrayIgnorePattern &&
def.name.parent.type === AST_NODE_TYPES.ArrayPattern
) {
return 'array-destructure';
}

switch (def.type) {
case DefinitionType.CatchClause:
return 'catch-clause';
case DefinitionType.Parameter:
return 'parameter';
default:
return 'variable';
}
}

/**
* Gets a given variable's description and configured ignore pattern
* based on the provided variableType
Expand All @@ -202,7 +237,7 @@ export default createRule<Options, MessageIds>({
case 'catch-clause':
return {
pattern: options.caughtErrorsIgnorePattern?.toString(),
variableDescription: 'args',
variableDescription: 'caught errors',
};

case 'parameter':
Expand All @@ -228,33 +263,13 @@ export default createRule<Options, MessageIds>({
function getDefinedMessageData(
unusedVar: ScopeVariable,
): Record<string, unknown> {
const def = unusedVar.defs.at(0)?.type;
const def = unusedVar.defs.at(0);
let additionalMessageData = '';

if (def) {
const { variableDescription, pattern } = (() => {
switch (def) {
case DefinitionType.CatchClause:
if (options.caughtErrorsIgnorePattern) {
return getVariableDescription('catch-clause');
}
break;

case DefinitionType.Parameter:
if (options.argsIgnorePattern) {
return getVariableDescription('parameter');
}
break;

default:
if (options.varsIgnorePattern) {
return getVariableDescription('variable');
}
break;
}

return { pattern: undefined, variableDescription: undefined };
})();
const { variableDescription, pattern } = getVariableDescription(
defToVariableType(def),
);

if (pattern && variableDescription) {
additionalMessageData = `. Allowed unused ${variableDescription} must match ${pattern}`;
Expand All @@ -281,18 +296,9 @@ export default createRule<Options, MessageIds>({
let additionalMessageData = '';

if (def) {
const { variableDescription, pattern } = (() => {
if (
def.name.parent.type === AST_NODE_TYPES.ArrayPattern &&
options.destructuredArrayIgnorePattern
) {
return getVariableDescription('array-destructure');
} else if (options.varsIgnorePattern) {
return getVariableDescription('variable');
}

return { pattern: undefined, variableDescription: undefined };
})();
const { variableDescription, pattern } = getVariableDescription(
defToVariableType(def),
);

if (pattern && variableDescription) {
additionalMessageData = `. Allowed unused ${variableDescription} must match ${pattern}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2536,7 +2536,10 @@ try {
`,
options: [{ caughtErrors: 'all', caughtErrorsIgnorePattern: '^ignore' }],
errors: [
definedError('err', '. Allowed unused args must match /^ignore/u'),
definedError(
'err',
'. Allowed unused caught errors must match /^ignore/u',
),
],
},
{
Expand Down Expand Up @@ -2566,7 +2569,10 @@ try {
`,
options: [{ caughtErrors: 'all', caughtErrorsIgnorePattern: '^ignore' }],
errors: [
definedError('err', '. Allowed unused args must match /^ignore/u'),
definedError(
'err',
'. Allowed unused caught errors must match /^ignore/u',
),
],
},

Expand All @@ -2580,8 +2586,14 @@ try {
`,
options: [{ caughtErrors: 'all', caughtErrorsIgnorePattern: '^ignore' }],
errors: [
definedError('error', '. Allowed unused args must match /^ignore/u'),
definedError('err', '. Allowed unused args must match /^ignore/u'),
definedError(
'error',
'. Allowed unused caught errors must match /^ignore/u',
),
definedError(
'err',
'. Allowed unused caught errors must match /^ignore/u',
),
],
},

Expand Down Expand Up @@ -3330,7 +3342,101 @@ try {
reportUsedIgnorePattern: true,
},
],
errors: [usedIgnoredError('_err', '. Used args must not match /^_/u')],
errors: [
usedIgnoredError('_err', '. Used caught errors must not match /^_/u'),
],
},
{
code: `
try {
} catch (_) {
_ = 'foo';
}
`,
options: [{ caughtErrorsIgnorePattern: 'foo' }],
errors: [
assignedError('_', '. Allowed unused caught errors must match /foo/u'),
],
},
{
code: `
try {
} catch (_) {
_ = 'foo';
}
`,
options: [
{
caughtErrorsIgnorePattern: 'ignored',
varsIgnorePattern: '_',
},
],
errors: [
assignedError(
'_',
'. Allowed unused caught errors must match /ignored/u',
),
],
},
{
code: `
try {
} catch ({ message, errors: [firstError] }) {}
`,
options: [{ caughtErrorsIgnorePattern: 'foo' }],
errors: [
{
...definedError(
'message',
'. Allowed unused caught errors must match /foo/u',
),
column: 12,
endColumn: 19,
},
{
...definedError(
'firstError',
'. Allowed unused caught errors must match /foo/u',
),
column: 30,
endColumn: 40,
},
],
},
{
code: `
try {
} catch ({ stack: $ }) {
$ = 'Something broke: ' + $;
}
`,
options: [{ caughtErrorsIgnorePattern: '\\w' }],
errors: [
{
...assignedError(
'$',
'. Allowed unused caught errors must match /\\w/u',
),
column: 3,
endColumn: 4,
},
],
},
{
code: `
_ => {
_ = _ + 1;
};
`,
options: [
{
argsIgnorePattern: 'ignored',
varsIgnorePattern: '_',
},
],
errors: [
assignedError('_', '. Allowed unused args must match /ignored/u'),
],
},
],
});
Loading