From d0fbb803f7579edc656cd20656c1940f17fe604d Mon Sep 17 00:00:00 2001 From: Zach Kirsch Date: Wed, 20 Apr 2022 15:15:05 -0400 Subject: [PATCH 1/3] Add failing test --- .../eslint-plugin/tests/rules/no-namespace.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-namespace.test.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts index 3bb9079b3fc3..6f4948c26e9d 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.test.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -49,6 +49,16 @@ declare namespace foo { namespace bar { namespace baz {} } +} + `, + options: [{ allowDeclarations: true }], + }, + { + code: ` +export declare namespace foo { + export namespace bar { + namespace baz {} + } } `, options: [{ allowDeclarations: true }], From 64699f5aca91c5200df83178fdb85d45e270d12c Mon Sep 17 00:00:00 2001 From: Zach Kirsch Date: Wed, 20 Apr 2022 15:55:23 -0400 Subject: [PATCH 2/3] Fix isDeclaration to look recursively --- packages/eslint-plugin/src/rules/no-namespace.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index c8c3ff213954..c7183444e8b8 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -46,12 +46,15 @@ export default util.createRule({ create(context, [{ allowDeclarations, allowDefinitionFiles }]) { const filename = context.getFilename(); - function isDeclaration(node: TSESTree.TSModuleDeclaration): boolean { - return ( - node.declare === true || - (node.parent!.parent?.type === AST_NODE_TYPES.TSModuleDeclaration && - isDeclaration(node.parent!.parent)) - ); + function isDeclaration(node: TSESTree.Node): boolean { + if ( + node.type === AST_NODE_TYPES.TSModuleDeclaration && + node.declare === true + ) { + return true; + } + + return node.parent != null && isDeclaration(node.parent); } return { From 58c139122fe7b6cba9499852f8bcd8a54a11cd77 Mon Sep 17 00:00:00 2001 From: Zach Kirsch Date: Thu, 21 Apr 2022 22:00:45 -0700 Subject: [PATCH 3/3] Add more tests --- .../tests/rules/no-namespace.test.ts | 302 ++++++++++++++++++ 1 file changed, 302 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-namespace.test.ts b/packages/eslint-plugin/tests/rules/no-namespace.test.ts index 6f4948c26e9d..11d9d1a6fca7 100644 --- a/packages/eslint-plugin/tests/rules/no-namespace.test.ts +++ b/packages/eslint-plugin/tests/rules/no-namespace.test.ts @@ -261,5 +261,307 @@ namespace Foo.Bar { }, ], }, + { + code: ` +namespace A { + namespace B { + declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 3, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 3, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + declare namespace B { + namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + export declare namespace B { + namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + export declare namespace B { + declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + export declare namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + declare namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +namespace A { + export namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 1, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 10, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + namespace B { + declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 3, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 3, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + declare namespace B { + namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + export declare namespace B { + namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + export declare namespace B { + declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + export declare namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + declare namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + ], + options: [{ allowDeclarations: true }], + }, + { + code: ` +export namespace A { + export namespace B { + export declare namespace C {} + } +} + `, + errors: [ + { + messageId: 'moduleSyntaxIsPreferred', + line: 2, + column: 8, + }, + { + messageId: 'moduleSyntaxIsPreferred', + line: 3, + column: 10, + }, + ], + options: [{ allowDeclarations: true }], + }, ], });