Converted no-bad-reference from TSLint to ESLint (#521)

* Converted no-bad-reference from TSLint to ESLint

* Fix duplicate import

* Remove no-bad-reference entry in dtslint.json

* Add positive test case: ./path

Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
Josh Goldberg
2022-09-15 12:50:45 -04:00
committed by GitHub
parent 703b397abf
commit 3e57adefae
7 changed files with 128 additions and 59 deletions

View File

@@ -4,7 +4,6 @@
"rules": {
// Custom rules
"expect": true,
"no-bad-reference": true,
"no-import-default-of-export-equals": true,
"no-padding": true,
"redundant-undefined": true,

View File

@@ -0,0 +1,62 @@
import { TSESTree } from "@typescript-eslint/utils";
import { createRule } from "../util";
type MessageId = "referencePathPackage" | "referencePathTest";
const rule = createRule({
name: "no-bad-reference",
defaultOptions: [],
meta: {
type: "problem",
docs: {
description: `Forbids <reference path="../etc"/> in any file, and forbid <reference path> in test files.`,
recommended: "error",
},
messages: {
referencePathPackage:
"Don't use <reference path> to reference another package. Use an import or <reference types> instead.",
referencePathTest:
"Don't use <reference path> in test files. Use <reference types> or include the file in 'tsconfig.json'.",
},
schema: [],
},
create(context) {
const { comments } = context.getSourceCode().ast;
const isDeclarationFile = context.getFilename().endsWith(".d.ts");
for (const comment of comments) {
const referenceMatch = comment.value.match(/<reference\s+path\s*=\s*"(.+)"\s*\/>/)?.[1];
if (!referenceMatch) {
continue;
}
if (isDeclarationFile) {
if (referenceMatch.startsWith("..")) {
report(comment, "referencePathPackage");
}
} else {
report(comment, "referencePathTest");
}
}
return {};
function report(comment: TSESTree.Comment, messageId: MessageId) {
context.report({
loc: {
end: {
column: comment.value.lastIndexOf(`"`),
line: comment.loc.end.line,
},
start: {
column: comment.value.indexOf(`"`) + 1,
line: comment.loc.start.line,
},
},
messageId,
});
}
},
});
export = rule;

View File

@@ -1,41 +0,0 @@
import * as Lint from "tslint";
import * as ts from "typescript";
import { failure } from "../util";
export class Rule extends Lint.Rules.AbstractRule {
static metadata: Lint.IRuleMetadata = {
ruleName: "no-bad-reference",
description: 'Forbid <reference path="../etc"/> in any file, and forbid <reference path> in test files.',
optionsDescription: "Not configurable.",
options: null,
type: "functionality",
typescriptOnly: true,
};
static FAILURE_STRING = failure(
Rule.metadata.ruleName,
"Don't use <reference path> to reference another package. Use an import or <reference types> instead."
);
static FAILURE_STRING_REFERENCE_IN_TEST = failure(
Rule.metadata.ruleName,
"Don't use <reference path> in test files. Use <reference types> or include the file in 'tsconfig.json'."
);
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
}
}
function walk(ctx: Lint.WalkContext<void>): void {
const { sourceFile } = ctx;
for (const ref of sourceFile.referencedFiles) {
if (sourceFile.isDeclarationFile) {
if (ref.fileName.startsWith("..")) {
ctx.addFailure(ref.pos, ref.end, Rule.FAILURE_STRING);
}
} else {
ctx.addFailure(ref.pos, ref.end, Rule.FAILURE_STRING_REFERENCE_IN_TEST);
}
}
}

View File

@@ -0,0 +1,66 @@
import { ESLintUtils } from "@typescript-eslint/utils";
import * as noBadReference from "../src/rules/no-bad-reference";
const ruleTester = new ESLintUtils.RuleTester({
parser: "@typescript-eslint/parser",
});
ruleTester.run("no-bad-reference", noBadReference, {
invalid: [
{
code: `/// <reference path="../other" />`,
errors: [
{
column: 20,
endColumn: 28,
line: 1,
messageId: "referencePathTest",
},
],
filename: "types.ts",
},
{
code: `/// <reference path="other" />`,
errors: [
{
column: 20,
endColumn: 25,
line: 1,
messageId: "referencePathTest",
},
],
filename: "types.ts",
},
{
code: `/// <reference path="../other" />`,
errors: [
{
column: 20,
endColumn: 28,
line: 1,
messageId: "referencePathPackage",
},
],
filename: "types.d.ts",
},
],
valid: [
``,
`// unrelated comment`,
`/// similar (reference path) comment`,
{
code: `/// <reference path="other" />`,
filename: "types.d.ts",
},
{
code: `/// <reference path="./other" />`,
filename: "types.d.ts",
},
{
code: `/// <reference path="other" />
/// <reference path="other2" />`,
filename: "types.d.ts",
},
],
});

View File

@@ -1,4 +0,0 @@
/// <reference path="../foo" />
~~~~~~ [Don't use <reference path> to reference another package. Use an import or <reference types> instead. See: https://github.com/microsoft/DefinitelyTyped-tools/blob/master/packages/dtslint/docs/no-bad-reference.md]
/// <reference path="foo" />

View File

@@ -1,7 +0,0 @@
/// <reference path="../foo" />
~~~~~~ [0]
/// <reference path="foo" />
~~~ [0]
[0]: Don't use <reference path> in test files. Use <reference types> or include the file in 'tsconfig.json'. See: https://github.com/microsoft/DefinitelyTyped-tools/blob/master/packages/dtslint/docs/no-bad-reference.md

View File

@@ -1,6 +0,0 @@
{
"rulesDirectory": ["../../dist/rules"],
"rules": {
"no-bad-reference": true
}
}