mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 12:32:08 -06:00
Fixed crashes when looking up symbols of jsdoc nodes in TS files (#57110)
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
parent
f2bd592838
commit
69e7e57b15
@ -11272,6 +11272,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
if (isParameter(declaration)) {
|
||||
if (!declaration.symbol) {
|
||||
// parameters of function types defined in JSDoc in TS files don't have symbols
|
||||
return;
|
||||
}
|
||||
const func = declaration.parent as FunctionLikeDeclaration;
|
||||
// For a parameter of a set accessor, use the type of the get accessor if one is present
|
||||
if (func.kind === SyntaxKind.SetAccessor && hasBindableName(func)) {
|
||||
|
||||
@ -151,6 +151,7 @@ import {
|
||||
isIdentifier,
|
||||
isImportMeta,
|
||||
isInComment,
|
||||
isInJSFile,
|
||||
isInsideJsxElement,
|
||||
isInsideJsxElementOrAttribute,
|
||||
isInString,
|
||||
@ -245,6 +246,7 @@ import {
|
||||
PrivateIdentifier,
|
||||
Program,
|
||||
PropertyName,
|
||||
PropertySignature,
|
||||
QuickInfo,
|
||||
refactor,
|
||||
RefactorContext,
|
||||
@ -2067,7 +2069,6 @@ export function createLanguageService(
|
||||
const typeChecker = program.getTypeChecker();
|
||||
const nodeForQuickInfo = getNodeForQuickInfo(node);
|
||||
const symbol = getSymbolAtLocationForQuickInfo(nodeForQuickInfo, typeChecker);
|
||||
|
||||
if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
|
||||
const type = shouldGetType(sourceFile, nodeForQuickInfo, position) ? typeChecker.getTypeAtLocation(nodeForQuickInfo) : undefined;
|
||||
return type && {
|
||||
@ -2110,6 +2111,14 @@ export function createLanguageService(
|
||||
function shouldGetType(sourceFile: SourceFile, node: Node, position: number): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
if (
|
||||
node.flags & NodeFlags.JSDoc && !isInJSFile(node) &&
|
||||
((node.parent.kind === SyntaxKind.PropertySignature && (node.parent as PropertySignature).name === node) ||
|
||||
findAncestor(node, n => n.kind === SyntaxKind.Parameter))
|
||||
) {
|
||||
// if we'd request type at those locations we'd get `errorType` that displays confusingly as `any`
|
||||
return false;
|
||||
}
|
||||
return !isLabelName(node) && !isTagName(node) && !isConstTypeReference(node.parent);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.QualifiedName:
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
// === findAllReferences ===
|
||||
// === /tests/cases/fourslash/src/index.ts ===
|
||||
// import { useQuery } from "use-query";
|
||||
// <|const { /*FIND ALL REFS*/[|{| isWriteAccess: true, isDefinition: true |}data|] } = useQuery();|>
|
||||
|
||||
// === Definitions ===
|
||||
// === /tests/cases/fourslash/src/index.ts ===
|
||||
// import { useQuery } from "use-query";
|
||||
// <|const { /*FIND ALL REFS*/[|data|] } = useQuery();|>
|
||||
|
||||
// === Details ===
|
||||
[
|
||||
{
|
||||
"containerKind": "",
|
||||
"containerName": "",
|
||||
"kind": "const",
|
||||
"name": "const data: any",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "const",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "data",
|
||||
"kind": "localName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "any",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,45 @@
|
||||
// === findAllReferences ===
|
||||
// === /tests/cases/fourslash/src/index.ts ===
|
||||
// import { useQuery } from "use-query";
|
||||
// <|const { /*FIND ALL REFS*/[|{| isWriteAccess: true, isDefinition: true |}data|] } = useQuery();|>
|
||||
|
||||
// === Definitions ===
|
||||
// === /tests/cases/fourslash/src/index.ts ===
|
||||
// import { useQuery } from "use-query";
|
||||
// <|const { /*FIND ALL REFS*/[|data|] } = useQuery();|>
|
||||
|
||||
// === Details ===
|
||||
[
|
||||
{
|
||||
"containerKind": "",
|
||||
"containerName": "",
|
||||
"kind": "const",
|
||||
"name": "const data: any",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "const",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "data",
|
||||
"kind": "localName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "any",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,111 @@
|
||||
// === findAllReferences ===
|
||||
// === /tests/cases/fourslash/findReferencesSeeTagInTs.ts ===
|
||||
// <|function [|{| isWriteAccess: true, isDefinition: true |}doStuffWithStuff|]/*FIND ALL REFS*/(stuff: { quantity: number }) {}|>
|
||||
//
|
||||
// declare const stuff: { quantity: number };
|
||||
// /** @see {[|doStuffWithStuff|]} */
|
||||
// if (stuff.quantity) {}
|
||||
|
||||
// === Definitions ===
|
||||
// === /tests/cases/fourslash/findReferencesSeeTagInTs.ts ===
|
||||
// <|function [|doStuffWithStuff|]/*FIND ALL REFS*/(stuff: { quantity: number }) {}|>
|
||||
//
|
||||
// declare const stuff: { quantity: number };
|
||||
// /** @see {doStuffWithStuff} */
|
||||
// if (stuff.quantity) {}
|
||||
|
||||
// === Details ===
|
||||
[
|
||||
{
|
||||
"containerKind": "",
|
||||
"containerName": "",
|
||||
"kind": "function",
|
||||
"name": "function doStuffWithStuff(stuff: {\n quantity: number;\n}): void",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "function",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "doStuffWithStuff",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "stuff",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "{",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "\n",
|
||||
"kind": "lineBreak"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "quantity",
|
||||
"kind": "propertyName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
},
|
||||
{
|
||||
"text": ";",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "\n",
|
||||
"kind": "lineBreak"
|
||||
},
|
||||
{
|
||||
"text": "}",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: node_modules/use-query/package.json
|
||||
////{
|
||||
//// "name": "use-query",
|
||||
//// "types": "index.d.ts"
|
||||
////}
|
||||
// @Filename: node_modules/use-query/index.d.ts
|
||||
////declare function useQuery(): {
|
||||
//// data: string[];
|
||||
////};
|
||||
|
||||
// @Filename: node_modules/other/package.json
|
||||
////{
|
||||
//// "name": "other",
|
||||
//// "types": "index.d.ts"
|
||||
////}
|
||||
// @Filename: node_modules/other/index.d.ts
|
||||
////interface BottomSheetModalProps {
|
||||
//// /**
|
||||
//// * A scrollable node or normal view.
|
||||
//// * @type {({ data: any }?) => any}
|
||||
//// */
|
||||
//// children: ({ data: any }?) => any;
|
||||
////}
|
||||
|
||||
// @Filename: src/index.ts
|
||||
////import { useQuery } from "use-query";
|
||||
////const { /*1*/data } = useQuery();
|
||||
|
||||
verify.baselineFindAllReferences('1');
|
||||
@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @moduleResolution: node
|
||||
|
||||
// @Filename: node_modules/use-query/package.json
|
||||
////{
|
||||
//// "name": "use-query",
|
||||
//// "types": "index.d.ts"
|
||||
////}
|
||||
// @Filename: node_modules/use-query/index.d.ts
|
||||
////declare function useQuery(): {
|
||||
//// data: string[];
|
||||
////};
|
||||
|
||||
// @Filename: node_modules/use-query/package.json
|
||||
////{
|
||||
//// "name": "other",
|
||||
//// "types": "index.d.ts"
|
||||
////}
|
||||
// @Filename: node_modules/other/index.d.ts
|
||||
////interface BottomSheetModalProps {
|
||||
//// /**
|
||||
//// * A scrollable node or normal view.
|
||||
//// * @type null | (({ data: any }?) => any)
|
||||
//// */
|
||||
//// children: null | (({ data: any }?) => any);
|
||||
////}
|
||||
|
||||
// @Filename: src/index.ts
|
||||
////import { useQuery } from "use-query";
|
||||
////const { /*1*/data } = useQuery();
|
||||
|
||||
verify.baselineFindAllReferences('1');
|
||||
9
tests/cases/fourslash/findReferencesSeeTagInTs.ts
Normal file
9
tests/cases/fourslash/findReferencesSeeTagInTs.ts
Normal file
@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// function doStuffWithStuff/*1*/(stuff: { quantity: number }) {}
|
||||
////
|
||||
//// declare const stuff: { quantity: number };
|
||||
//// /** @see {doStuffWithStuff} */
|
||||
//// if (stuff.quantity) {}
|
||||
|
||||
verify.baselineFindAllReferences("1");
|
||||
@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////** @type {({ /*1*/data: any }?) => { data: string[] }} */
|
||||
////function useQuery({ data }): { data: string[] } {
|
||||
//// return {
|
||||
//// data,
|
||||
//// };
|
||||
////}
|
||||
|
||||
verify.quickInfoAt("1", "");
|
||||
62
tests/cases/fourslash/quickInfoInJsdocInTsFile1.ts
Normal file
62
tests/cases/fourslash/quickInfoInJsdocInTsFile1.ts
Normal file
@ -0,0 +1,62 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//// /** @type {() => { /*1*/data: string[] }} */
|
||||
//// function test(): { data: string[] } {
|
||||
//// return {
|
||||
//// data: [],
|
||||
//// };
|
||||
//// }
|
||||
////
|
||||
//// /** @returns {{ /*2*/data: string[] }} */
|
||||
//// function test2(): { data: string[] } {
|
||||
//// return {
|
||||
//// data: [],
|
||||
//// };
|
||||
//// }
|
||||
////
|
||||
//// /** @type {{ /*3*/bar: string; }} */
|
||||
//// const test3 = { bar: '' };
|
||||
////
|
||||
//// type SomeObj = { bar: string; };
|
||||
//// /** @type {SomeObj/*4*/} */
|
||||
//// const test4 = { bar: '' }
|
||||
////
|
||||
//// /**
|
||||
//// * @param/*5*/ stuff/*6*/ Stuff to do stuff with
|
||||
//// */
|
||||
//// function doStuffWithStuff(stuff: { quantity: number }) {}
|
||||
////
|
||||
//// declare const stuff: { quantity: number };
|
||||
//// /** @see {doStuffWithStuff/*7*/} */
|
||||
//// if (stuff.quantity) {}
|
||||
////
|
||||
//// /** @type {(a/*8*/: string) => void} */
|
||||
//// function test2(a: string) {}
|
||||
|
||||
verify.quickInfoAt("1", "");
|
||||
verify.quickInfoAt("2", "");
|
||||
verify.quickInfoAt("3", "");
|
||||
verify.quickInfoAt("4", `type SomeObj = {
|
||||
bar: string;
|
||||
}`);
|
||||
verify.quickInfoAt(
|
||||
"5",
|
||||
`(parameter) stuff: {
|
||||
quantity: number;
|
||||
}`,
|
||||
"Stuff to do stuff with"
|
||||
);
|
||||
verify.quickInfoAt(
|
||||
"6",
|
||||
`(parameter) stuff: {
|
||||
quantity: number;
|
||||
}`,
|
||||
"Stuff to do stuff with"
|
||||
);
|
||||
verify.quickInfoAt(
|
||||
"7",
|
||||
`function doStuffWithStuff(stuff: {
|
||||
quantity: number;
|
||||
}): void`,
|
||||
);
|
||||
verify.quickInfoAt("8", "");
|
||||
Loading…
x
Reference in New Issue
Block a user