From 790f65d15b0a9775ce2e3a6bcf44984bbb238bcf Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 22 Feb 2018 13:22:34 -0800 Subject: [PATCH] Simplify isJumpStatementTarget and isLabelOfLabeledStatement users using type predicates (#22100) --- src/services/findAllReferences.ts | 20 ++++++------- src/services/goToDefinition.ts | 5 ++-- src/services/services.ts | 48 +++++++++++++++---------------- src/services/utilities.ts | 14 ++++----- 4 files changed, 39 insertions(+), 48 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 8100a021fb8..46a17707e79 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -330,17 +330,15 @@ namespace ts.FindAllReferences.Core { } // Labels - if (isLabelName(node)) { - if (isJumpStatementTarget(node)) { - const labelDefinition = getTargetLabel((node.parent), (node).text); - // if we have a label definition, look within its statement for references, if not, then - // the label is undefined and we have no results.. - return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition); - } - else { - // it is a label definition and not a target, search within the parent labeledStatement - return getLabelReferencesInNode(node.parent, node); - } + if (isJumpStatementTarget(node)) { + const labelDefinition = getTargetLabel(node.parent, node.text); + // if we have a label definition, look within its statement for references, if not, then + // the label is undefined and we have no results.. + return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition); + } + else if (isLabelOfLabeledStatement(node)) { + // it is a label definition and not a target, search within the parent labeledStatement + return getLabelReferencesInNode(node.parent, node); } if (isThis(node)) { diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 6be00efd53f..cf51e8f93cd 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -13,9 +13,8 @@ namespace ts.GoToDefinition { // Labels if (isJumpStatementTarget(node)) { - const labelName = (node).text; - const label = getTargetLabel((node.parent), labelName); - return label ? [createDefinitionInfoFromName(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined; + const label = getTargetLabel(node.parent, node.text); + return label ? [createDefinitionInfoFromName(label, ScriptElementKind.label, node.text, /*containerName*/ undefined)] : undefined; } const typeChecker = program.getTypeChecker(); diff --git a/src/services/services.ts b/src/services/services.ts index caa927cf80d..624ca8c42bb 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1467,10 +1467,7 @@ namespace ts { const sourceFile = getValidSourceFile(fileName); const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (node === sourceFile) { - return undefined; - } - - if (isLabelName(node)) { + // Avoid giving quickInfo for the sourceFile as a whole. return undefined; } @@ -1481,6 +1478,11 @@ namespace ts { // Try getting just type at this position and show switch (node.kind) { case SyntaxKind.Identifier: + if (isLabelName(node)) { + // Type here will be 'any', avoid displaying this. + return undefined; + } + // falls through case SyntaxKind.PropertyAccessExpression: case SyntaxKind.QualifiedName: case SyntaxKind.ThisKeyword: @@ -1488,29 +1490,27 @@ namespace ts { case SyntaxKind.SuperKeyword: // For the identifiers/this/super etc get the type at position const type = typeChecker.getTypeAtLocation(node); - if (type) { - return { - kind: ScriptElementKind.unknown, - kindModifiers: ScriptElementKindModifier.none, - textSpan: createTextSpan(node.getStart(), node.getWidth()), - displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)), - documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, - tags: type.symbol ? type.symbol.getJsDocTags() : undefined - }; - } + return type && { + kind: ScriptElementKind.unknown, + kindModifiers: ScriptElementKindModifier.none, + textSpan: createTextSpanFromNode(node, sourceFile), + displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)), + documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, + tags: type.symbol ? type.symbol.getJsDocTags() : undefined + }; } return undefined; } - const displayPartsDocumentationsAndKind = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node); + const { symbolKind, displayParts, documentation, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node); return { - kind: displayPartsDocumentationsAndKind.symbolKind, + kind: symbolKind, kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), - textSpan: createTextSpan(node.getStart(), node.getWidth()), - displayParts: displayPartsDocumentationsAndKind.displayParts, - documentation: displayPartsDocumentationsAndKind.documentation, - tags: displayPartsDocumentationsAndKind.tags + textSpan: createTextSpanFromNode(node, sourceFile), + displayParts, + documentation, + tags, }; } @@ -1519,11 +1519,9 @@ namespace ts { && isPropertyAssignment(node.parent) && node.parent.name === node) { const type = checker.getContextualType(node.parent.parent); - if (type) { - const property = checker.getPropertyOfType(type, getTextOfIdentifierOrLiteral(node)); - if (property) { - return property; - } + const property = type && checker.getPropertyOfType(type, getTextOfIdentifierOrLiteral(node)); + if (property) { + return property; } } return checker.getSymbolAtLocation(node); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 6ece5e018b3..5c79774073f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -214,16 +214,12 @@ namespace ts { return undefined; } - export function isJumpStatementTarget(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - (node.parent.kind === SyntaxKind.BreakStatement || node.parent.kind === SyntaxKind.ContinueStatement) && - (node.parent).label === node; - } + export function isJumpStatementTarget(node: Node): node is Identifier & { parent: BreakOrContinueStatement } { + return node.kind === SyntaxKind.Identifier && isBreakOrContinueStatement(node.parent) && node.parent.label === node; + } - function isLabelOfLabeledStatement(node: Node): boolean { - return node.kind === SyntaxKind.Identifier && - node.parent.kind === SyntaxKind.LabeledStatement && - (node.parent).label === node; + export function isLabelOfLabeledStatement(node: Node): node is Identifier { + return node.kind === SyntaxKind.Identifier && isLabeledStatement(node.parent) && node.parent.label === node; } export function isLabelName(node: Node): boolean {