Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Compiler/Checking/NicePrint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ module internal PrintUtilities =
else
restL

let squashToWidth width layout =
match width with
| Some w -> Display.squashTo w layout
| None -> layout

module PrintIL =

let fullySplitILTypeRef (tref: ILTypeRef) =
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Checking/NicePrint.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ open FSharp.Compiler.TypedTreeOps
module PrintUtilities =
val layoutBuiltinAttribute: denv: DisplayEnv -> attrib: BuiltinAttribInfo -> Layout

val squashToWidth: width: int option -> Layout -> Layout

val layoutTyparConstraint: denv: DisplayEnv -> Typar * TyparConstraint -> Layout

val outputType: denv: DisplayEnv -> os: StringBuilder -> x: TType -> unit
Expand Down
26 changes: 17 additions & 9 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open System.IO
open System.Reflection
open System.Threading
open FSharp.Compiler.IO
open FSharp.Compiler.NicePrint
open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open FSharp.Core.Printf
Expand Down Expand Up @@ -350,7 +351,10 @@ type internal TypeCheckInfo
// this unchanged file. Keyed on lineStr though to prevent a change to the currently line
// being available against a stale scope.
let getToolTipTextCache =
AgedLookup<AnyCallerThreadToken, int * int * string, ToolTipText>(getToolTipTextSize, areSimilar = (fun (x, y) -> x = y))
AgedLookup<AnyCallerThreadToken, int * int * string * int option, ToolTipText>(
getToolTipTextSize,
areSimilar = (fun (x, y) -> x = y)
)

let amap = tcImports.GetImportMap()
let infoReader = InfoReader(g, amap)
Expand Down Expand Up @@ -1614,7 +1618,7 @@ type internal TypeCheckInfo
[])

/// Get the "reference resolution" tooltip for at a location
member _.GetReferenceResolutionStructuredToolTipText(line, col) =
member _.GetReferenceResolutionStructuredToolTipText(line, col, width) =

let pos = mkPos line col

Expand Down Expand Up @@ -1644,6 +1648,8 @@ type internal TypeCheckInfo
let tip =
wordL (TaggedText.tagStringLiteral ((resolved.prepareToolTip ()).TrimEnd([| '\n' |])))

let tip = PrintUtilities.squashToWidth width tip

let tip = LayoutRender.toArray tip
ToolTipText.ToolTipText [ ToolTipElement.Single(tip, FSharpXmlDoc.None) ]

Expand All @@ -1666,6 +1672,7 @@ type internal TypeCheckInfo
[
for line in lines ->
let tip = wordL (TaggedText.tagStringLiteral line)
let tip = PrintUtilities.squashToWidth width tip
let tip = LayoutRender.toArray tip
ToolTipElement.Single(tip, FSharpXmlDoc.None)
]
Expand All @@ -1688,12 +1695,12 @@ type internal TypeCheckInfo
}

let toolTipElement =
FormatStructuredDescriptionOfItem displayFullName infoReader accessorDomain m denv itemWithInst
FormatStructuredDescriptionOfItem displayFullName infoReader accessorDomain m denv itemWithInst None

ToolTipText [ toolTipElement ]

// GetToolTipText: return the "pop up" (or "Quick Info") text given a certain context.
member _.GetStructuredToolTipText(line, lineStr, colAtEndOfNames, names) =
member _.GetStructuredToolTipText(line, lineStr, colAtEndOfNames, names, width) =
let Compute () =
DiagnosticsScope.Protect
range0
Expand All @@ -1718,15 +1725,16 @@ type internal TypeCheckInfo
| Some (items, denv, _, m) ->
ToolTipText(
items
|> List.map (fun x -> FormatStructuredDescriptionOfItem false infoReader tcAccessRights m denv x.ItemWithInst)
|> List.map (fun x ->
FormatStructuredDescriptionOfItem false infoReader tcAccessRights m denv x.ItemWithInst width)
))

(fun err ->
Trace.TraceInformation(sprintf "FCS: recovering from error in GetStructuredToolTipText: '%s'" err)
ToolTipText [ ToolTipElement.CompositionError err ])

// See devdiv bug 646520 for rationale behind truncating and caching these quick infos (they can be big!)
let key = line, colAtEndOfNames, lineStr
let key = line, colAtEndOfNames, lineStr, width

