117616: Fixed alias-imports edge case where duplicate imports with different aliases were both kept

This commit is contained in:
Alexandre Vryghem
2024-08-28 19:00:49 +02:00
parent abb03799e0
commit f10447b8d3
2 changed files with 33 additions and 7 deletions

View File

@@ -1,4 +1,5 @@
import {
AST_NODE_TYPES,
ESLintUtils,
TSESLint,
TSESTree,
@@ -12,9 +13,16 @@ import {
export enum Message {
NO_ALIAS = 'noAlias',
WRONG_ALIAS = 'wrongAlias',
MULTIPLE_ALIASES = 'multipleAliases',
}
export const info: DSpaceESLintRuleInfo = {
interface AliasImportOption {
package: string;
imported: string;
local: string;
}
export const info: DSpaceESLintRuleInfo<[[AliasImportOption]]> = {
name: 'alias-imports',
meta: {
docs: {
@@ -23,6 +31,7 @@ export const info: DSpaceESLintRuleInfo = {
messages: {
[Message.NO_ALIAS]: 'This import must be aliased',
[Message.WRONG_ALIAS]: 'This import uses the wrong alias (should be {{ local }})',
[Message.MULTIPLE_ALIASES]: 'This import was used twice with a different alias (should be {{ local }})',
},
fixable: 'code',
type: 'problem',
@@ -54,7 +63,7 @@ export const info: DSpaceESLintRuleInfo = {
export const rule = ESLintUtils.RuleCreator.withoutDocs({
...info,
create(context: TSESLint.RuleContext<Message, unknown[]>, options: any) {
return options[0].reduce((selectors: any, option: any) => {
return options[0].reduce((selectors: any, option: AliasImportOption) => {
selectors[`ImportDeclaration[source.value = "${option.package}"] > ImportSpecifier[imported.name = "${option.imported}"][local.name != "${option.local}"]`] = (node: TSESTree.ImportSpecifier) => handleUnaliasedImport(context, option, node);
return selectors;
}, {});
@@ -107,11 +116,28 @@ import { of as observableOf } from 'rxjs';
* Replaces the incorrectly aliased imports with the ones defined in the defaultOptions
*
* @param context The current {@link TSESLint.RuleContext}
* @param option The current `defaultOptions` that needs to be handled
* @param option The current {@link AliasImportOption} that needs to be handled
* @param node The incorrect import node that should be fixed
*/
function handleUnaliasedImport(context: TSESLint.RuleContext<Message, unknown[]>, option: any, node: TSESTree.ImportSpecifier): void {
if (node.local.name === node.imported.name) {
function handleUnaliasedImport(context: TSESLint.RuleContext<Message, unknown[]>, option: AliasImportOption, node: TSESTree.ImportSpecifier): void {
const hasAliasedImport: boolean = (node.parent as TSESTree.ImportDeclaration).specifiers.find((specifier: TSESTree.ImportClause) => specifier.local.name === option.local && specifier.type === AST_NODE_TYPES.ImportSpecifier && (specifier as TSESTree.ImportSpecifier).imported.name === option.imported) !== undefined;
if (hasAliasedImport) {
context.report({
messageId: Message.MULTIPLE_ALIASES,
node: node,
fix(fixer: TSESLint.RuleFixer) {
const commaAfter = context.sourceCode.getTokenAfter(node, {
filter: (token: TSESTree.Token) => token.value === ',',
});
if (commaAfter) {
return fixer.removeRange([node.range[0], commaAfter.range[1]]);
} else {
return fixer.remove(node);
}
},
});
} else if (node.local.name === node.imported.name) {
context.report({
messageId: Message.NO_ALIAS,
node: node,

View File

@@ -17,10 +17,10 @@ export type Meta = RuleMetaData<string, unknown[]>;
export type Valid = ValidTestCase<unknown[]>;
export type Invalid = InvalidTestCase<string, unknown[]>;
export interface DSpaceESLintRuleInfo {
export interface DSpaceESLintRuleInfo<T = unknown[]> {
name: string;
meta: Meta,
defaultOptions: unknown[],
defaultOptions: T,
}
export interface NamedTests {