Skip to content

Commit

Permalink
feat(eslint-plugin): [ban-types] Support namespaced type (#616)
Browse files Browse the repository at this point in the history
  • Loading branch information
golopot authored and bradzacher committed Jun 28, 2019
1 parent 606fc70 commit e325b72
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 36 deletions.
77 changes: 41 additions & 36 deletions packages/eslint-plugin/src/rules/ban-types.ts
@@ -1,8 +1,4 @@
import {
TSESLint,
TSESTree,
AST_NODE_TYPES,
} from '@typescript-eslint/experimental-utils';
import { TSESLint, TSESTree } from '@typescript-eslint/experimental-utils';
import * as util from '../util';

type Options = [
Expand All @@ -20,6 +16,31 @@ type Options = [
];
type MessageIds = 'bannedTypeMessage';

function stringifyTypeName(
node: TSESTree.EntityName,
sourceCode: TSESLint.SourceCode,
): string {
return sourceCode.getText(node).replace(/ /g, '');
}

function getCustomMessage(
bannedType: null | string | { message?: string; fixWith?: string },
) {
if (bannedType === null) {
return '';
}

if (typeof bannedType === 'string') {
return ` ${bannedType}`;
}

if (bannedType.message) {
return ` ${bannedType.message}`;
}

return '';
}

export default util.createRule<Options, MessageIds>({
name: 'ban-types',
meta: {
Expand Down Expand Up @@ -87,39 +108,23 @@ export default util.createRule<Options, MessageIds>({
],
create(context, [{ types: bannedTypes }]) {
return {
'TSTypeReference Identifier'(node: TSESTree.Identifier) {
if (
node.parent &&
node.parent.type !== AST_NODE_TYPES.TSQualifiedName
) {
if (node.name in bannedTypes) {
let customMessage = '';
const bannedCfgValue = bannedTypes[node.name];
TSTypeReference({ typeName }) {
const name = stringifyTypeName(typeName, context.getSourceCode());

let fix: TSESLint.ReportFixFunction | null = null;
if (name in bannedTypes) {
const bannedType = bannedTypes[name];
const customMessage = getCustomMessage(bannedType);
const fixWith = bannedType && (bannedType as any).fixWith;

if (typeof bannedCfgValue === 'string') {
customMessage += ` ${bannedCfgValue}`;
} else if (bannedCfgValue !== null) {
if (bannedCfgValue.message) {
customMessage += ` ${bannedCfgValue.message}`;
}
if (bannedCfgValue.fixWith) {
const fixWith = bannedCfgValue.fixWith;
fix = fixer => fixer.replaceText(node, fixWith);
}
}

context.report({
node,
messageId: 'bannedTypeMessage',
data: {
name: node.name,
customMessage,
},
fix,
});
}
context.report({
node: typeName,
messageId: 'bannedTypeMessage',
data: {
name: name,
customMessage,
},
fix: fixWith ? fixer => fixer.replaceText(typeName, fixWith) : null,
});
}
},
};
Expand Down
78 changes: 78 additions & 0 deletions packages/eslint-plugin/tests/rules/ban-types.test.ts
Expand Up @@ -16,6 +16,10 @@ const options: InferOptionsTypeFromRule<typeof rule> = [
Object: "Use '{}' instead.",
Array: null,
F: null,
'NS.Bad': {
message: 'Use NS.Good instead.',
fixWith: 'NS.Good',
},
},
},
];
Expand All @@ -39,6 +43,14 @@ ruleTester.run('ban-types', rule, {
code: 'let e: foo.String;',
options,
},
{
code: 'let a: _.NS.Bad',
options,
},
{
code: 'let a: NS.Bad._',
options,
},
],
invalid: [
{
Expand All @@ -56,6 +68,25 @@ ruleTester.run('ban-types', rule, {
],
options,
},
{
code: 'let aa: Foo;',
errors: [
{
messageId: 'bannedTypeMessage',
data: {
name: 'Foo',
customMessage: '',
},
},
],
options: [
{
types: {
Foo: { message: '' },
},
},
],
},
{
code: 'let b: {c: String};',
output: 'let b: {c: string};',
Expand Down Expand Up @@ -217,5 +248,52 @@ class Foo<F = string> extends Bar<string> implements Baz<Object> {
],
options,
},
{
code: 'let a: NS.Bad;',
output: 'let a: NS.Good;',
errors: [
{
messageId: 'bannedTypeMessage',
data: {
name: 'NS.Bad',
customMessage: ' Use NS.Good instead.',
},
line: 1,
column: 8,
},
],
options,
},
{
code: `
let a: NS.Bad<Foo>;
let b: Foo<NS.Bad>;
`,
output: `
let a: NS.Good<Foo>;
let b: Foo<NS.Good>;
`,
errors: [
{
messageId: 'bannedTypeMessage',
data: {
name: 'NS.Bad',
customMessage: ' Use NS.Good instead.',
},
line: 2,
column: 8,
},
{
messageId: 'bannedTypeMessage',
data: {
name: 'NS.Bad',
customMessage: ' Use NS.Good instead.',
},
line: 3,
column: 12,
},
],
options,
},
],
});

0 comments on commit e325b72

Please sign in to comment.