Skip to content

Commit

Permalink
feat(prefer-immutable-types): allow for changing suggestion messages (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
RebeccaStevens committed Jun 19, 2024
1 parent 3ed5aa6 commit 822cc33
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 75 deletions.
17 changes: 14 additions & 3 deletions docs/rules/prefer-immutable-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,15 @@ type Options = {
};

suggestions?: {
ReadonlyShallow?: Array<Array<{ pattern: string; replace: string }>>;
ReadonlyDeep?: Array<Array<{ pattern: string; replace: string }>>;
Immutable?: Array<Array<{ pattern: string; replace: string }>>;
ReadonlyShallow?: Array<
Array<{ pattern: string; replace: string; message?: string }>
>;
ReadonlyDeep?: Array<
Array<{ pattern: string; replace: string; message?: string }>
>;
Immutable?: Array<
Array<{ pattern: string; replace: string; message?: string }>
>;
};
};
```
Expand All @@ -262,14 +268,19 @@ const defaults = {
pattern:
"^([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*\\[\\])$",
replace: "readonly $1",
message: "Prepend with readonly.",
},
{
pattern: "^(Array|Map|Set)<(.+)>$",
replace: "Readonly$1<$2>",
message: "Use Readonly$1 instead of $1.",
},
],
[
{
pattern: "^(.+)$",
replace: "Readonly<$1>",
message: "Surround with Readonly.",
},
],
],
Expand Down
126 changes: 73 additions & 53 deletions src/rules/prefer-immutable-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ type FixerConfigRaw = {
replace: string;
};

type SuggestionsConfigRaw = Array<FixerConfigRaw & { message?: string }>;

type FixerConfigRawMap = Partial<
Record<
"ReadonlyShallow" | "ReadonlyDeep" | "Immutable",
Expand All @@ -79,7 +81,7 @@ type FixerConfigRawMap = Partial<
type SuggestionConfigRawMap = Partial<
Record<
"ReadonlyShallow" | "ReadonlyDeep" | "Immutable",
FixerConfigRaw[][] | undefined
SuggestionsConfigRaw[] | undefined
>
>;

Expand All @@ -88,7 +90,7 @@ type FixerConfig = {
replace: string;
};

type SuggestionsConfig = FixerConfig[];
type SuggestionsConfig = Array<FixerConfig & { message?: string }>;

/**
* The options this rule can take.
Expand Down Expand Up @@ -205,6 +207,7 @@ const suggestionsSchema: JSONSchema4 = {
properties: {
pattern: { type: "string" },
replace: { type: "string" },
message: { type: "string" },
},
additionalProperties: false,
},
Expand Down Expand Up @@ -275,14 +278,19 @@ const defaultOptions: Options = [
pattern:
"^([_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*\\[\\])$",
replace: "readonly $1",
message: "Prepend with readonly.",
},
{
pattern: "^(Array|Map|Set)<(.+)>$",
replace: "Readonly$1<$2>",
message: "Use Readonly$1 instead of $1.",
},
],
[
{
pattern: "^(.+)$",
replace: "Readonly<$1>",
message: "Surround with Readonly.",
},
],
],
Expand All @@ -303,6 +311,8 @@ const errorMessages = {
propertyImmutability:
'Property should have an immutability of at least "{{ expected }}" (actual: "{{ actual }}").',
propertyModifier: "Property should have a readonly modifier.",
propertyModifierSuggestion: "Add readonly modifier.",
userDefined: "{{ message }}",
} as const;

/**
Expand Down Expand Up @@ -331,7 +341,7 @@ type Descriptor = RuleResult<

type AllFixers = {
fix: ReportFixFunction | null;
suggestionFixers: ReportFixFunction[] | null;
suggestionFixers: Array<{ fix: ReportFixFunction; message: string }> | null;
};

/**
Expand Down Expand Up @@ -383,14 +393,27 @@ function getConfiguredSuggestionFixers(
suggestionsConfigs: SuggestionsConfig[],
) {
return suggestionsConfigs
.map((configs): NonNullable<Descriptor["fix"]> | null => {
const config = configs.find((c) => c.pattern.test(text));
if (config === undefined) {
return null;
}
return (fixer) =>
fixer.replaceText(node, text.replace(config.pattern, config.replace));
})
.map(
(
configs,
): { fix: NonNullable<Descriptor["fix"]>; message: string } | null => {
const config = configs.find((c) => c.pattern.test(text));
if (config === undefined) {
return null;
}
return {
fix: (fixer) =>
fixer.replaceText(
node,
text.replace(config.pattern, config.replace),
),
message:
config.message === undefined
? `Replace with: ${text.replace(config.pattern, config.replace)}`
: text.replace(config.pattern, config.message),
};
},
)
.filter(isDefined);
}

Expand Down Expand Up @@ -504,17 +527,16 @@ function getParameterTypeViolations(

const parameterProperty = isTSParameterProperty(param);
if (parameterProperty && !param.readonly) {
const messageId = "propertyModifier";
const fix: NonNullable<Descriptor["fix"]> | null = (fixer) =>
fixer.insertTextBefore(param.parameter, "readonly ");

return {
node: param,
messageId,
messageId: "propertyModifier",
fix: fixerConfigs === false ? null : fix,
suggest: [
{
messageId,
messageId: "propertyModifierSuggestion",
fix,
},
],
Expand Down Expand Up @@ -564,21 +586,20 @@ function getParameterTypeViolations(
suggestionsConfigs,
);

const messageId = "parameter";
const data = {
actual: Immutability[immutability],
expected: Immutability[enforcement],
};

return {
node: actualParam,
messageId,
data,
messageId: "parameter",
data: {
actual: Immutability[immutability],
expected: Immutability[enforcement],
},
fix,
suggest:
suggestionFixers?.map((fix) => ({
messageId,
data,
suggestionFixers?.map(({ fix, message }) => ({

Check warning on line 598 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js

'fix' is already declared in the upper scope on line 579 column 15

Check warning on line 598 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js / lint_js

'fix' is already declared in the upper scope on line 579 column 15
messageId: "userDefined",
data: {
message,
},
fix,
})) ?? null,
};
Expand Down Expand Up @@ -658,22 +679,21 @@ function getReturnTypeViolations(
suggestionsConfigs,
);

const messageId = "returnType";
const data = {
actual: Immutability[immutability],
expected: Immutability[enforcement],
};

return [
{
node: node.returnType,
messageId,
data,
messageId: "returnType",
data: {
actual: Immutability[immutability],
expected: Immutability[enforcement],
},
fix,
suggest:
suggestionFixers?.map((fix) => ({
messageId,
data,
suggestionFixers?.map(({ fix, message }) => ({

Check warning on line 692 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js

'fix' is already declared in the upper scope on line 675 column 13

Check warning on line 692 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js / lint_js

'fix' is already declared in the upper scope on line 675 column 13
messageId: "userDefined",
data: {
message,
},
fix,
})) ?? null,
},
Expand Down Expand Up @@ -713,22 +733,21 @@ function getReturnTypeViolations(
suggestionsConfigs,
);

const messageId = "returnType";
const data = {
actual: Immutability[immutability],
expected: Immutability[enforcement],
};

return [
{
node: hasID(node) && node.id !== null ? node.id : node,
messageId,
data,
messageId: "returnType",
data: {
actual: Immutability[immutability],
expected: Immutability[enforcement],
},
fix,
suggest:
suggestionFixers?.map((fix) => ({
messageId,
data,
suggestionFixers?.map(({ fix, message }) => ({

Check warning on line 746 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js

'fix' is already declared in the upper scope on line 726 column 11

Check warning on line 746 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js / lint_js

'fix' is already declared in the upper scope on line 726 column 11
messageId: "userDefined",
data: {
message,
},
fix,
})) ?? null,
},
Expand Down Expand Up @@ -807,17 +826,16 @@ function checkVariable(
const fix: NonNullable<Descriptor["fix"]> | null = (fixer) =>
fixer.insertTextBefore(node.key, "readonly ");

const messageId = "propertyModifier";
return {
context,
descriptors: [
{
node,
messageId,
messageId: "propertyModifier",
fix: rawFixerConfig === undefined ? null : fix,
suggest: [
{
messageId,
messageId: "propertyModifierSuggestion",
fix,
},
],
Expand Down Expand Up @@ -912,9 +930,11 @@ function checkVariable(
data,
fix,
suggest:
suggestionFixers?.map((fix) => ({
messageId,
data,
suggestionFixers?.map(({ fix, message }) => ({

Check warning on line 933 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js

'fix' is already declared in the upper scope on line 921 column 38

Check warning on line 933 in src/rules/prefer-immutable-types.ts

View workflow job for this annotation

GitHub Actions / lint_js / lint_js

'fix' is already declared in the upper scope on line 921 column 38
messageId: "userDefined",
data: {
message,
},
fix,
})) ?? null,
};
Expand Down
Loading

0 comments on commit 822cc33

Please sign in to comment.