From a1d06d3f70b94b4852fad9e3fc5acbeeac2b0999 Mon Sep 17 00:00:00 2001 From: mainframev Date: Mon, 30 Jun 2025 16:45:05 +0200 Subject: [PATCH 1/5] fix(eslint-plugin): add support of exports/reexports to no-deprecated rule --- .../eslint-plugin/src/rules/no-deprecated.ts | 20 ++++-- .../tests/fixtures/deprecated.ts | 5 ++ .../tests/rules/no-deprecated.test.ts | 64 +++++++++++++++++++ 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index 725ddaf3fce9..eb12b788e926 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -161,13 +161,11 @@ export default createRule({ } } - function isInsideExportOrImport(node: TSESTree.Node): boolean { + function isInsideImport(node: TSESTree.Node): boolean { let current = node; while (true) { switch (current.type) { - case AST_NODE_TYPES.ExportAllDeclaration: - case AST_NODE_TYPES.ExportNamedDeclaration: case AST_NODE_TYPES.ImportDeclaration: return true; @@ -178,6 +176,7 @@ export default createRule({ case AST_NODE_TYPES.FunctionDeclaration: case AST_NODE_TYPES.FunctionExpression: case AST_NODE_TYPES.Program: + case AST_NODE_TYPES.ExportSpecifier: case AST_NODE_TYPES.TSUnionType: case AST_NODE_TYPES.VariableDeclarator: return false; @@ -365,7 +364,7 @@ export default createRule({ } function checkIdentifier(node: IdentifierLike): void { - if (isDeclaration(node) || isInsideExportOrImport(node)) { + if (isDeclaration(node) || isInsideImport(node)) { return; } @@ -436,7 +435,18 @@ export default createRule({ } return { - Identifier: checkIdentifier, + ExportSpecifier(node): void { + const symbol = services.getSymbolAtLocation(node.exported); + + if (searchForDeprecationInAliasesChain(symbol, false) == null) { + checkIdentifier(node.exported as TSESTree.Identifier); + } + }, + Identifier(node): void { + if (node.parent.type !== AST_NODE_TYPES.ExportSpecifier) { + checkIdentifier(node); + } + }, JSXIdentifier(node): void { if (node.parent.type !== AST_NODE_TYPES.JSXClosingElement) { checkIdentifier(node); diff --git a/packages/eslint-plugin/tests/fixtures/deprecated.ts b/packages/eslint-plugin/tests/fixtures/deprecated.ts index 2302eabd3f54..b8dc49fcf16d 100644 --- a/packages/eslint-plugin/tests/fixtures/deprecated.ts +++ b/packages/eslint-plugin/tests/fixtures/deprecated.ts @@ -36,6 +36,11 @@ export { ClassWithDeprecatedConstructor as ReexportedClassWithDeprecatedConstructor, }; +/** @deprecated Reason */ +export type T = { a: string }; + +export type U = { b: string }; + /** @deprecated */ export default { foo: 1, diff --git a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts index 1c8f354886df..ecb14cc817f0 100644 --- a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts +++ b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts @@ -329,6 +329,12 @@ ruleTester.run('no-deprecated', rule, { } ; `, + ` + export { + /** @deprecated */ + foo, + }; + `, { code: ` /** @deprecated */ @@ -3173,5 +3179,63 @@ class B extends A { }, ], }, + { + code: ` + import { deprecatedFunction } from './deprecated'; + + export { deprecatedFunction }; + `, + errors: [ + { + column: 18, + endColumn: 36, + endLine: 4, + line: 4, + messageId: 'deprecated', + }, + ], + }, + { + code: ` + export { deprecatedFunction } from './deprecated'; + `, + errors: [ + { + column: 18, + endColumn: 36, + endLine: 2, + line: 2, + messageId: 'deprecated', + }, + ], + }, + { + code: ` + export type { T, U } from './deprecated'; + `, + errors: [ + { + column: 23, + endColumn: 24, + endLine: 2, + line: 2, + messageId: 'deprecatedWithReason', + }, + ], + }, + { + code: ` + export { default as foo } from './deprecated'; + `, + errors: [ + { + column: 29, + endColumn: 32, + endLine: 2, + line: 2, + messageId: 'deprecated', + }, + ], + }, ], }); From e6b1f419dbe2e346a8b7dad66e30e703a6a01197 Mon Sep 17 00:00:00 2001 From: mainframev Date: Tue, 8 Jul 2025 10:29:37 +0200 Subject: [PATCH 2/5] fixup! fix(eslint-plugin): add support of exports/reexports to no-deprecated rule --- .../eslint-plugin/src/rules/no-deprecated.ts | 7 ++++-- .../tests/rules/no-deprecated.test.ts | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index eb12b788e926..1b89d49c4d08 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -438,8 +438,11 @@ export default createRule({ ExportSpecifier(node): void { const symbol = services.getSymbolAtLocation(node.exported); - if (searchForDeprecationInAliasesChain(symbol, false) == null) { - checkIdentifier(node.exported as TSESTree.Identifier); + if ( + searchForDeprecationInAliasesChain(symbol, false) == null && + node.exported.type === AST_NODE_TYPES.Identifier + ) { + checkIdentifier(node.exported); } }, Identifier(node): void { diff --git a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts index ecb14cc817f0..f18f435ebe92 100644 --- a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts +++ b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts @@ -222,6 +222,15 @@ ruleTester.run('no-deprecated', rule, { default as ts, } from 'typescript'; `, + ` + export { deprecatedFunction as 'bur' } from './deprecated'; + `, + ` + export { 'deprecatedFunction' } from './deprecated'; + `, + ` + export { deprecatedFunction as 'bar' } from './deprecated'; + `, ` namespace A { /** @deprecated */ @@ -3237,5 +3246,19 @@ class B extends A { }, ], }, + { + code: ` + export { deprecatedFunction as bar } from './deprecated'; + `, + errors: [ + { + column: 40, + endColumn: 43, + endLine: 2, + line: 2, + messageId: 'deprecated', + }, + ], + }, ], }); From cad618920173a7bd1c51394a5a3d03bb749c46ca Mon Sep 17 00:00:00 2001 From: mainframev Date: Fri, 11 Jul 2025 15:11:18 +0200 Subject: [PATCH 3/5] fixup! fix(eslint-plugin): add support of exports/reexports to no-deprecated rule --- .../eslint-plugin/src/rules/no-deprecated.ts | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index 1b89d49c4d08..81e5f5d47271 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -170,13 +170,14 @@ export default createRule({ return true; case AST_NODE_TYPES.ArrowFunctionExpression: + case AST_NODE_TYPES.ExportAllDeclaration: + case AST_NODE_TYPES.ExportNamedDeclaration: case AST_NODE_TYPES.BlockStatement: case AST_NODE_TYPES.ClassDeclaration: case AST_NODE_TYPES.TSInterfaceDeclaration: case AST_NODE_TYPES.FunctionDeclaration: case AST_NODE_TYPES.FunctionExpression: case AST_NODE_TYPES.Program: - case AST_NODE_TYPES.ExportSpecifier: case AST_NODE_TYPES.TSUnionType: case AST_NODE_TYPES.VariableDeclarator: return false; @@ -369,11 +370,13 @@ export default createRule({ } const reason = getDeprecationReason(node); + if (reason == null) { return; } const type = services.getTypeAtLocation(node); + if (typeMatchesSomeSpecifier(type, allow, services.program)) { return; } @@ -436,19 +439,30 @@ export default createRule({ return { ExportSpecifier(node): void { + if (node.exported.type !== AST_NODE_TYPES.Identifier) { + return; + } + const symbol = services.getSymbolAtLocation(node.exported); + const aliasDeprecation = getJsDocDeprecation(symbol); - if ( - searchForDeprecationInAliasesChain(symbol, false) == null && - node.exported.type === AST_NODE_TYPES.Identifier - ) { - checkIdentifier(node.exported); + if (aliasDeprecation != null) { + return; } + + checkIdentifier(node.exported); }, Identifier(node): void { - if (node.parent.type !== AST_NODE_TYPES.ExportSpecifier) { - checkIdentifier(node); + if ( + [ + AST_NODE_TYPES.ExportNamedDeclaration, + AST_NODE_TYPES.ExportAllDeclaration, + AST_NODE_TYPES.ExportSpecifier, + ].includes(node.parent.type) + ) { + return; } + checkIdentifier(node); }, JSXIdentifier(node): void { if (node.parent.type !== AST_NODE_TYPES.JSXClosingElement) { From a91cbaaab9d5b522a26b4a63cdd43f547fc3524b Mon Sep 17 00:00:00 2001 From: mainframev Date: Mon, 14 Jul 2025 11:12:03 +0200 Subject: [PATCH 4/5] fixup! fix(eslint-plugin): add support of exports/reexports to no-deprecated rule --- .../eslint-plugin/src/rules/no-deprecated.ts | 36 +++++++++++++------ .../tests/rules/no-deprecated.test.ts | 3 -- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index 81e5f5d47271..ea8630aef11a 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -88,22 +88,39 @@ export default createRule({ ? getJsDocDeprecation(symbol) : undefined; } + + const seen = new Set(); const targetSymbol = checker.getAliasedSymbol(symbol); - while (tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) { - const reason = getJsDocDeprecation(symbol); + let current = symbol; + + while (tsutils.isSymbolFlagSet(current, ts.SymbolFlags.Alias)) { + if (seen.has(current)) { + break; + } + + seen.add(current); + + const reason = getJsDocDeprecation(current); + if (reason != null) { return reason; } - const immediateAliasedSymbol: ts.Symbol | undefined = - symbol.getDeclarations() && checker.getImmediateAliasedSymbol(symbol); - if (!immediateAliasedSymbol) { + + const nextAlias: ts.Symbol | undefined = + current.getDeclarations() && + checker.getImmediateAliasedSymbol(current); + + if (!nextAlias) { break; } - symbol = immediateAliasedSymbol; - if (checkDeprecationsOfAliasedSymbol && symbol === targetSymbol) { - return getJsDocDeprecation(symbol); + + current = nextAlias; + + if (checkDeprecationsOfAliasedSymbol && current === targetSymbol) { + return getJsDocDeprecation(current); } } + return undefined; } @@ -178,6 +195,7 @@ export default createRule({ case AST_NODE_TYPES.FunctionDeclaration: case AST_NODE_TYPES.FunctionExpression: case AST_NODE_TYPES.Program: + case AST_NODE_TYPES.ExportSpecifier: case AST_NODE_TYPES.TSUnionType: case AST_NODE_TYPES.VariableDeclarator: return false; @@ -370,13 +388,11 @@ export default createRule({ } const reason = getDeprecationReason(node); - if (reason == null) { return; } const type = services.getTypeAtLocation(node); - if (typeMatchesSomeSpecifier(type, allow, services.program)) { return; } diff --git a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts index f18f435ebe92..c5e4c8d92140 100644 --- a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts +++ b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts @@ -228,9 +228,6 @@ ruleTester.run('no-deprecated', rule, { ` export { 'deprecatedFunction' } from './deprecated'; `, - ` - export { deprecatedFunction as 'bar' } from './deprecated'; - `, ` namespace A { /** @deprecated */ From 82dd8ad320a02f250eedf45daf51313bcf4261c5 Mon Sep 17 00:00:00 2001 From: mainframev Date: Mon, 14 Jul 2025 17:40:39 +0200 Subject: [PATCH 5/5] fixup! fix(eslint-plugin): add support of exports/reexports to no-deprecated rule --- .../eslint-plugin/src/rules/no-deprecated.ts | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index ea8630aef11a..acecd7363385 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -454,30 +454,31 @@ export default createRule({ } return { - ExportSpecifier(node): void { - if (node.exported.type !== AST_NODE_TYPES.Identifier) { + Identifier(node): void { + const { parent } = node; + + if ( + parent.type === AST_NODE_TYPES.ExportNamedDeclaration || + parent.type === AST_NODE_TYPES.ExportAllDeclaration + ) { return; } - const symbol = services.getSymbolAtLocation(node.exported); - const aliasDeprecation = getJsDocDeprecation(symbol); + if (parent.type === AST_NODE_TYPES.ExportSpecifier) { + // only deal with the alias (exported) side, not the local binding + if (parent.exported !== node) { + return; + } - if (aliasDeprecation != null) { - return; - } + const symbol = services.getSymbolAtLocation(node); + const aliasDeprecation = getJsDocDeprecation(symbol); - checkIdentifier(node.exported); - }, - Identifier(node): void { - if ( - [ - AST_NODE_TYPES.ExportNamedDeclaration, - AST_NODE_TYPES.ExportAllDeclaration, - AST_NODE_TYPES.ExportSpecifier, - ].includes(node.parent.type) - ) { - return; + if (aliasDeprecation != null) { + return; + } } + + // whether it's a plain identifier or the exported alias checkIdentifier(node); }, JSXIdentifier(node): void { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy