Skip to content

Commit 7558de6

Browse files
TypeScript BotKingwl
TypeScript Bot
andauthored
Cherry-pick PR #39702 into release-4.0 (#39985)
Component commits: cd5dde5 Improve deprecated suggestion node position 6e39ee7 fix typo a593fd0 Simplify code 58f6f3d merge helper function Co-authored-by: kingwl <[email protected]>
1 parent 3055018 commit 7558de6

File tree

4 files changed

+56
-33
lines changed

4 files changed

+56
-33
lines changed

src/compiler/checker.ts

+29-5
Original file line numberDiff line numberDiff line change
@@ -24698,7 +24698,7 @@ namespace ts {
2469824698
if (isNodeOpeningLikeElement) {
2469924699
const jsxOpeningLikeNode = node as JsxOpeningLikeElement;
2470024700
const sig = getResolvedSignature(jsxOpeningLikeNode);
24701-
checkDeprecatedSignature(sig, node);
24701+
checkDeprecatedSignature(sig, <JsxOpeningLikeElement>node);
2470224702
checkJsxReturnAssignableToAppropriateBound(getJsxReferenceKind(jsxOpeningLikeNode), getReturnTypeOfSignature(sig), jsxOpeningLikeNode);
2470324703
}
2470424704
}
@@ -27581,9 +27581,34 @@ namespace ts {
2758127581
return returnType;
2758227582
}
2758327583

27584-
function checkDeprecatedSignature(signature: Signature, node: Node) {
27584+
function checkDeprecatedSignature(signature: Signature, node: CallLikeExpression) {
2758527585
if (signature.declaration && signature.declaration.flags & NodeFlags.Deprecated) {
27586-
errorOrSuggestion(/*isError*/ false, node, Diagnostics._0_is_deprecated, signatureToString(signature));
27586+
const suggestionNode = getDeprecatedSuggestionNode(node);
27587+
errorOrSuggestion(/*isError*/ false, suggestionNode, Diagnostics._0_is_deprecated, signatureToString(signature));
27588+
}
27589+
}
27590+
27591+
function getDeprecatedSuggestionNode(node: Node): Node {
27592+
node = skipParentheses(node);
27593+
switch (node.kind) {
27594+
case SyntaxKind.CallExpression:
27595+
case SyntaxKind.Decorator:
27596+
case SyntaxKind.NewExpression:
27597+
return getDeprecatedSuggestionNode((<Decorator | CallExpression | NewExpression>node).expression);
27598+
case SyntaxKind.TaggedTemplateExpression:
27599+
return getDeprecatedSuggestionNode((<TaggedTemplateExpression>node).tag);
27600+
case SyntaxKind.JsxOpeningElement:
27601+
case SyntaxKind.JsxSelfClosingElement:
27602+
return getDeprecatedSuggestionNode((<JsxOpeningLikeElement>node).tagName);
27603+
case SyntaxKind.ElementAccessExpression:
27604+
return (<ElementAccessExpression>node).argumentExpression;
27605+
case SyntaxKind.PropertyAccessExpression:
27606+
return (<PropertyAccessExpression>node).name;
27607+
case SyntaxKind.TypeReference:
27608+
const typeReference = <TypeReferenceNode>node;
27609+
return isQualifiedName(typeReference.typeName) ? typeReference.typeName.right : typeReference;
27610+
default:
27611+
return node;
2758727612
}
2758827613
}
2758927614

@@ -30978,8 +31003,7 @@ namespace ts {
3097831003
const symbol = getNodeLinks(node).resolvedSymbol;
3097931004
if (symbol) {
3098031005
if (some(symbol.declarations, d => isTypeDeclaration(d) && !!(d.flags & NodeFlags.Deprecated))) {
30981-
const diagLocation = isTypeReferenceNode(node) && isQualifiedName(node.typeName) ? node.typeName.right : node;
30982-
errorOrSuggestion(/* isError */ false, diagLocation, Diagnostics._0_is_deprecated, symbol.escapedName as string);
31006+
errorOrSuggestion(/* isError */ false, getDeprecatedSuggestionNode(node), Diagnostics._0_is_deprecated, symbol.escapedName as string);
3098331007
}
3098431008
if (type.flags & TypeFlags.Enum && symbol.flags & SymbolFlags.EnumMember) {
3098531009
error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));

tests/cases/fourslash/jsdocDeprecated_suggestion1.ts

+15-16
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
//// export namespace foo {
66
//// /** @deprecated */
77
//// export function faff () { }
8-
//// [|faff()|]
8+
//// [|faff|]()
99
//// }
10-
//// const [|a|] = [|foo.faff()|]
10+
//// const [|a|] = foo.[|faff|]()
1111
//// foo[[|"faff"|]]
1212
//// const { [|faff|] } = foo
13-
//// [|faff()|]
13+
//// [|faff|]()
1414
//// /** @deprecated */
1515
//// export function bar () {
16-
//// [|foo?.faff()|]
16+
//// foo?.[|faff|]()
1717
//// }
18-
//// [|foo?.["faff"]?.()|]
19-
//// [|bar()|];
18+
//// foo?.[[|"faff"|]]?.()
19+
//// [|bar|]();
2020
//// /** @deprecated */
2121
//// export interface Foo {
2222
//// /** @deprecated */
@@ -37,8 +37,8 @@
3737
//// constructor() {
3838
//// }
3939
//// }
40-
//// var c = [|new C()|]
41-
//// [|c.m()|]
40+
//// var c = new [|C|]()
41+
//// c.[|m|]()
4242
//// c.[|m|]
4343
//// new [|D|]()
4444
//// C
@@ -51,26 +51,26 @@
5151
//// return <div></div>
5252
//// }
5353
//// [|Compi|];
54-
//// [|<Compi />|];
55-
//// [|<Compi {...props}>|]<div></div></[|Compi|]>;
54+
//// <[|Compi|] />;
55+
//// <[|Compi|] {...props}><div></div></[|Compi|]>;
5656
//// /** @deprecated */
5757
//// function ttf(_x: unknown) {
5858
//// }
59-
//// [|ttf``|]
59+
//// [|ttf|]``
6060
//// [|ttf|]
6161
//// /** @deprecated */
6262
//// function dec(_c: unknown) { }
6363
//// [|dec|]
64-
//// [|@dec|]
64+
//// @[|dec|]
6565
//// class K { }
6666

6767
// @Filename: b.ts
6868
//// // imports and aliases
6969
//// import * as f from './a';
7070
//// import { [|bar|], [|QW|] } from './a';
71-
//// [|f.bar()|];
72-
//// [|f.foo.faff()|];
73-
//// [|bar()|];
71+
//// f.[|bar|]();
72+
//// f.foo.[|faff|]();
73+
//// [|bar|]();
7474
//// type Z = [|QW|];
7575
//// type A = f.[|Foo|];
7676
//// type B = f.[|QW|];
@@ -79,7 +79,6 @@
7979

8080
goTo.file('a.ts')
8181
const ranges = test.ranges();
82-
8382
verify.getSuggestionDiagnostics([
8483
{
8584
"code": 6385,

tests/cases/fourslash/jsdocDeprecated_suggestion2.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
//// /** @deprecated */
66
//// declare function foo(): undefined;
77
//// declare function foo (a?: string): number | undefined;
8-
//// [|foo()|];
8+
//// [|foo|]();
99
//// foo('');
1010
//// foo;
1111

1212
//// /** @deprecated */
1313
//// declare function bar(): number;
14-
//// [|bar()|];
14+
//// [|bar|]();
1515
//// [|bar|];
1616

1717
//// /** @deprecated */
1818
//// declare function baz(): number;
1919
//// /** @deprecated */
2020
//// declare function baz(): number | undefined;
21-
//// [|baz()|];
21+
//// [|baz|]();
2222
//// [|baz|];
2323

2424
//// interface Foo {
@@ -27,7 +27,7 @@
2727
//// (a: number): void
2828
//// }
2929
//// declare const f: Foo;
30-
//// [|f()|];
30+
//// [|f|]();
3131
//// f(1);
3232

3333
//// interface T {
@@ -37,15 +37,15 @@
3737
//// }
3838
//// declare const t: T;
3939
//// t.createElement();
40-
//// [|t.createElement('xmp')|];
40+
//// t.[|createElement|]('xmp');
4141

4242
//// declare class C {
4343
//// /** @deprecated */
4444
//// constructor ();
4545
//// constructor(v: string)
4646
//// }
4747
//// C;
48-
//// const c = [|new C()|];
48+
//// const c = new [|C|]();
4949

5050
//// interface Ca {
5151
//// /** @deprecated */
@@ -61,10 +61,10 @@
6161
//// declare const cb: Cb;
6262
//// ca;
6363
//// cb;
64-
//// [|ca()|];
64+
//// [|ca|]();
6565
//// cb();
6666
//// new ca();
67-
//// [|new cb()|];
67+
//// new [|cb|]();
6868

6969
const ranges = test.ranges();
7070
verify.getSuggestionDiagnostics([

tests/cases/fourslash/jsdocDeprecated_suggestion3.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
//// declare function b(): void
1414
//// declare const tb: b;
1515
//// [|b|]
16-
//// [|b()|];
16+
//// [|b|]();
1717

1818
//// interface c { }
1919
//// /** @deprecated */
2020
//// declare function c(): void
2121
//// declare function c(a: number): void
2222
//// declare const tc: c;
2323
//// c;
24-
//// [|c()|];
24+
//// [|c|]();
2525
//// c(1);
2626

2727
//// /** @deprecated */
@@ -38,8 +38,8 @@
3838
//// /** @deprecated */
3939
//// declare function e(a: number): void
4040
//// [|e|];
41-
//// [|e()|];
42-
//// [|e(1)|];
41+
//// [|e|]();
42+
//// [|e|](1);
4343

4444
//// /** @deprecated */
4545
//// interface f { a: number }

0 commit comments

Comments
 (0)