match getToolTipTextCache.TryGet(AnyCallerThread, key) with
| Some res -> res
Expand Down Expand Up @@ -2685,17 +2693,17 @@ type FSharpCheckFileResults
]

/// Resolve the names at the given location to give a data tip
member _.GetToolTip(line, colAtEndOfNames, lineText, names, tokenTag) =
member _.GetToolTip(line, colAtEndOfNames, lineText, names, tokenTag, width) =
match tokenTagToTokenId tokenTag with
| TOKEN_IDENT ->
match details with
| None -> emptyToolTip
| Some (scope, _builderOpt) -> scope.GetStructuredToolTipText(line, lineText, colAtEndOfNames, names)
| Some (scope, _builderOpt) -> scope.GetStructuredToolTipText(line, lineText, colAtEndOfNames, names, width)
| TOKEN_STRING
| TOKEN_STRING_TEXT ->
match details with
| None -> emptyToolTip
| Some (scope, _builderOpt) -> scope.GetReferenceResolutionStructuredToolTipText(line, colAtEndOfNames)
| Some (scope, _builderOpt) -> scope.GetReferenceResolutionStructuredToolTipText(line, colAtEndOfNames, width)
| _ -> emptyToolTip

member _.GetDescription(symbol: FSharpSymbol, inst: (FSharpGenericParameter * FSharpType) list, displayFullName, range: range) =
Expand Down
4 changes: 3 additions & 1 deletion src/Compiler/Service/FSharpCheckerResults.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,10 @@ type public FSharpCheckFileResults =
/// <param name="lineText">The text of the line where the information is being requested.</param>
/// <param name="names">The identifiers at the location where the information is being requested.</param>
/// <param name="tokenTag">Used to discriminate between 'identifiers', 'strings' and others. For strings, an attempt is made to give a tooltip for a #r "..." location. Use a value from FSharpTokenInfo.Tag, or FSharpTokenTag.Identifier, unless you have other information available.</param>
/// <param name="width">The optional width that the layout gets squashed to.</param>
member GetToolTip:
line: int * colAtEndOfNames: int * lineText: string * names: string list * tokenTag: int -> ToolTipText
line: int * colAtEndOfNames: int * lineText: string * names: string list * tokenTag: int * ?width: int ->
ToolTipText

/// <summary>Compute a formatted tooltip for the given symbol at position</summary>
///
Expand Down
42 changes: 33 additions & 9 deletions src/Compiler/Service/ServiceDeclarationLists.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace FSharp.Compiler.EditorServices

open FSharp.Compiler.NicePrint
open Internal.Utilities.Library
open Internal.Utilities.Library.Extras
open FSharp.Compiler
Expand Down Expand Up @@ -92,7 +93,7 @@ module DeclarationListHelpers =
let emptyToolTip = ToolTipText []

/// Generate the structured tooltip for a method info
let FormatOverloadsToList (infoReader: InfoReader) m denv (item: ItemWithInst) minfos : ToolTipElement =
let FormatOverloadsToList (infoReader: InfoReader) m denv (item: ItemWithInst) minfos (width: int option) : ToolTipElement =
ToolTipFault |> Option.iter (fun msg ->
let exn = Error((0, msg), range.Zero)
let ph = PhasedDiagnostic.Create(exn, BuildPhase.TypeCheck)
Expand All @@ -103,6 +104,7 @@ module DeclarationListHelpers =
let prettyTyparInst, layout = NicePrint.prettyLayoutOfMethInfoFreeStyle infoReader m denv item.TyparInstantiation minfo
let xml = GetXmlCommentForMethInfoItem infoReader m item.Item minfo
let tpsL = FormatTyparMapping denv prettyTyparInst
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
let tpsL = List.map toArray tpsL
ToolTipElementData.Create(layout, xml, tpsL) ]
Expand Down Expand Up @@ -147,21 +149,22 @@ module DeclarationListHelpers =
let pubpathOfTyconRef (x: TyconRef) = x.PublicPath

/// Output the quick info information of a language item
let rec FormatItemDescriptionToToolTipElement displayFullName (infoReader: InfoReader) ad m denv (item: ItemWithInst) =
let rec FormatItemDescriptionToToolTipElement displayFullName (infoReader: InfoReader) ad m denv (item: ItemWithInst) (width: int option) =
let g = infoReader.g
let amap = infoReader.amap
let denv = SimplerDisplayEnv denv
let xml = GetXmlCommentForItem infoReader m item.Item
match item.Item with
| Item.ImplicitOp(_, { contents = Some(TraitConstraintSln.FSMethSln(vref=vref)) }) ->
// operator with solution
FormatItemDescriptionToToolTipElement displayFullName infoReader ad m denv { item with Item = Item.Value vref }
FormatItemDescriptionToToolTipElement displayFullName infoReader ad m denv { item with Item = Item.Value vref } width

| Item.Value vref | Item.CustomBuilder (_, vref) ->
let prettyTyparInst, resL = NicePrint.layoutQualifiedValOrMember denv infoReader item.TyparInstantiation vref
let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout vref
let tpsL = FormatTyparMapping denv prettyTyparInst
let tpsL = List.map toArray tpsL
let resL = PrintUtilities.squashToWidth width resL
let resL = toArray resL
let remarks = toArray remarks
ToolTipElement.Single(resL, xml, tpsL, remarks=remarks)
Expand All @@ -179,6 +182,7 @@ module DeclarationListHelpers =
RightL.colon ^^
(if List.isEmpty recd then emptyL else NicePrint.layoutUnionCases denv infoReader ucinfo.TyconRef recd ^^ WordL.arrow) ^^
NicePrint.layoutType denv unionTy
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -190,6 +194,7 @@ module DeclarationListHelpers =
wordL (tagActivePatternResult (List.item idx items) |> mkNav apinfo.Range) ^^
RightL.colon ^^
NicePrint.layoutType denv ty
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -205,6 +210,7 @@ module DeclarationListHelpers =
wordL (tagActivePatternCase apref.DisplayName |> mkNav v.DefinitionRange) ^^
RightL.colon ^^
NicePrint.layoutType denv prettyTy
let layout = PrintUtilities.squashToWidth width layout

let tpsL = FormatTyparMapping denv prettyTyparInst

Expand All @@ -216,6 +222,7 @@ module DeclarationListHelpers =
// F# exception names
| Item.ExnCase ecref ->
let layout = NicePrint.layoutExnDef denv infoReader ecref
let layout = PrintUtilities.squashToWidth width layout
let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfExnRefAsLayout ecref
let layout = toArray layout
let remarks = toArray remarks
Expand All @@ -229,6 +236,7 @@ module DeclarationListHelpers =
wordL (tagParameter id) ^^
RightL.colon ^^
NicePrint.layoutType denv ty
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml, paramName = id)

Expand All @@ -247,6 +255,7 @@ module DeclarationListHelpers =
| None -> emptyL
| Some lit -> try WordL.equals ^^ NicePrint.layoutConst denv.g ty lit with _ -> emptyL
)
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -259,6 +268,7 @@ module DeclarationListHelpers =
wordL (tagParameter id.idText) ^^
RightL.colon ^^
NicePrint.layoutType denv fieldTy
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml, paramName = id.idText)

Expand All @@ -267,6 +277,7 @@ module DeclarationListHelpers =
let layout =
wordL (tagText (FSComp.SR.typeInfoPatternVariable())) ^^
wordL (tagUnknownEntity id.idText)
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -286,6 +297,7 @@ module DeclarationListHelpers =
WordL.equals ^^
try NicePrint.layoutConst denv.g (finfo.FieldType(infoReader.amap, m)) (CheckExpressions.TcFieldInit m v) with _ -> emptyL
)
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -300,12 +312,14 @@ module DeclarationListHelpers =
wordL (tagEvent einfo.EventName) ^^
RightL.colon ^^
NicePrint.layoutType denv eventTy
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

// F# and .NET properties
| Item.Property(_, pinfo :: _) ->
let layout = NicePrint.prettyLayoutOfPropInfoFreeStyle g amap m denv pinfo
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -332,13 +346,14 @@ module DeclarationListHelpers =
SepL.dot ^^
wordL (tagMethod minfo.DisplayName)

let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

// F# constructors and methods
| Item.CtorGroup(_, minfos)
| Item.MethodGroup(_, minfos, _) ->
FormatOverloadsToList infoReader m denv item minfos
FormatOverloadsToList infoReader m denv item minfos width

// The 'fake' zero-argument constructors of .NET interfaces.
// This ideally should never appear in intellisense, but we do get here in repros like:
Expand All @@ -348,6 +363,7 @@ module DeclarationListHelpers =
| Item.FakeInterfaceCtor ty ->
let ty, _ = PrettyTypes.PrettifyType g ty
let layout = NicePrint.layoutTyconRef denv (tcrefOfAppTy g ty)
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single(layout, xml)

Expand All @@ -360,6 +376,7 @@ module DeclarationListHelpers =
LeftL.leftParen ^^
NicePrint.layoutType denv delFuncTy ^^
RightL.rightParen
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single(layout, xml)

Expand All @@ -374,6 +391,7 @@ module DeclarationListHelpers =
// be shown in the tip.
showDocumentation = false }
let layout = NicePrint.layoutTyconDefn denv infoReader ad m (* width *) tcref.Deref
let layout = PrintUtilities.squashToWidth width layout
let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfTyconRefAsLayout tcref
let layout = toArray layout
let remarks = toArray remarks
Expand All @@ -382,12 +400,14 @@ module DeclarationListHelpers =
// Type variables
| Item.TypeVar (_, typar) ->
let layout = NicePrint.prettyLayoutOfTypar denv typar
let layout = PrintUtilities.squashToWidth width layout
ToolTipElement.Single (toArray layout, xml)

// Traits
| Item.Trait traitInfo ->
let denv = { denv with shortConstraints = false}
let layout = NicePrint.prettyLayoutOfTrait denv traitInfo
let layout = PrintUtilities.squashToWidth width layout
ToolTipElement.Single (toArray layout, xml)

// F# Modules and namespaces
Expand Down Expand Up @@ -427,9 +447,11 @@ module DeclarationListHelpers =
else
emptyL
)
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)
else
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml)

Expand All @@ -442,6 +464,7 @@ module DeclarationListHelpers =
wordL (tagRecordField nm) ^^
RightL.colon ^^
NicePrint.layoutType denv argTy
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, FSharpXmlDoc.None)

Expand All @@ -453,11 +476,12 @@ module DeclarationListHelpers =
wordL (tagParameter id.idText) ^^
RightL.colon ^^
NicePrint.layoutType denv argTy
let layout = PrintUtilities.squashToWidth width layout
let layout = toArray layout
ToolTipElement.Single (layout, xml, paramName = id.idText)

| Item.SetterArg (_, item) ->
FormatItemDescriptionToToolTipElement displayFullName infoReader ad m denv (ItemWithNoInst item)
FormatItemDescriptionToToolTipElement displayFullName infoReader ad m denv (ItemWithNoInst item) width

| Item.ArgName (None, _, _, _)

Expand Down Expand Up @@ -499,9 +523,9 @@ module DeclarationListHelpers =
| Item.CustomOperation (_, _, None) -> ToolTipElement.None

/// Format the structured version of a tooltip for an item
let FormatStructuredDescriptionOfItem isDecl infoReader ad m denv item =
let FormatStructuredDescriptionOfItem isDecl infoReader ad m denv item width =
DiagnosticsScope.Protect m
(fun () -> FormatItemDescriptionToToolTipElement isDecl infoReader ad m denv item)
(fun () -> FormatItemDescriptionToToolTipElement isDecl infoReader ad m denv item width)
(fun err -> ToolTipElement.CompositionError err)

/// Represents one parameter for one method (or other item) in a group.
Expand Down Expand Up @@ -1010,7 +1034,7 @@ type DeclarationListItem(textInDeclList: string, textInCode: string, fullName: s
member _.Description =
match info with
| Choice1Of2 (items: CompletionItem list, infoReader, ad, m, denv) ->
ToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem true infoReader ad m denv x.ItemWithInst))
ToolTipText(items |> List.map (fun x -> FormatStructuredDescriptionOfItem true infoReader ad m denv x.ItemWithInst None))
| Choice2Of2 result ->
result

Expand Down Expand Up @@ -1273,7 +1297,7 @@ type MethodGroup( name: string, unsortedMethods: MethodGroupItem[] ) =
(fun () -> PrettyParamsAndReturnTypeOfItem infoReader m denv { item with Item = flatItem })
(fun err -> [], wordL (tagText err))

let description = ToolTipText [FormatStructuredDescriptionOfItem true infoReader ad m denv { item with Item = flatItem }]
let description = ToolTipText [FormatStructuredDescriptionOfItem true infoReader ad m denv { item with Item = flatItem } None]

let hasParamArrayArg =
match flatItem with
Expand Down
Loading