From 7c3356d0f07b5a0ed27e94898ea1638bbcdadb59 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 14 Dec 2024 16:00:13 +0900 Subject: [PATCH 1/3] fix: no-deprecated --- .../eslint-plugin/src/rules/no-deprecated.ts | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index b39fb0609d35..a365958bef24 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -94,10 +94,13 @@ export default createRule({ case AST_NODE_TYPES.Property: // foo in "const { foo } = bar" will be processed twice, as parent.key // and parent.value. The second is treated as a declaration. - return ( - (parent.shorthand && parent.value === node) || - parent.parent.type === AST_NODE_TYPES.ObjectExpression - ); + if (parent.shorthand && parent.value === node) { + return parent.parent.type === AST_NODE_TYPES.ObjectPattern; + } + if (parent.value === node) { + return false; + } + return parent.parent.type === AST_NODE_TYPES.ObjectExpression; case AST_NODE_TYPES.AssignmentPattern: // foo in "const { foo = "" } = bar" will be processed twice, as parent.parent.key @@ -289,6 +292,24 @@ export default createRule({ return getJsDocDeprecation(symbol); } + function checkDeprecatedInObjectValue( + node: TSESTree.Identifier | TSESTree.JSXIdentifier, + ): string | undefined { + const symbol = services.getSymbolAtLocation(node); + if (symbol === undefined) { + return undefined; + } + + const jsDocTags = symbol.getJsDocTags(checker); + const deprecatedTag = jsDocTags.find(tag => tag.name === 'deprecated'); + if (deprecatedTag === undefined) { + return undefined; + } + + const displayParts = deprecatedTag.text; + return displayParts ? ts.displayPartsToString(displayParts) : ''; + } + function getDeprecationReason(node: IdentifierLike): string | undefined { const callLikeNode = getCallLikeNode(node); if (callLikeNode) { @@ -306,8 +327,11 @@ export default createRule({ node.parent.type === AST_NODE_TYPES.Property && node.type !== AST_NODE_TYPES.Super ) { - return getJsDocDeprecation( - services.getTypeAtLocation(node.parent.parent).getProperty(node.name), + const property = services + .getTypeAtLocation(node.parent.parent) + .getProperty(node.name); + return ( + getJsDocDeprecation(property) ?? checkDeprecatedInObjectValue(node) ); } return searchForDeprecationInAliasesChain( From fdccbb75bc835d577e632d5eebeee0a544db247e Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 14 Dec 2024 16:00:47 +0900 Subject: [PATCH 2/3] test: add test --- .../tests/rules/no-deprecated.test.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts index 8bbbe83a0837..39f3947891ef 100644 --- a/packages/eslint-plugin/tests/rules/no-deprecated.test.ts +++ b/packages/eslint-plugin/tests/rules/no-deprecated.test.ts @@ -681,6 +681,36 @@ ruleTester.run('no-deprecated', rule, { }, ], }, + { + code: ` + /** @deprecated */ + declare const test: string; + const myObj = { + prop: test, + deep: { + prop: test, + }, + }; + `, + errors: [ + { + column: 17, + data: { name: 'test' }, + endColumn: 21, + endLine: 5, + line: 5, + messageId: 'deprecated', + }, + { + column: 19, + data: { name: 'test' }, + endColumn: 23, + endLine: 7, + line: 7, + messageId: 'deprecated', + }, + ], + }, { code: ` /** @deprecated */ const a = { b: 1 }; From d871b5587885f26b3c8091dfc055d70b5240e652 Mon Sep 17 00:00:00 2001 From: Hasegawa-Yukihiro Date: Sat, 14 Dec 2024 16:10:23 +0900 Subject: [PATCH 3/3] refactor: delete unnecessary function --- .../eslint-plugin/src/rules/no-deprecated.ts | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-deprecated.ts b/packages/eslint-plugin/src/rules/no-deprecated.ts index a365958bef24..7fb966a249b0 100644 --- a/packages/eslint-plugin/src/rules/no-deprecated.ts +++ b/packages/eslint-plugin/src/rules/no-deprecated.ts @@ -292,24 +292,6 @@ export default createRule({ return getJsDocDeprecation(symbol); } - function checkDeprecatedInObjectValue( - node: TSESTree.Identifier | TSESTree.JSXIdentifier, - ): string | undefined { - const symbol = services.getSymbolAtLocation(node); - if (symbol === undefined) { - return undefined; - } - - const jsDocTags = symbol.getJsDocTags(checker); - const deprecatedTag = jsDocTags.find(tag => tag.name === 'deprecated'); - if (deprecatedTag === undefined) { - return undefined; - } - - const displayParts = deprecatedTag.text; - return displayParts ? ts.displayPartsToString(displayParts) : ''; - } - function getDeprecationReason(node: IdentifierLike): string | undefined { const callLikeNode = getCallLikeNode(node); if (callLikeNode) { @@ -330,9 +312,8 @@ export default createRule({ const property = services .getTypeAtLocation(node.parent.parent) .getProperty(node.name); - return ( - getJsDocDeprecation(property) ?? checkDeprecatedInObjectValue(node) - ); + const symbol = services.getSymbolAtLocation(node); + return getJsDocDeprecation(property) ?? getJsDocDeprecation(symbol); } return searchForDeprecationInAliasesChain( services.getSymbolAtLocation(node),