mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
117616: Fixed alias-imports edge case where duplicate imports with different aliases were both kept
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
AST_NODE_TYPES,
|
||||||
ESLintUtils,
|
ESLintUtils,
|
||||||
TSESLint,
|
TSESLint,
|
||||||
TSESTree,
|
TSESTree,
|
||||||
@@ -12,9 +13,16 @@ import {
|
|||||||
export enum Message {
|
export enum Message {
|
||||||
NO_ALIAS = 'noAlias',
|
NO_ALIAS = 'noAlias',
|
||||||
WRONG_ALIAS = 'wrongAlias',
|
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',
|
name: 'alias-imports',
|
||||||
meta: {
|
meta: {
|
||||||
docs: {
|
docs: {
|
||||||
@@ -23,6 +31,7 @@ export const info: DSpaceESLintRuleInfo = {
|
|||||||
messages: {
|
messages: {
|
||||||
[Message.NO_ALIAS]: 'This import must be aliased',
|
[Message.NO_ALIAS]: 'This import must be aliased',
|
||||||
[Message.WRONG_ALIAS]: 'This import uses the wrong alias (should be {{ local }})',
|
[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',
|
fixable: 'code',
|
||||||
type: 'problem',
|
type: 'problem',
|
||||||
@@ -54,7 +63,7 @@ export const info: DSpaceESLintRuleInfo = {
|
|||||||
export const rule = ESLintUtils.RuleCreator.withoutDocs({
|
export const rule = ESLintUtils.RuleCreator.withoutDocs({
|
||||||
...info,
|
...info,
|
||||||
create(context: TSESLint.RuleContext<Message, unknown[]>, options: any) {
|
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);
|
selectors[`ImportDeclaration[source.value = "${option.package}"] > ImportSpecifier[imported.name = "${option.imported}"][local.name != "${option.local}"]`] = (node: TSESTree.ImportSpecifier) => handleUnaliasedImport(context, option, node);
|
||||||
return selectors;
|
return selectors;
|
||||||
}, {});
|
}, {});
|
||||||
@@ -107,11 +116,28 @@ import { of as observableOf } from 'rxjs';
|
|||||||
* Replaces the incorrectly aliased imports with the ones defined in the defaultOptions
|
* Replaces the incorrectly aliased imports with the ones defined in the defaultOptions
|
||||||
*
|
*
|
||||||
* @param context The current {@link TSESLint.RuleContext}
|
* @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
|
* @param node The incorrect import node that should be fixed
|
||||||
*/
|
*/
|
||||||
function handleUnaliasedImport(context: TSESLint.RuleContext<Message, unknown[]>, option: any, node: TSESTree.ImportSpecifier): void {
|
function handleUnaliasedImport(context: TSESLint.RuleContext<Message, unknown[]>, option: AliasImportOption, node: TSESTree.ImportSpecifier): void {
|
||||||
if (node.local.name === node.imported.name) {
|
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({
|
context.report({
|
||||||
messageId: Message.NO_ALIAS,
|
messageId: Message.NO_ALIAS,
|
||||||
node: node,
|
node: node,
|
||||||
|
@@ -17,10 +17,10 @@ export type Meta = RuleMetaData<string, unknown[]>;
|
|||||||
export type Valid = ValidTestCase<unknown[]>;
|
export type Valid = ValidTestCase<unknown[]>;
|
||||||
export type Invalid = InvalidTestCase<string, unknown[]>;
|
export type Invalid = InvalidTestCase<string, unknown[]>;
|
||||||
|
|
||||||
export interface DSpaceESLintRuleInfo {
|
export interface DSpaceESLintRuleInfo<T = unknown[]> {
|
||||||
name: string;
|
name: string;
|
||||||
meta: Meta,
|
meta: Meta,
|
||||||
defaultOptions: unknown[],
|
defaultOptions: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NamedTests {
|
export interface NamedTests {
|
||||||
|
Reference in New Issue
Block a user