diff --git a/src/services/services.ts b/src/services/services.ts index b8300aba0c34c..ca5670021c658 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1587,7 +1587,9 @@ namespace ts { kind: ScriptElementKind.unknown, kindModifiers: ScriptElementKindModifier.none, textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile), - displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo))), + displayParts: prefixWithApproximation( + typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo))) + ), documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, tags: type.symbol ? type.symbol.getJsDocTags() : undefined }; @@ -1600,7 +1602,7 @@ namespace ts { kind: symbolKind, kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile), - displayParts, + displayParts: prefixWithApproximation(displayParts), documentation, tags, }; @@ -1630,6 +1632,13 @@ namespace ts { } } + function prefixWithApproximation(displayParts: SymbolDisplayPart[]): SymbolDisplayPart[] { + if (languageServiceMode === LanguageServiceMode.Semantic) { + return displayParts; + } + return [textPart("(approximation)"), spacePart(), ...displayParts]; + } + /// Goto definition function getDefinitionAtPosition(fileName: string, position: number): readonly DefinitionInfo[] | undefined { synchronizeHostData(); diff --git a/src/testRunner/unittests/tsserver/partialSemanticServer.ts b/src/testRunner/unittests/tsserver/partialSemanticServer.ts index d821ccc1a36bb..c2722e0958d67 100644 --- a/src/testRunner/unittests/tsserver/partialSemanticServer.ts +++ b/src/testRunner/unittests/tsserver/partialSemanticServer.ts @@ -30,6 +30,22 @@ import { something } from "something"; return { host, session, file1, file2, file3, something, configFile }; } + it("adds '(approximation)' to the description of quick info", () => { + const file: File = { + path: `${tscWatch.projectRoot}/foo.ts`, + content: "export const foo = 100;" + }; + const host = createServerHost([file]); + const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true }); + openFilesForSession([file], session); + const response = session.executeCommandSeq({ + command: protocol.CommandTypes.Quickinfo, + arguments: protocolFileLocationFromSubstring(file, "foo"), + }).response as protocol.QuickInfoResponseBody; + + assert(stringContainsAt(response.displayString, "(approximation)", 0)); + }); + it("open files are added to inferred project even if config file is present and semantic operations succeed", () => { const { host, session, file1, file2 } = setup(); const service = session.getProjectService();