-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Jsdoc property description #50269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jsdoc property description #50269
Changes from all commits
0c51f47
3add1f9
c74367d
84e4611
8ba9d2c
6af103b
f404c80
50372d9
868ef27
ecfbf8b
cca8b27
b7011f9
bef80c2
38e27cc
c42189b
6440898
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -439,6 +439,7 @@ namespace ts { | |
| getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), | ||
| getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === IndexKind.String ? stringType : numberType), | ||
| getIndexInfosOfType, | ||
| getIndexInfosOfIndexSymbol, | ||
| getSignaturesOfType, | ||
| getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType), | ||
| getIndexType: type => getIndexType(type), | ||
|
|
@@ -42554,6 +42555,35 @@ namespace ts { | |
|
|
||
| if (name.kind === SyntaxKind.PropertyAccessExpression) { | ||
| checkPropertyAccessExpression(name, CheckMode.Normal); | ||
| if (!links.resolvedSymbol) { | ||
| const expressionType = checkExpressionCached(name.expression); | ||
| const infos = getApplicableIndexInfos(expressionType, getLiteralTypeFromPropertyName(name.name)); | ||
| if (infos.length && (expressionType as ObjectType).members) { | ||
| const resolved = resolveStructuredTypeMembers(expressionType as ObjectType); | ||
| const symbol = resolved.members.get(InternalSymbolName.Index); | ||
| if (infos === getIndexInfosOfType(expressionType)) { | ||
| links.resolvedSymbol = symbol; | ||
| } | ||
| else if (symbol) { | ||
| const symbolLinks = getSymbolLinks(symbol); | ||
| const declarationList = mapDefined(infos, i => i.declaration); | ||
| const nodeListId = map(declarationList, getNodeId).join(","); | ||
| if (!symbolLinks.filteredIndexSymbolCache) { | ||
| symbolLinks.filteredIndexSymbolCache = new Map(); | ||
| } | ||
| if (symbolLinks.filteredIndexSymbolCache.has(nodeListId)) { | ||
| links.resolvedSymbol = symbolLinks.filteredIndexSymbolCache.get(nodeListId)!; | ||
| } | ||
| else { | ||
| const copy = createSymbol(SymbolFlags.Signature, InternalSymbolName.Index); | ||
| copy.declarations = mapDefined(infos, i => i.declaration); | ||
| copy.parent = expressionType.aliasSymbol ? expressionType.aliasSymbol : expressionType.symbol ? expressionType.symbol : getSymbolAtLocation(copy.declarations[0].parent); | ||
| symbolLinks.filteredIndexSymbolCache.set(nodeListId, copy); | ||
| links.resolvedSymbol = symbolLinks.filteredIndexSymbolCache.get(nodeListId)!; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
danay1999 marked this conversation as resolved.
Outdated
|
||
| else { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we creating a new symbol here? Given interface Foo { [key: string]: any }
declare let foo: Foo;
foo.bar;
foo.bar;
foo.bar;
foo.bar;every mention of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested it to handle filtering the symbol's declarations to only those matching the use site in order to handle when multiple index signatures exist (since all index signatures usually get tossed into the same __index symbol, rather than each having their own). Certainly, if the filtered list of applicable index signature declarations is identical to the full list, reusing the original symbol should be OK, and we could probably cache and reuse symbols when they're the same declaration subset across usages.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New approach, as explained by Wesley Wigham (@weswigham)
|
||
| checkQualifiedName(name, CheckMode.Normal); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,6 +64,7 @@ namespace ts.SymbolDisplay { | |
| if (flags & SymbolFlags.SetAccessor) return ScriptElementKind.memberSetAccessorElement; | ||
| if (flags & SymbolFlags.Method) return ScriptElementKind.memberFunctionElement; | ||
| if (flags & SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement; | ||
| if (flags & SymbolFlags.Signature) return ScriptElementKind.indexSignatureElement; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am actually not sure about this. The function returns ScriptElementKind.memberVariableElement ('property') for |
||
|
|
||
| if (flags & SymbolFlags.Property) { | ||
| if (flags & SymbolFlags.Transient && (symbol as TransientSymbol).checkFlags & CheckFlags.Synthetic) { | ||
|
|
@@ -506,19 +507,19 @@ namespace ts.SymbolDisplay { | |
| else { | ||
| addPrefixForAnyFunctionOrVar(symbol, symbolKind); | ||
| } | ||
|
|
||
| // For properties, variables and local vars: show the type | ||
| if (symbolKind === ScriptElementKind.memberVariableElement || | ||
| symbolKind === ScriptElementKind.memberGetAccessorElement || | ||
| symbolKind === ScriptElementKind.memberSetAccessorElement || | ||
| symbolKind === ScriptElementKind.jsxAttribute || | ||
| symbolFlags & SymbolFlags.Variable || | ||
| symbolKind === ScriptElementKind.localVariableElement || | ||
| symbolKind === ScriptElementKind.indexSignatureElement || | ||
| isThisExpression) { | ||
| displayParts.push(punctuationPart(SyntaxKind.ColonToken)); | ||
| displayParts.push(spacePart()); | ||
| // If the type is type parameter, format it specially | ||
| if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter) { | ||
| if (type.symbol && type.symbol.flags & SymbolFlags.TypeParameter && symbolKind !== ScriptElementKind.indexSignatureElement) { | ||
| const typeParameterParts = mapToDisplayParts(writer => { | ||
| const param = typeChecker.typeParameterToDeclaration(type as TypeParameter, enclosingDeclaration, symbolDisplayNodeBuilderFlags)!; | ||
| getPrinter().writeNode(EmitHint.Unspecified, param, getSourceFileOfNode(getParseTreeNode(enclosingDeclaration)), writer); | ||
|
|
@@ -639,13 +640,38 @@ namespace ts.SymbolDisplay { | |
| } | ||
|
|
||
| function addFullSymbolName(symbolToDisplay: Symbol, enclosingDeclaration?: Node) { | ||
| let indexInfos; | ||
|
|
||
| if (alias && symbolToDisplay === symbol) { | ||
| symbolToDisplay = alias; | ||
| } | ||
| const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, | ||
| SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); | ||
| addRange(displayParts, fullSymbolDisplayParts); | ||
| if (symbolKind === ScriptElementKind.indexSignatureElement) { | ||
| indexInfos = typeChecker.getIndexInfosOfIndexSymbol(symbolToDisplay); | ||
| } | ||
|
|
||
| let fullSymbolDisplayParts: SymbolDisplayPart[] = []; | ||
| if (symbolToDisplay.flags & SymbolFlags.Signature && indexInfos) { | ||
| if (symbolToDisplay.parent) { | ||
| fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay.parent); | ||
| } | ||
| fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.OpenBracketToken)); | ||
| //Needed to handle more than one type of index | ||
| indexInfos.forEach((info, i) => { | ||
| //Needed to handle template literals | ||
| fullSymbolDisplayParts.push(...typeToDisplayParts(typeChecker, info.keyType)); | ||
| if (i !== indexInfos.length - 1) { | ||
| fullSymbolDisplayParts.push(spacePart()); | ||
| fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.BarToken)); | ||
| fullSymbolDisplayParts.push(spacePart()); | ||
| } | ||
| }); | ||
| fullSymbolDisplayParts.push(punctuationPart(SyntaxKind.CloseBracketToken)); | ||
| } | ||
| else { | ||
| fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, | ||
| SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); | ||
| } | ||
| addRange(displayParts, fullSymbolDisplayParts); | ||
| if (symbol.flags & SymbolFlags.Optional) { | ||
| displayParts.push(punctuationPart(SyntaxKind.QuestionToken)); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.