From d5e6c7d23c0cb7461ab187c66944c4e93d8d9616 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 25 Mar 2023 01:10:08 -0400 Subject: [PATCH 1/5] Converted no-single-declare-module from TSLint to ESLint --- packages/dtslint/dtslint.json | 1 - .../src/rules/no-single-declare-module.ts | 58 +++++++++++++++++++ .../src/rules/noSingleDeclareModuleRule.ts | 55 ------------------ .../test/no-single-declare-module.test.ts | 50 ++++++++++++++++ .../augmentation.d.ts.lint | 3 - .../multiple.d.ts.lint | 2 - .../test/no-single-declare-module/tslint.json | 6 -- .../wildcard.d.ts.lint | 1 - .../no-single-declare-module/wrong.d.ts.lint | 5 -- .../tsconfig.no-single-declare-module.json | 7 +++ 10 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 packages/dtslint/src/rules/no-single-declare-module.ts delete mode 100644 packages/dtslint/src/rules/noSingleDeclareModuleRule.ts create mode 100644 packages/dtslint/test/no-single-declare-module.test.ts delete mode 100644 packages/dtslint/test/no-single-declare-module/augmentation.d.ts.lint delete mode 100644 packages/dtslint/test/no-single-declare-module/multiple.d.ts.lint delete mode 100644 packages/dtslint/test/no-single-declare-module/tslint.json delete mode 100644 packages/dtslint/test/no-single-declare-module/wildcard.d.ts.lint delete mode 100644 packages/dtslint/test/no-single-declare-module/wrong.d.ts.lint create mode 100644 packages/dtslint/test/tsconfig.no-single-declare-module.json diff --git a/packages/dtslint/dtslint.json b/packages/dtslint/dtslint.json index ad43f18629..d3bfef9c68 100644 --- a/packages/dtslint/dtslint.json +++ b/packages/dtslint/dtslint.json @@ -8,7 +8,6 @@ "no-padding": true, "no-relative-import-in-test": true, "strict-export-declare-modifiers": true, - "no-single-declare-module": true, "unified-signatures": true, "void-return": true, "npm-naming": true, diff --git a/packages/dtslint/src/rules/no-single-declare-module.ts b/packages/dtslint/src/rules/no-single-declare-module.ts new file mode 100644 index 0000000000..aae9db6f57 --- /dev/null +++ b/packages/dtslint/src/rules/no-single-declare-module.ts @@ -0,0 +1,58 @@ +import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import * as ts from "typescript"; + +import { createRule } from "../util"; + +const rule = createRule({ + defaultOptions: [], + meta: { + docs: { + description: "Don't use an ambient module declaration if there's just one -- write it as a normal module.", + recommended: "error", + }, + messages: { + oneModuleDeclaration: + "File has only 1 ambient module declaration. Move the contents outside the ambient module block, rename the file to match the ambient module name, and remove the block.", + }, + schema: [], + type: "problem", + }, + name: "no-single-declare-module", + create(context) { + const services = ESLintUtils.getParserServices(context); + const sourceFile = services.esTreeNodeToTSNodeMap.get(context.getSourceCode().ast); + + // If it's an external module, any module declarations inside are augmentations. + if (ts.isExternalModule(sourceFile)) { + return {}; + } + + let moduleDeclaration: ts.ModuleDeclaration | undefined; + for (const statement of sourceFile.statements) { + if (ts.isModuleDeclaration(statement) && ts.isStringLiteral(statement.name)) { + if (statement.name.text.indexOf("*") !== -1) { + // Ignore wildcard module declarations + return {}; + } + + if (moduleDeclaration === undefined) { + moduleDeclaration = statement; + } else { + // Has more than 1 declaration + return {}; + } + } + } + + if (moduleDeclaration) { + context.report({ + messageId: "oneModuleDeclaration", + node: services.tsNodeToESTreeNodeMap.get(moduleDeclaration), + }); + } + + return {}; + }, +}); + +export = rule; diff --git a/packages/dtslint/src/rules/noSingleDeclareModuleRule.ts b/packages/dtslint/src/rules/noSingleDeclareModuleRule.ts deleted file mode 100644 index c5f59170db..0000000000 --- a/packages/dtslint/src/rules/noSingleDeclareModuleRule.ts +++ /dev/null @@ -1,55 +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-single-declare-module", - description: "Don't use an ambient module declaration if there's just one -- write it as a normal module.", - rationale: "Cuts down on nesting", - optionsDescription: "Not configurable.", - options: null, - type: "style", - typescriptOnly: true, - }; - - static FAILURE_STRING = failure( - Rule.metadata.ruleName, - "File has only 1 ambient module declaration. Move the contents outside the ambient module block, rename the file to match the ambient module name, and remove the block." - ); - - apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { - return this.applyWithFunction(sourceFile, walk); - } -} - -function walk(ctx: Lint.WalkContext): void { - const { sourceFile } = ctx; - - // If it's an external module, any module declarations inside are augmentations. - if (ts.isExternalModule(sourceFile)) { - return; - } - - let moduleDecl: ts.ModuleDeclaration | undefined; - for (const statement of sourceFile.statements) { - if (ts.isModuleDeclaration(statement) && ts.isStringLiteral(statement.name)) { - if (statement.name.text.indexOf("*") !== -1) { - // Ignore wildcard module declarations - return; - } - - if (moduleDecl === undefined) { - moduleDecl = statement; - } else { - // Has more than 1 declaration - return; - } - } - } - - if (moduleDecl) { - ctx.addFailureAtNode(moduleDecl, Rule.FAILURE_STRING); - } -} diff --git a/packages/dtslint/test/no-single-declare-module.test.ts b/packages/dtslint/test/no-single-declare-module.test.ts new file mode 100644 index 0000000000..2df3b840f8 --- /dev/null +++ b/packages/dtslint/test/no-single-declare-module.test.ts @@ -0,0 +1,50 @@ +import { ESLintUtils } from "@typescript-eslint/utils"; +import path from "path"; + +import rule from "../src/rules/no-single-declare-module"; + +const ruleTester = new ESLintUtils.RuleTester({ + parser: "@typescript-eslint/parser", + parserOptions: { + tsconfigRootDir: __dirname, + project: "./tsconfig.no-single-declare-module.json", + }, +}); + +ruleTester.run("no-single-declare-module", rule, { + invalid: [ + { + code: ` + declare module "foo" {} + + // Other global declarations don't affect this. They should go in "declare global". + interface I {} + `, + errors: [ + { + line: 2, + messageId: "oneModuleDeclaration", + }, + ], + }, + ], + valid: [ + { + code: ` + import x from "x"; + declare module "foo" {} + `, + }, + { + code: ` + declare module "foo" {} + declare module "bar" {} + `, + }, + { + code: ` + declare module "*.svg" {} + `, + }, + ], +}); diff --git a/packages/dtslint/test/no-single-declare-module/augmentation.d.ts.lint b/packages/dtslint/test/no-single-declare-module/augmentation.d.ts.lint deleted file mode 100644 index 751d5e6dd8..0000000000 --- a/packages/dtslint/test/no-single-declare-module/augmentation.d.ts.lint +++ /dev/null @@ -1,3 +0,0 @@ -import x from "x"; - -declare module "foo" {} diff --git a/packages/dtslint/test/no-single-declare-module/multiple.d.ts.lint b/packages/dtslint/test/no-single-declare-module/multiple.d.ts.lint deleted file mode 100644 index 6ddb31fe88..0000000000 --- a/packages/dtslint/test/no-single-declare-module/multiple.d.ts.lint +++ /dev/null @@ -1,2 +0,0 @@ -declare module "foo" {} -declare module "bar" {} diff --git a/packages/dtslint/test/no-single-declare-module/tslint.json b/packages/dtslint/test/no-single-declare-module/tslint.json deleted file mode 100644 index c6b13c3fcf..0000000000 --- a/packages/dtslint/test/no-single-declare-module/tslint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rulesDirectory": ["../../dist/rules"], - "rules": { - "no-single-declare-module": true - } -} diff --git a/packages/dtslint/test/no-single-declare-module/wildcard.d.ts.lint b/packages/dtslint/test/no-single-declare-module/wildcard.d.ts.lint deleted file mode 100644 index 794d08e55e..0000000000 --- a/packages/dtslint/test/no-single-declare-module/wildcard.d.ts.lint +++ /dev/null @@ -1 +0,0 @@ -declare module "*.svg" {} diff --git a/packages/dtslint/test/no-single-declare-module/wrong.d.ts.lint b/packages/dtslint/test/no-single-declare-module/wrong.d.ts.lint deleted file mode 100644 index a77ecd6cdb..0000000000 --- a/packages/dtslint/test/no-single-declare-module/wrong.d.ts.lint +++ /dev/null @@ -1,5 +0,0 @@ -declare module "foo" {} -~~~~~~~~~~~~~~~~~~~~~~~ [File has only 1 ambient module declaration. Move the contents outside the ambient module block, rename the file to match the ambient module name, and remove the block. See: https://github.com/microsoft/DefinitelyTyped-tools/blob/master/packages/dtslint/docs/no-single-declare-module.md] - -// Other global declarations don't affect this. They should go in "declare global". -interface I {} diff --git a/packages/dtslint/test/tsconfig.no-single-declare-module.json b/packages/dtslint/test/tsconfig.no-single-declare-module.json new file mode 100644 index 0000000000..38f0dbf6ae --- /dev/null +++ b/packages/dtslint/test/tsconfig.no-single-declare-module.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext" + }, + "files": ["file.ts"] +} From 7eee69d903df25df5e0b8d1f3c7506ec4ddc6893 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 25 Mar 2023 01:11:03 -0400 Subject: [PATCH 2/5] lint fix --- packages/dtslint/src/rules/no-single-declare-module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dtslint/src/rules/no-single-declare-module.ts b/packages/dtslint/src/rules/no-single-declare-module.ts index aae9db6f57..6e45e8ac1d 100644 --- a/packages/dtslint/src/rules/no-single-declare-module.ts +++ b/packages/dtslint/src/rules/no-single-declare-module.ts @@ -1,4 +1,4 @@ -import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { ESLintUtils } from "@typescript-eslint/utils"; import * as ts from "typescript"; import { createRule } from "../util"; From 8f6f55f29666bf0864308ec8dbbd69da6ba3345d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:18:00 -0700 Subject: [PATCH 3/5] Move eslint rule to eslint-plugin Bad merge. --- .../src/rules/no-single-declare-module.ts | 0 .../test/no-single-declare-module.test.ts | 0 .../test/tsconfig.no-single-declare-module.json | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/{dtslint => eslint-plugin}/src/rules/no-single-declare-module.ts (100%) rename packages/{dtslint => eslint-plugin}/test/no-single-declare-module.test.ts (100%) rename packages/{dtslint => eslint-plugin}/test/tsconfig.no-single-declare-module.json (100%) diff --git a/packages/dtslint/src/rules/no-single-declare-module.ts b/packages/eslint-plugin/src/rules/no-single-declare-module.ts similarity index 100% rename from packages/dtslint/src/rules/no-single-declare-module.ts rename to packages/eslint-plugin/src/rules/no-single-declare-module.ts diff --git a/packages/dtslint/test/no-single-declare-module.test.ts b/packages/eslint-plugin/test/no-single-declare-module.test.ts similarity index 100% rename from packages/dtslint/test/no-single-declare-module.test.ts rename to packages/eslint-plugin/test/no-single-declare-module.test.ts diff --git a/packages/dtslint/test/tsconfig.no-single-declare-module.json b/packages/eslint-plugin/test/tsconfig.no-single-declare-module.json similarity index 100% rename from packages/dtslint/test/tsconfig.no-single-declare-module.json rename to packages/eslint-plugin/test/tsconfig.no-single-declare-module.json From 905e9ea1b39256cbca56ca011ef8bca6330a0d79 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:06:52 -0700 Subject: [PATCH 4/5] Add no-single-declare-module to default list in eslint-plugin --- packages/eslint-plugin/src/rules/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 7efc50f92a..4892fa7bb2 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -15,6 +15,7 @@ import * as noUselessFiles from "./no-useless-files"; import * as preferDeclareFunction from "./prefer-declare-function"; import * as redundantUndefined from "./redundant-undefined"; import * as strictExportDeclareModifiers from "./strict-export-declare-modifiers"; +import * as noSingleDeclareModule from './no-single-declare-module'; export const rules = { "dt-header": dtHeader, @@ -34,4 +35,5 @@ export const rules = { "prefer-declare-function": preferDeclareFunction, "redundant-undefined": redundantUndefined, "strict-export-declare-modifiers": strictExportDeclareModifiers, + "no-single-declare-module": noSingleDeclareModule, }; From 97e794d052d79c17065985a67437ee7b619dbaf3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 27 Sep 2023 06:05:24 -0700 Subject: [PATCH 5/5] Add changeset --- .changeset/khaki-papayas-sit.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/khaki-papayas-sit.md diff --git a/.changeset/khaki-papayas-sit.md b/.changeset/khaki-papayas-sit.md new file mode 100644 index 0000000000..0a08c9b820 --- /dev/null +++ b/.changeset/khaki-papayas-sit.md @@ -0,0 +1,6 @@ +--- +"@definitelytyped/eslint-plugin": patch +"@definitelytyped/dtslint": patch +--- + +Port no-single-declare-module tslint->eslint