From 88140075633ee5003dd32901a787ee2c615b6b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Solano?= Date: Mon, 24 Jul 2023 14:08:09 -0700 Subject: [PATCH 1/4] Display parts for types --- src/services/inlayHints.ts | 355 +++++++++++++++++- ...inlayHintsFunctionParameterTypes1.baseline | 2 +- 2 files changed, 343 insertions(+), 14 deletions(-) diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index a2381d491ea58..d61dfbce9db0b 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -1,7 +1,10 @@ import { __String, + ArrayTypeNode, ArrowFunction, CallExpression, + ConditionalTypeNode, + ConstructorTypeNode, createPrinterWithRemoveComments, createTextSpanFromNode, Debug, @@ -16,17 +19,24 @@ import { FunctionDeclaration, FunctionExpression, FunctionLikeDeclaration, + FunctionTypeNode, GetAccessorDeclaration, getEffectiveReturnTypeNode, getEffectiveTypeAnnotationNode, getLanguageVariant, getLeadingCommentRanges, + getNameOfDeclaration, hasContextSensitiveParameters, Identifier, + idText, + ImportTypeNode, + IndexedAccessTypeNode, + InferTypeNode, InlayHint, InlayHintDisplayPart, InlayHintKind, InlayHintsContext, + IntersectionTypeNode, isArrowFunction, isAssertionExpression, isBindingPattern, @@ -52,30 +62,48 @@ import { isTypeNode, isVarConst, isVariableDeclaration, + LiteralTypeNode, + MappedTypeNode, MethodDeclaration, + NamedTupleMember, NewExpression, Node, + NodeArray, NodeBuilderFlags, + NumericLiteral, + OptionalTypeNode, ParameterDeclaration, + ParenthesizedTypeNode, PrefixUnaryExpression, PropertyDeclaration, + PropertySignature, + QualifiedName, + RestTypeNode, Signature, skipParentheses, some, + StringLiteral, Symbol, SymbolFlags, SyntaxKind, textSpanIntersectsWith, + tokenToString, + TupleTypeNode, TupleTypeReference, Type, + TypeLiteralNode, + TypeOperatorNode, + TypeParameterDeclaration, + TypePredicateNode, + TypeQueryNode, + TypeReferenceNode, unescapeLeadingUnderscores, + UnionTypeNode, UserPreferences, usingSingleLineStringWriter, VariableDeclaration, } from "./_namespaces/ts"; -const maxTypeHintLength = 30; - const leadingParameterNameCommentRegexFactory = (name: string) => { return new RegExp(`^\\s?/\\*\\*?\\s?${name}\\s?\\*\\/\\s?$`); }; @@ -176,9 +204,10 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { }); } - function addTypeHints(text: string, position: number) { + function addTypeHints(hintText: string | InlayHintDisplayPart[], position: number) { result.push({ - text: `: ${text.length > maxTypeHintLength ? text.substr(0, maxTypeHintLength - "...".length) + "..." : text}`, + text: typeof hintText === "string" ? `: ${hintText}` : "", + displayParts: typeof hintText === "string" ? undefined : [{ text: ": " }, ...hintText], position, kind: InlayHintKind.Type, whitespaceBefore: true, @@ -224,13 +253,14 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { return; } - const typeDisplayString = printTypeInSingleLine(declarationType); - if (typeDisplayString) { - const isVariableNameMatchesType = preferences.includeInlayVariableTypeHintsWhenTypeMatchesName === false && equateStringsCaseInsensitive(decl.name.getText(), typeDisplayString); + const hints = typeToInlayHintParts(declarationType); + if (hints) { + const hintText = typeof hints === "string" ? hints : hints.map(part => part.text).join(""); + const isVariableNameMatchesType = preferences.includeInlayVariableTypeHintsWhenTypeMatchesName === false && equateStringsCaseInsensitive(decl.name.getText(), hintText); if (isVariableNameMatchesType) { return; } - addTypeHints(typeDisplayString, decl.name.end); + addTypeHints(hints, decl.name.end); } } @@ -355,12 +385,10 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { return; } - const typeDisplayString = printTypeInSingleLine(returnType); - if (!typeDisplayString) { - return; + const hint = typeToInlayHintParts(returnType); + if (hint) { + addTypeHints(hint, getTypeAnnotationPosition(decl)); } - - addTypeHints(typeDisplayString, getTypeAnnotationPosition(decl)); } function getTypeAnnotationPosition(decl: FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration | GetAccessorDeclaration) { @@ -422,6 +450,307 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { }); } + function typeToInlayHintParts(type: Type): InlayHintDisplayPart[] | string { + if (!shouldUseInteractiveInlayHints(preferences)) { + return printTypeInSingleLine(type); + } + + const flags = NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.AllowUniqueESSymbolType | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; + const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags); + Debug.assertIsDefined(typeNode, "should always get typenode"); + + const parts: InlayHintDisplayPart[] = []; + visitDisplayPart(typeNode); + + function visitDisplayPart(node: Node) { + if (!node) { + return; + } + + const tokenString = tokenToString(node.kind); + if (tokenString) { + parts.push({ text: tokenString }); + return; + } + + switch (node.kind) { + case SyntaxKind.Identifier: + const identifier = node as Identifier; + const identifierText = idText(identifier); + const name = identifier.symbol && identifier.symbol.declarations && identifier.symbol.declarations.length && getNameOfDeclaration(identifier.symbol.declarations[0]); + if (name) { + parts.push(getNodeDisplayPart(identifierText, name)); + } + else { + parts.push({ text: identifierText }); + } + break; + case SyntaxKind.NumericLiteral: + parts.push({ text: (node as NumericLiteral).text }); + break; + case SyntaxKind.StringLiteral: + parts.push({ text: `"${(node as StringLiteral).text}"` }); + break; + case SyntaxKind.QualifiedName: + const qualifiedName = node as QualifiedName; + visitDisplayPart(qualifiedName.left); + parts.push({ text: "." }); + visitDisplayPart(qualifiedName.right); + break; + case SyntaxKind.TypePredicate: + const predicate = node as TypePredicateNode; + if (predicate.assertsModifier) { + parts.push({ text: "asserts " }); + } + visitDisplayPart(predicate.parameterName); + if (predicate.type) { + parts.push({ text: " is " }); + visitDisplayPart(predicate.type); + } + break; + case SyntaxKind.TypeReference: + const typeReference = node as TypeReferenceNode; + visitDisplayPart(typeReference.typeName); + if (typeReference.typeArguments) { + parts.push({ text: "<" }); + visitDisplayPartList(typeReference.typeArguments, ", "); + parts.push({ text: ">" }); + } + break; + case SyntaxKind.TypeParameter: + const typeParameter = node as TypeParameterDeclaration; + if (typeParameter.modifiers) { + visitDisplayPartList(typeParameter.modifiers, " "); + } + visitDisplayPart(typeParameter.name); + if (typeParameter.constraint) { + parts.push({ text: " extends " }); + visitDisplayPart(typeParameter.constraint); + } + if (typeParameter.default) { + parts.push({ text: " = " }); + visitDisplayPart(typeParameter.default); + } + break; + case SyntaxKind.Parameter: + const parameter = node as ParameterDeclaration; + if (parameter.modifiers) { + visitDisplayPartList(parameter.modifiers, " "); + } + if (parameter.dotDotDotToken) { + parts.push({ text: "..." }); + } + visitDisplayPart(parameter.name); + if (parameter.questionToken) { + parts.push({ text: "?" }); + } + if (parameter.type) { + parts.push({ text: ": " }); + visitDisplayPart(parameter.type); + } + break; + case SyntaxKind.ConstructorType: + const constructorType = node as ConstructorTypeNode; + parts.push({ text: "new " }); + if (constructorType.typeParameters) { + parts.push({ text: "<" }); + visitDisplayPartList(constructorType.typeParameters, ", "); + parts.push({ text: ">" }); + } + parts.push({ text: "(" }); + visitDisplayPartList(constructorType.parameters, ", "); + parts.push({ text: ")" }); + parts.push({ text: " => " }); + visitDisplayPart(constructorType.type); + break; + case SyntaxKind.TypeQuery: + const typeQuery = node as TypeQueryNode; + parts.push({ text: "typeof " }); + visitDisplayPart(typeQuery.exprName); + if (typeQuery.typeArguments) { + parts.push({ text: "<" }); + visitDisplayPartList(typeQuery.typeArguments, ", "); + parts.push({ text: ">" }); + } + break; + case SyntaxKind.TypeLiteral: + const typeLiteral = node as TypeLiteralNode; + parts.push({ text: "{" }); + if (typeLiteral.members.length) { + parts.push({ text: " " }); + visitDisplayPartList(typeLiteral.members, "; "); + parts.push({ text: " " }); + } + parts.push({ text: "}" }); + break; + case SyntaxKind.ArrayType: + visitDisplayPart((node as ArrayTypeNode).elementType); + parts.push({ text: "[]" }); + break; + case SyntaxKind.TupleType: + parts.push({ text: "[" }); + visitDisplayPartList((node as TupleTypeNode).elements, ", "); + parts.push({ text: "]" }); + break; + case SyntaxKind.NamedTupleMember: + const member = node as NamedTupleMember; + if (member.dotDotDotToken) { + parts.push({ text: "..." }); + } + visitDisplayPart(member.name); + if (member.questionToken) { + parts.push({ text: "?" }); + } + parts.push({ text: ": " }); + visitDisplayPart(member.type); + break; + case SyntaxKind.OptionalType: + visitDisplayPart((node as OptionalTypeNode).type); + parts.push({ text: "?" }); + break; + case SyntaxKind.RestType: + parts.push({ text: "..." }); + visitDisplayPart((node as RestTypeNode).type); + break; + case SyntaxKind.UnionType: + visitDisplayPartList((node as UnionTypeNode).types, " | "); + break; + case SyntaxKind.IntersectionType: + visitDisplayPartList((node as IntersectionTypeNode).types, " & "); + break; + case SyntaxKind.ConditionalType: + const conditionalType = node as ConditionalTypeNode; + visitDisplayPart(conditionalType.checkType); + parts.push({ text: " extends " }); + visitDisplayPart(conditionalType.extendsType); + parts.push({ text: " ? " }); + visitDisplayPart(conditionalType.trueType); + parts.push({ text: " : " }); + visitDisplayPart(conditionalType.falseType); + break; + case SyntaxKind.InferType: + parts.push({ text: "infer " }); + visitDisplayPart((node as InferTypeNode).typeParameter); + break; + case SyntaxKind.ParenthesizedType: + parts.push({ text: "(" }); + visitDisplayPart((node as ParenthesizedTypeNode).type); + parts.push({ text: ")" }); + break; + case SyntaxKind.TypeOperator: + const typeOperator = node as TypeOperatorNode; + parts.push({ text: `${tokenToString(typeOperator.operator)} ` }); + visitDisplayPart(typeOperator.type); + break; + case SyntaxKind.IndexedAccessType: + const indexedAccess = node as IndexedAccessTypeNode; + visitDisplayPart(indexedAccess.objectType); + parts.push({ text: "[" }); + visitDisplayPart(indexedAccess.indexType); + parts.push({ text: "]" }); + break; + case SyntaxKind.MappedType: + const mappedType = node as MappedTypeNode; + parts.push({ text: "{ " }); + if (mappedType.readonlyToken) { + if (mappedType.readonlyToken.kind === SyntaxKind.PlusToken) { + parts.push({ text: "+" }); + } + else if (mappedType.readonlyToken.kind === SyntaxKind.MinusToken) { + parts.push({ text: "-" }); + } + parts.push({ text: "readonly " }); + } + parts.push({ text: "[" }); + visitDisplayPart(mappedType.typeParameter); + if (mappedType.nameType) { + parts.push({ text: " as " }); + visitDisplayPart(mappedType.nameType); + } + parts.push({ text: "]" }); + if (mappedType.questionToken) { + if (mappedType.questionToken.kind === SyntaxKind.PlusToken) { + parts.push({ text: "+" }); + } + else if (mappedType.questionToken.kind === SyntaxKind.MinusToken) { + parts.push({ text: "-" }); + } + parts.push({ text: "?" }); + } + parts.push({ text: ": " }); + if (mappedType.type) { + visitDisplayPart(mappedType.type); + } + parts.push({ text: "; }" }); + break; + case SyntaxKind.LiteralType: + visitDisplayPart((node as LiteralTypeNode).literal); + break; + case SyntaxKind.FunctionType: + const functionType = node as FunctionTypeNode; + if (functionType.typeParameters) { + parts.push({ text: "<" }); + visitDisplayPartList(functionType.typeParameters, ", "); + parts.push({ text: ">" }); + } + parts.push({ text: "(" }); + visitDisplayPartList(functionType.parameters, ", "); + parts.push({ text: ")" }); + parts.push({ text: " => " }); + visitDisplayPart(functionType.type); + break; + case SyntaxKind.ImportType: + const importType = node as ImportTypeNode; + if (importType.isTypeOf) { + parts.push({ text: "typeof " }); + } + parts.push({ text: "import(" }); + visitDisplayPart(importType.argument); + if (importType.assertions) { + parts.push({ text: ", { assert: " }); + visitDisplayPartList(importType.assertions.assertClause.elements, ", "); + parts.push({ text: " }" }); + } + parts.push({ text: ")" }); + if (importType.qualifier) { + parts.push({ text: "." }); + visitDisplayPart(importType.qualifier); + } + if (importType.typeArguments) { + parts.push({ text: "<" }); + visitDisplayPartList(importType.typeArguments, ", "); + parts.push({ text: ">" }); + } + break; + case SyntaxKind.PropertySignature: + const propertySignature = node as PropertySignature; + if (propertySignature.modifiers) { + visitDisplayPartList(propertySignature.modifiers, " "); + } + visitDisplayPart(propertySignature.name); + if (propertySignature.questionToken) { + parts.push({ text: "?" }); + } + if (propertySignature.type) { + parts.push({ text: ": " }); + visitDisplayPart(propertySignature.type); + } + break; + } + } + + function visitDisplayPartList(nodes: NodeArray, separator: string) { + nodes.forEach((node, index) => { + if (index > 0) { + parts.push({ text: separator }); + } + visitDisplayPart(node); + }); + } + + return parts; + } + function isUndefined(name: __String) { return name === "undefined"; } diff --git a/tests/baselines/reference/inlayHintsFunctionParameterTypes1.baseline b/tests/baselines/reference/inlayHintsFunctionParameterTypes1.baseline index 31c95617ae2ce..af66775ae95dc 100644 --- a/tests/baselines/reference/inlayHintsFunctionParameterTypes1.baseline +++ b/tests/baselines/reference/inlayHintsFunctionParameterTypes1.baseline @@ -46,7 +46,7 @@ foo2((a) => { }) foo3(a => { ^ { - "text": ": (c: (d: 2 | 3) => void) => ...", + "text": ": (c: (d: 2 | 3) => void) => void", "position": 331, "kind": "Type", "whitespaceBefore": true From e77169e4ae2d54f2495a132b34cbae15b314ab98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Solano?= Date: Thu, 17 Aug 2023 09:59:46 -0700 Subject: [PATCH 2/4] Testing --- ...layHintsInteractiveAnyParameter1.baseline} | 10 +- ...layHintsInteractiveAnyParameter2.baseline} | 26 ++-- ...nteractiveFunctionParameterTypes1.baseline | 80 +++++++++++ ...nteractiveFunctionParameterTypes2.baseline | 1 + ...nteractiveFunctionParameterTypes3.baseline | 17 +++ ...nteractiveFunctionParameterTypes4.baseline | 1 + .../inlayHintsInteractiveImportType1.baseline | 1 + .../inlayHintsInteractiveImportType2.baseline | 33 +++++ ...ntsInteractiveJsDocParameterNames.baseline | 43 ++++++ .../inlayHintsInteractiveMultifile1.baseline | 128 ++++++++++++++++++ .../inlayHintsInteractiveReturnType.baseline | 84 ++++++++++++ ...layHintsInteractiveVariableTypes1.baseline | 25 ++++ ...layHintsInteractiveVariableTypes2.baseline | 103 ++++++++++++++ ... => inlayHintsInteractiveAnyParameter1.ts} | 0 ... => inlayHintsInteractiveAnyParameter2.ts} | 0 ...HintsInteractiveFunctionParameterTypes1.ts | 30 ++++ ...HintsInteractiveFunctionParameterTypes2.ts | 26 ++++ ...HintsInteractiveFunctionParameterTypes3.ts | 22 +++ ...HintsInteractiveFunctionParameterTypes4.ts | 18 +++ .../inlayHintsInteractiveImportType1.ts | 16 +++ .../inlayHintsInteractiveImportType2.ts | 20 +++ ...nlayHintsInteractiveJsDocParameterNames.ts | 25 ++++ .../inlayHintsInteractiveMultifile1.ts | 21 +++ .../inlayHintsInteractiveReturnType.ts | 27 ++++ .../inlayHintsInteractiveVariableTypes1.ts | 29 ++++ .../inlayHintsInteractiveVariableTypes2.ts | 18 +++ 26 files changed, 786 insertions(+), 18 deletions(-) rename tests/baselines/reference/{inlayHintsInterativeAnyParameter1.baseline => inlayHintsInteractiveAnyParameter1.baseline} (76%) rename tests/baselines/reference/{inlayHintsInterativeAnyParameter2.baseline => inlayHintsInteractiveAnyParameter2.baseline} (77%) create mode 100644 tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes1.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes2.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes3.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes4.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveImportType1.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveImportType2.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveJsDocParameterNames.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveMultifile1.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveReturnType.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveVariableTypes1.baseline create mode 100644 tests/baselines/reference/inlayHintsInteractiveVariableTypes2.baseline rename tests/cases/fourslash/{inlayHintsInterativeAnyParameter1.ts => inlayHintsInteractiveAnyParameter1.ts} (100%) rename tests/cases/fourslash/{inlayHintsInterativeAnyParameter2.ts => inlayHintsInteractiveAnyParameter2.ts} (100%) create mode 100644 tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes1.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes2.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes3.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes4.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveImportType1.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveImportType2.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveJsDocParameterNames.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveMultifile1.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveReturnType.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveVariableTypes1.ts create mode 100644 tests/cases/fourslash/inlayHintsInteractiveVariableTypes2.ts diff --git a/tests/baselines/reference/inlayHintsInterativeAnyParameter1.baseline b/tests/baselines/reference/inlayHintsInteractiveAnyParameter1.baseline similarity index 76% rename from tests/baselines/reference/inlayHintsInterativeAnyParameter1.baseline rename to tests/baselines/reference/inlayHintsInteractiveAnyParameter1.baseline index 6d4d794d58e4a..82f85a385b924 100644 --- a/tests/baselines/reference/inlayHintsInterativeAnyParameter1.baseline +++ b/tests/baselines/reference/inlayHintsInteractiveAnyParameter1.baseline @@ -12,7 +12,7 @@ foo(1); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts" }, { "text": ":" @@ -34,7 +34,7 @@ foo(''); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts" }, { "text": ":" @@ -56,7 +56,7 @@ foo(true); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts" }, { "text": ":" @@ -78,7 +78,7 @@ foo((1)); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts" }, { "text": ":" @@ -100,7 +100,7 @@ foo(foo(1)); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts" }, { "text": ":" diff --git a/tests/baselines/reference/inlayHintsInterativeAnyParameter2.baseline b/tests/baselines/reference/inlayHintsInteractiveAnyParameter2.baseline similarity index 77% rename from tests/baselines/reference/inlayHintsInterativeAnyParameter2.baseline rename to tests/baselines/reference/inlayHintsInteractiveAnyParameter2.baseline index 510267abb4adb..9709ddac5c2b5 100644 --- a/tests/baselines/reference/inlayHintsInterativeAnyParameter2.baseline +++ b/tests/baselines/reference/inlayHintsInteractiveAnyParameter2.baseline @@ -12,7 +12,7 @@ foo(1); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -34,7 +34,7 @@ foo(''); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -56,7 +56,7 @@ foo(true); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -78,7 +78,7 @@ foo(() => 1); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -100,7 +100,7 @@ foo(function () { return 1 }); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -122,7 +122,7 @@ foo({}); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -144,7 +144,7 @@ foo({ a: 1 }); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -166,7 +166,7 @@ foo([]); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -188,7 +188,7 @@ foo([1]); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -210,7 +210,7 @@ foo(foo); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -232,7 +232,7 @@ foo((1)); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -254,7 +254,7 @@ foo(foo(1)); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" @@ -276,7 +276,7 @@ foo(foo(1)); "start": 14, "length": 1 }, - "file": "/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts" + "file": "/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts" }, { "text": ":" diff --git a/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes1.baseline b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes1.baseline new file mode 100644 index 0000000000000..af66775ae95dc --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes1.baseline @@ -0,0 +1,80 @@ +const f1: F1 = (a, b) => { } + ^ +{ + "text": ": string", + "position": 58, + "kind": "Type", + "whitespaceBefore": true +} + +const f1: F1 = (a, b) => { } + ^ +{ + "text": ": number", + "position": 61, + "kind": "Type", + "whitespaceBefore": true +} + +const f2: F1 = (a, b: number) => { } + ^ +{ + "text": ": string", + "position": 87, + "kind": "Type", + "whitespaceBefore": true +} + +foo1((a) => { }) + ^ +{ + "text": ": string", + "position": 157, + "kind": "Type", + "whitespaceBefore": true +} + +foo2((a) => { }) + ^ +{ + "text": ": 2 | 3", + "position": 232, + "kind": "Type", + "whitespaceBefore": true +} + +foo3(a => { + ^ +{ + "text": ": (c: (d: 2 | 3) => void) => void", + "position": 331, + "kind": "Type", + "whitespaceBefore": true +} + + a(d => {}) + ^ +{ + "text": ": 2 | 3", + "position": 344, + "kind": "Type", + "whitespaceBefore": true +} + +foo4(1, a => { }) + ^ +{ + "text": ": number", + "position": 409, + "kind": "Type", + "whitespaceBefore": true +} + +const foo5: F2 = (a) => { } + ^ +{ + "text": ": { a: number; b: string; }", + "position": 492, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes2.baseline b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes2.baseline new file mode 100644 index 0000000000000..6136dbb8025a6 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes2.baseline @@ -0,0 +1 @@ +=== No inlay hints === \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes3.baseline b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes3.baseline new file mode 100644 index 0000000000000..33923495c7bbd --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes3.baseline @@ -0,0 +1,17 @@ + bar: function (x?): void { + ^ +{ + "text": ": boolean", + "position": 87, + "kind": "Type", + "whitespaceBefore": true +} + + set foo(value) { this.#value = value; } + ^ +{ + "text": ": number", + "position": 250, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes4.baseline b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes4.baseline new file mode 100644 index 0000000000000..6136dbb8025a6 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveFunctionParameterTypes4.baseline @@ -0,0 +1 @@ +=== No inlay hints === \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveImportType1.baseline b/tests/baselines/reference/inlayHintsInteractiveImportType1.baseline new file mode 100644 index 0000000000000..6136dbb8025a6 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveImportType1.baseline @@ -0,0 +1 @@ +=== No inlay hints === \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveImportType2.baseline b/tests/baselines/reference/inlayHintsInteractiveImportType2.baseline new file mode 100644 index 0000000000000..787ee663b8350 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveImportType2.baseline @@ -0,0 +1,33 @@ +function bar () { return require('./a').a; } + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "1" + } + ], + "position": 58, + "kind": "Type", + "whitespaceBefore": true +} + +const d = bar() + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "1" + } + ], + "position": 111, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveJsDocParameterNames.baseline b/tests/baselines/reference/inlayHintsInteractiveJsDocParameterNames.baseline new file mode 100644 index 0000000000000..af633a5b9752d --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveJsDocParameterNames.baseline @@ -0,0 +1,43 @@ +y.foo(1, 2) + ^ +{ + "text": "", + "position": 88, + "kind": "Parameter", + "whitespaceAfter": true, + "displayParts": [ + { + "text": "a", + "span": { + "start": 40, + "length": 1 + }, + "file": "/a.js" + }, + { + "text": ":" + } + ] +} + +y.foo(1, 2) + ^ +{ + "text": "", + "position": 91, + "kind": "Parameter", + "whitespaceAfter": true, + "displayParts": [ + { + "text": "b", + "span": { + "start": 51, + "length": 1 + }, + "file": "/a.js" + }, + { + "text": ":" + } + ] +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveMultifile1.baseline b/tests/baselines/reference/inlayHintsInteractiveMultifile1.baseline new file mode 100644 index 0000000000000..809e9d6eda115 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveMultifile1.baseline @@ -0,0 +1,128 @@ +async function foo () { + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "Promise", + "span": { + "start": -1, + "length": 7 + }, + "file": "lib.d.ts" + }, + { + "text": "<" + }, + { + "text": "Foo", + "span": { + "start": 17, + "length": 3 + }, + "file": "/a.ts" + }, + { + "text": ">" + } + ], + "position": 21, + "kind": "Type", + "whitespaceBefore": true +} + +function bar () { return import('./a') } + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "Promise", + "span": { + "start": -1, + "length": 7 + }, + "file": "lib.d.ts" + }, + { + "text": "<" + }, + { + "text": "typeof " + }, + { + "text": "import(" + }, + { + "text": "\"/a\"" + }, + { + "text": ")" + }, + { + "text": ">" + } + ], + "position": 83, + "kind": "Type", + "whitespaceBefore": true +} + +async function main () { + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "Promise", + "span": { + "start": -1, + "length": 7 + }, + "file": "lib.d.ts" + }, + { + "text": "<" + }, + { + "text": "void" + }, + { + "text": ">" + } + ], + "position": 131, + "kind": "Type", + "whitespaceBefore": true +} + + const a = await foo() + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "Foo", + "span": { + "start": 17, + "length": 3 + }, + "file": "/a.ts" + } + ], + "position": 145, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveReturnType.baseline b/tests/baselines/reference/inlayHintsInteractiveReturnType.baseline new file mode 100644 index 0000000000000..bf401880c3d24 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveReturnType.baseline @@ -0,0 +1,84 @@ +function foo1 () { + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + } + ], + "position": 16, + "kind": "Type", + "whitespaceBefore": true +} + + foo() { + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + } + ], + "position": 95, + "kind": "Type", + "whitespaceBefore": true +} + +const a = () => 1 + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + } + ], + "position": 135, + "kind": "Type", + "whitespaceBefore": true +} + +const b = function () { return 1 } + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + } + ], + "position": 162, + "kind": "Type", + "whitespaceBefore": true +} + +const c = (b) => 1 + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + } + ], + "position": 189, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveVariableTypes1.baseline b/tests/baselines/reference/inlayHintsInteractiveVariableTypes1.baseline new file mode 100644 index 0000000000000..18fe7f7b62db1 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveVariableTypes1.baseline @@ -0,0 +1,25 @@ + const m = () => 123; + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "(" + }, + { + "text": ")" + }, + { + "text": " => " + }, + { + "text": "number" + } + ], + "position": 331, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/baselines/reference/inlayHintsInteractiveVariableTypes2.baseline b/tests/baselines/reference/inlayHintsInteractiveVariableTypes2.baseline new file mode 100644 index 0000000000000..bc18a904cd289 --- /dev/null +++ b/tests/baselines/reference/inlayHintsInteractiveVariableTypes2.baseline @@ -0,0 +1,103 @@ +const array = [1, 2] + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + }, + { + "text": "[]" + } + ], + "position": 45, + "kind": "Type", + "whitespaceBefore": true +} + +const a = object; + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "{" + }, + { + "text": " " + }, + { + "text": "foo" + }, + { + "text": ": " + }, + { + "text": "number" + }, + { + "text": "; " + }, + { + "text": "bar" + }, + { + "text": ": " + }, + { + "text": "number" + }, + { + "text": " " + }, + { + "text": "}" + } + ], + "position": 62, + "kind": "Type", + "whitespaceBefore": true +} + +const b = array; + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "number" + }, + { + "text": "[]" + } + ], + "position": 128, + "kind": "Type", + "whitespaceBefore": true +} + +const x = foo(1) + ^ +{ + "text": "", + "displayParts": [ + { + "text": ": " + }, + { + "text": "1" + } + ], + "position": 244, + "kind": "Type", + "whitespaceBefore": true +} \ No newline at end of file diff --git a/tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts b/tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts similarity index 100% rename from tests/cases/fourslash/inlayHintsInterativeAnyParameter1.ts rename to tests/cases/fourslash/inlayHintsInteractiveAnyParameter1.ts diff --git a/tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts b/tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts similarity index 100% rename from tests/cases/fourslash/inlayHintsInterativeAnyParameter2.ts rename to tests/cases/fourslash/inlayHintsInteractiveAnyParameter2.ts diff --git a/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes1.ts b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes1.ts new file mode 100644 index 0000000000000..79e2d31a50f92 --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes1.ts @@ -0,0 +1,30 @@ +/// + +//// type F1 = (a: string, b: number) => void +//// const f1: F1 = (a, b) => { } +//// const f2: F1 = (a, b: number) => { } + +//// function foo1 (cb: (a: string) => void) {} +//// foo1((a) => { }) + +//// function foo2 (cb: (a: Exclude<1 | 2 | 3, 1>) => void) {} +//// foo2((a) => { }) + +//// function foo3 (a: (b: (c: (d: Exclude<1 | 2 | 3, 1>) => void) => void) => void) {} +//// foo3(a => { +//// a(d => {}) +//// }) + +//// function foo4(v: T, a: (v: T) => void) {} +//// foo4(1, a => { }) + +//// type F2 = (a: { +//// a: number +//// b: string +//// }) => void +//// const foo5: F2 = (a) => { } + +verify.baselineInlayHints(undefined, { + includeInlayFunctionParameterTypeHints: true, + interactiveInlayHints: true, +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes2.ts b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes2.ts new file mode 100644 index 0000000000000..9d49369685a1a --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes2.ts @@ -0,0 +1,26 @@ +/// + +////class C {} +////namespace N { export class Foo {} } +////interface Foo {} + +////function f1(a = 1) {} +////function f2(a = "a") {} +////function f3(a = true) {} + +////function f4(a = { } as Foo) {} +////function f5(a = {}) {} +////function f6(a = {} as const) {} +////function f7(a = (({} as const))) {} + +////function f8(a = new C()) {} +////function f9(a = new N.C()) {} +////function f10(a = ((((new C()))))) {} + +////function f11(a = { a: 1, b: 1 }) {} +////function f12(a = ((({ a: 1, b: 1 })))) {} + +verify.baselineInlayHints(undefined, { + includeInlayFunctionParameterTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes3.ts b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes3.ts new file mode 100644 index 0000000000000..7010f180b06ad --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes3.ts @@ -0,0 +1,22 @@ +/// + +////interface IFoo { +//// bar(x?: boolean): void; +////} +//// +////const a: IFoo = { +//// bar: function (x?): void { +//// throw new Error("Function not implemented."); +//// } +////} + +////class Foo { +//// #value = 0; +//// get foo(): number { return this.#value; } +//// set foo(value) { this.#value = value; } +////} + +verify.baselineInlayHints(undefined, { + includeInlayFunctionParameterTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes4.ts b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes4.ts new file mode 100644 index 0000000000000..ed137af592de1 --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveFunctionParameterTypes4.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true +// @checkJs: true +// @Filename: /a.js +////class Foo { +//// #value = 0; +//// get foo() { return this.#value; } +//// /** +//// * @param {number} value +//// */ +//// set foo(value) { this.#value = value; } +////} + +verify.baselineInlayHints(undefined, { + includeInlayFunctionParameterTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveImportType1.ts b/tests/cases/fourslash/inlayHintsInteractiveImportType1.ts new file mode 100644 index 0000000000000..63c108e9f636b --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveImportType1.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /a.js +//// module.exports.a = 1 + +// @Filename: /b.js +//// const a = require('./a'); + +goTo.file('/b.js') +verify.baselineInlayHints(undefined, { + includeInlayVariableTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveImportType2.ts b/tests/cases/fourslash/inlayHintsInteractiveImportType2.ts new file mode 100644 index 0000000000000..e56b6ea97065c --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveImportType2.ts @@ -0,0 +1,20 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /a.js +//// module.exports.a = 1 + +// @Filename: /b.js +//// function foo () { return require('./a'); } +//// function bar () { return require('./a').a; } +//// const c = foo() +//// const d = bar() + +goTo.file('/b.js') +verify.baselineInlayHints(undefined, { + includeInlayVariableTypeHints: true, + includeInlayFunctionLikeReturnTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveJsDocParameterNames.ts b/tests/cases/fourslash/inlayHintsInteractiveJsDocParameterNames.ts new file mode 100644 index 0000000000000..d97e51ebd9727 --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveJsDocParameterNames.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: /a.js +//// var x +//// x.foo(1, 2); + +//// /** +//// * @type {{foo: (a: number, b: number) => void}} +//// */ +//// var y +//// y.foo(1, 2) + +//// /** +//// * @type {string} +//// */ +//// var z = "" + +goTo.file('/a.js') +verify.baselineInlayHints(undefined, { + includeInlayParameterNameHints: "literals", + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveMultifile1.ts b/tests/cases/fourslash/inlayHintsInteractiveMultifile1.ts new file mode 100644 index 0000000000000..db990eebd1ffa --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveMultifile1.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: /a.ts +//// export interface Foo { a: string } + +// @Filename: /b.ts +//// async function foo () { +//// return {} as any as import('./a').Foo +//// } +//// function bar () { return import('./a') } +//// async function main () { +//// const a = await foo() +//// const b = await bar() +//// } + +goTo.file('/b.ts') +verify.baselineInlayHints(undefined, { + includeInlayVariableTypeHints: true, + includeInlayFunctionLikeReturnTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveReturnType.ts b/tests/cases/fourslash/inlayHintsInteractiveReturnType.ts new file mode 100644 index 0000000000000..5bb31f39cb366 --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveReturnType.ts @@ -0,0 +1,27 @@ +/// + +//// function foo1 () { +//// return 1 +//// } + +//// function foo2 (): number { +//// return 1 +//// } + +//// class C { +//// foo() { +//// return 1 +//// } +//// } + +//// const a = () => 1 + +//// const b = function () { return 1 } + +//// const c = (b) => 1 +//// const d = b => 1 + +verify.baselineInlayHints(undefined, { + includeInlayFunctionLikeReturnTypeHints: true, + interactiveInlayHints: true, +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveVariableTypes1.ts b/tests/cases/fourslash/inlayHintsInteractiveVariableTypes1.ts new file mode 100644 index 0000000000000..50d60bd03ccfe --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveVariableTypes1.ts @@ -0,0 +1,29 @@ +/// + +////class C {} +////namespace N { export class Foo {} } +////interface Foo {} + +////const a = "a"; +////const b = 1; +////const c = true; + +////const d = {} as Foo; +////const e = {}; +////const f = {} as const; +////const g = (({} as const)); + +////const h = new C(); +////const i = new N.C(); +////const j = ((((new C())))); + +////const k = { a: 1, b: 1 }; +////const l = ((({ a: 1, b: 1 }))); + +//// const m = () => 123; +//// const n; + +verify.baselineInlayHints(undefined, { + includeInlayVariableTypeHints: true, + interactiveInlayHints: true +}); diff --git a/tests/cases/fourslash/inlayHintsInteractiveVariableTypes2.ts b/tests/cases/fourslash/inlayHintsInteractiveVariableTypes2.ts new file mode 100644 index 0000000000000..343c121b789ae --- /dev/null +++ b/tests/cases/fourslash/inlayHintsInteractiveVariableTypes2.ts @@ -0,0 +1,18 @@ +/// + +//// const object = { foo: 1, bar: 2 } +//// const array = [1, 2] +//// const a = object; +//// const { foo, bar } = object; +//// const {} = object; +//// const b = array; +//// const [ first, second ] = array; +//// const [] = array; + +//// declare function foo(t: T): T +//// const x = foo(1) + +verify.baselineInlayHints(undefined, { + includeInlayVariableTypeHints: true, + interactiveInlayHints: true +}); From 0497a330295c1b665b3af6a1b835449ee3405daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Solano?= Date: Mon, 18 Sep 2023 15:35:05 -0700 Subject: [PATCH 3/4] PR review --- src/services/inlayHints.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index d61dfbce9db0b..d8b4c75b0dd61 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -461,6 +461,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { const parts: InlayHintDisplayPart[] = []; visitDisplayPart(typeNode); + return parts; function visitDisplayPart(node: Node) { if (!node) { @@ -736,6 +737,8 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { visitDisplayPart(propertySignature.type); } break; + default: + Debug.failBadSyntaxKind(node); } } @@ -747,8 +750,6 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { visitDisplayPart(node); }); } - - return parts; } function isUndefined(name: __String) { From 080628a269c33c3b8bfeaa84eb73b030be5f384c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Solano?= Date: Tue, 19 Sep 2023 18:13:24 -0700 Subject: [PATCH 4/4] Rename visitor function --- src/services/inlayHints.ts | 76 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index d8b4c75b0dd61..c9025109d2491 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -460,10 +460,10 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { Debug.assertIsDefined(typeNode, "should always get typenode"); const parts: InlayHintDisplayPart[] = []; - visitDisplayPart(typeNode); + visitForDisplayParts(typeNode); return parts; - function visitDisplayPart(node: Node) { + function visitForDisplayParts(node: Node) { if (!node) { return; } @@ -494,24 +494,24 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { break; case SyntaxKind.QualifiedName: const qualifiedName = node as QualifiedName; - visitDisplayPart(qualifiedName.left); + visitForDisplayParts(qualifiedName.left); parts.push({ text: "." }); - visitDisplayPart(qualifiedName.right); + visitForDisplayParts(qualifiedName.right); break; case SyntaxKind.TypePredicate: const predicate = node as TypePredicateNode; if (predicate.assertsModifier) { parts.push({ text: "asserts " }); } - visitDisplayPart(predicate.parameterName); + visitForDisplayParts(predicate.parameterName); if (predicate.type) { parts.push({ text: " is " }); - visitDisplayPart(predicate.type); + visitForDisplayParts(predicate.type); } break; case SyntaxKind.TypeReference: const typeReference = node as TypeReferenceNode; - visitDisplayPart(typeReference.typeName); + visitForDisplayParts(typeReference.typeName); if (typeReference.typeArguments) { parts.push({ text: "<" }); visitDisplayPartList(typeReference.typeArguments, ", "); @@ -523,14 +523,14 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { if (typeParameter.modifiers) { visitDisplayPartList(typeParameter.modifiers, " "); } - visitDisplayPart(typeParameter.name); + visitForDisplayParts(typeParameter.name); if (typeParameter.constraint) { parts.push({ text: " extends " }); - visitDisplayPart(typeParameter.constraint); + visitForDisplayParts(typeParameter.constraint); } if (typeParameter.default) { parts.push({ text: " = " }); - visitDisplayPart(typeParameter.default); + visitForDisplayParts(typeParameter.default); } break; case SyntaxKind.Parameter: @@ -541,13 +541,13 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { if (parameter.dotDotDotToken) { parts.push({ text: "..." }); } - visitDisplayPart(parameter.name); + visitForDisplayParts(parameter.name); if (parameter.questionToken) { parts.push({ text: "?" }); } if (parameter.type) { parts.push({ text: ": " }); - visitDisplayPart(parameter.type); + visitForDisplayParts(parameter.type); } break; case SyntaxKind.ConstructorType: @@ -562,12 +562,12 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { visitDisplayPartList(constructorType.parameters, ", "); parts.push({ text: ")" }); parts.push({ text: " => " }); - visitDisplayPart(constructorType.type); + visitForDisplayParts(constructorType.type); break; case SyntaxKind.TypeQuery: const typeQuery = node as TypeQueryNode; parts.push({ text: "typeof " }); - visitDisplayPart(typeQuery.exprName); + visitForDisplayParts(typeQuery.exprName); if (typeQuery.typeArguments) { parts.push({ text: "<" }); visitDisplayPartList(typeQuery.typeArguments, ", "); @@ -585,7 +585,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { parts.push({ text: "}" }); break; case SyntaxKind.ArrayType: - visitDisplayPart((node as ArrayTypeNode).elementType); + visitForDisplayParts((node as ArrayTypeNode).elementType); parts.push({ text: "[]" }); break; case SyntaxKind.TupleType: @@ -598,20 +598,20 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { if (member.dotDotDotToken) { parts.push({ text: "..." }); } - visitDisplayPart(member.name); + visitForDisplayParts(member.name); if (member.questionToken) { parts.push({ text: "?" }); } parts.push({ text: ": " }); - visitDisplayPart(member.type); + visitForDisplayParts(member.type); break; case SyntaxKind.OptionalType: - visitDisplayPart((node as OptionalTypeNode).type); + visitForDisplayParts((node as OptionalTypeNode).type); parts.push({ text: "?" }); break; case SyntaxKind.RestType: parts.push({ text: "..." }); - visitDisplayPart((node as RestTypeNode).type); + visitForDisplayParts((node as RestTypeNode).type); break; case SyntaxKind.UnionType: visitDisplayPartList((node as UnionTypeNode).types, " | "); @@ -621,33 +621,33 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { break; case SyntaxKind.ConditionalType: const conditionalType = node as ConditionalTypeNode; - visitDisplayPart(conditionalType.checkType); + visitForDisplayParts(conditionalType.checkType); parts.push({ text: " extends " }); - visitDisplayPart(conditionalType.extendsType); + visitForDisplayParts(conditionalType.extendsType); parts.push({ text: " ? " }); - visitDisplayPart(conditionalType.trueType); + visitForDisplayParts(conditionalType.trueType); parts.push({ text: " : " }); - visitDisplayPart(conditionalType.falseType); + visitForDisplayParts(conditionalType.falseType); break; case SyntaxKind.InferType: parts.push({ text: "infer " }); - visitDisplayPart((node as InferTypeNode).typeParameter); + visitForDisplayParts((node as InferTypeNode).typeParameter); break; case SyntaxKind.ParenthesizedType: parts.push({ text: "(" }); - visitDisplayPart((node as ParenthesizedTypeNode).type); + visitForDisplayParts((node as ParenthesizedTypeNode).type); parts.push({ text: ")" }); break; case SyntaxKind.TypeOperator: const typeOperator = node as TypeOperatorNode; parts.push({ text: `${tokenToString(typeOperator.operator)} ` }); - visitDisplayPart(typeOperator.type); + visitForDisplayParts(typeOperator.type); break; case SyntaxKind.IndexedAccessType: const indexedAccess = node as IndexedAccessTypeNode; - visitDisplayPart(indexedAccess.objectType); + visitForDisplayParts(indexedAccess.objectType); parts.push({ text: "[" }); - visitDisplayPart(indexedAccess.indexType); + visitForDisplayParts(indexedAccess.indexType); parts.push({ text: "]" }); break; case SyntaxKind.MappedType: @@ -663,10 +663,10 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { parts.push({ text: "readonly " }); } parts.push({ text: "[" }); - visitDisplayPart(mappedType.typeParameter); + visitForDisplayParts(mappedType.typeParameter); if (mappedType.nameType) { parts.push({ text: " as " }); - visitDisplayPart(mappedType.nameType); + visitForDisplayParts(mappedType.nameType); } parts.push({ text: "]" }); if (mappedType.questionToken) { @@ -680,12 +680,12 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { } parts.push({ text: ": " }); if (mappedType.type) { - visitDisplayPart(mappedType.type); + visitForDisplayParts(mappedType.type); } parts.push({ text: "; }" }); break; case SyntaxKind.LiteralType: - visitDisplayPart((node as LiteralTypeNode).literal); + visitForDisplayParts((node as LiteralTypeNode).literal); break; case SyntaxKind.FunctionType: const functionType = node as FunctionTypeNode; @@ -698,7 +698,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { visitDisplayPartList(functionType.parameters, ", "); parts.push({ text: ")" }); parts.push({ text: " => " }); - visitDisplayPart(functionType.type); + visitForDisplayParts(functionType.type); break; case SyntaxKind.ImportType: const importType = node as ImportTypeNode; @@ -706,7 +706,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { parts.push({ text: "typeof " }); } parts.push({ text: "import(" }); - visitDisplayPart(importType.argument); + visitForDisplayParts(importType.argument); if (importType.assertions) { parts.push({ text: ", { assert: " }); visitDisplayPartList(importType.assertions.assertClause.elements, ", "); @@ -715,7 +715,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { parts.push({ text: ")" }); if (importType.qualifier) { parts.push({ text: "." }); - visitDisplayPart(importType.qualifier); + visitForDisplayParts(importType.qualifier); } if (importType.typeArguments) { parts.push({ text: "<" }); @@ -728,13 +728,13 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { if (propertySignature.modifiers) { visitDisplayPartList(propertySignature.modifiers, " "); } - visitDisplayPart(propertySignature.name); + visitForDisplayParts(propertySignature.name); if (propertySignature.questionToken) { parts.push({ text: "?" }); } if (propertySignature.type) { parts.push({ text: ": " }); - visitDisplayPart(propertySignature.type); + visitForDisplayParts(propertySignature.type); } break; default: @@ -747,7 +747,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] { if (index > 0) { parts.push({ text: separator }); } - visitDisplayPart(node); + visitForDisplayParts(node); }); } }