Skip to content

Commit

Permalink
Various improvement around TipFormatter and Documentation (#1099)
Browse files Browse the repository at this point in the history
Co-authored-by: Chet Husk <baronfel@users.noreply.github.com>
Co-authored-by: Maxime Mangel <maxime.shadaen@protonmail.com>
  • Loading branch information
3 people authored Apr 11, 2023
1 parent 935bf6e commit 37648cb
Show file tree
Hide file tree
Showing 8 changed files with 627 additions and 331 deletions.
77 changes: 48 additions & 29 deletions src/FsAutoComplete.Core/DocumentationFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,22 @@ module DocumentationFormatter =

let mutable lastDisplayContext: FSharpDisplayContext = FSharpDisplayContext.Empty

let emptyTypeTip = [||], [||], [||], [||], [||], [||]
type EntityInfo =
{ Constructors: string array
Fields: string array
Functions: string array
Interfaces: string array
Attributes: string array
DeclaredTypes: string array }

static member Empty =

{ Constructors = [||]
Fields = [||]
Functions = [||]
Interfaces = [||]
Attributes = [||]
DeclaredTypes = [||] }

/// Concat two strings with a space between if both a and b are not IsNullOrWhiteSpace
let internal (++) (a: string) (b: string) =
Expand Down Expand Up @@ -719,8 +734,12 @@ module DocumentationFormatter =
++ fst (formatShowDocumentationLink ne.DisplayName ne.XmlDocSig ne.Assembly.SimpleName))
|> Seq.toArray


constrc, fields, funcs, interfaces, attrs, types
{ Constructors = constrc
Fields = fields
Functions = funcs
Interfaces = interfaces
Attributes = attrs
DeclaredTypes = types }

let typeDisplay =
let name =
Expand Down Expand Up @@ -756,9 +775,9 @@ module DocumentationFormatter =
if fse.IsFSharpUnion then
(typeDisplay + uniontip ()), typeTip ()
elif fse.IsEnum then
(typeDisplay + enumtip ()), emptyTypeTip
(typeDisplay + enumtip ()), EntityInfo.Empty
elif fse.IsDelegate then
(typeDisplay + delegateTip ()), emptyTypeTip
(typeDisplay + delegateTip ()), EntityInfo.Empty
else
typeDisplay, typeTip ()

Expand Down Expand Up @@ -867,60 +886,60 @@ module DocumentationFormatter =
| Some ent when ent.IsValueType || ent.IsEnum ->
//ValueTypes
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)
| _ ->
//ReferenceType constructor
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Operator func ->
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Pattern func ->
//Active pattern or operator
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Property prop ->
let signature = getFuncSignature symbol.DisplayContext prop
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.ClosureOrNestedFunction func ->
//represents a closure or nested function
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Function func ->
let signature = getFuncSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Val func ->
//val name : Type
let signature = getValSignature symbol.DisplayContext func
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.Field fsf ->
let signature = getFieldSignature symbol.DisplayContext fsf
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.UnionCase uc ->
let signature = getUnioncaseSignature symbol.DisplayContext uc
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.ActivePatternCase apc ->
let signature = getAPCaseSignature symbol.DisplayContext apc
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.ActivePattern ap ->
let signature = getFuncSignature symbol.DisplayContext ap
Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| SymbolUse.GenericParameter gp ->
let signature =
$"'%s{gp.Name} (requires %s{formatGenericParameter false symbol.DisplayContext gp})"

Some((signature, emptyTypeTip), footerForType symbol, cn)
Some((signature, EntityInfo.Empty), footerForType symbol, cn)

| _ -> None

Expand All @@ -942,51 +961,51 @@ module DocumentationFormatter =
| Some ent when ent.IsValueType || ent.IsEnum ->
//ValueTypes
let signature = getFuncSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)
| _ ->
//ReferenceType constructor
let signature = getFuncSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| SymbolPatterns.Operator func ->
let signature = getFuncSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| Property prop ->
let signature = getFuncSignature lastDisplayContext prop
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| ClosureOrNestedFunction func ->
//represents a closure or nested function
let signature = getFuncSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| Function func ->
let signature = getFuncSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| Val func ->
//val name : Type
let signature = getValSignature lastDisplayContext func
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| Field(fsf, _) ->
let signature = getFieldSignature lastDisplayContext fsf
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| UnionCase uc ->
let signature = getUnioncaseSignature lastDisplayContext uc
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| ActivePatternCase apc ->
let signature = getAPCaseSignature lastDisplayContext apc
Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)


| GenericParameter gp ->
let signature =
$"'%s{gp.Name} (requires %s{formatGenericParameter false lastDisplayContext gp})"

Some((signature, emptyTypeTip), footerForType' symbol, cn)
Some((signature, EntityInfo.Empty), footerForType' symbol, cn)

| _ -> None
49 changes: 42 additions & 7 deletions src/FsAutoComplete.Core/ParseAndCheckResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ type FindDeclarationResult =
/// The declaration refers to a file.
| File of string

[<RequireQualifiedAccess>]
module TryGetToolTipEnhancedResult =

type SymbolInfo =
| Keyword of string
| Symbol of
{| XmlDocSig: string
Assembly: string |}

type TryGetToolTipEnhancedResult =
{ ToolTipText: ToolTipText
Signature: string
Footer: string
SymbolInfo: TryGetToolTipEnhancedResult.SymbolInfo }

type ParseAndCheckResults
(parseResults: FSharpParseFileResults, checkResults: FSharpCheckFileResults, entityCache: EntityCache) =

Expand Down Expand Up @@ -320,7 +335,10 @@ type ParseAndCheckResults
| _ -> ResultOrString.Error "No tooltip information"
| _ -> Ok(tip)

member x.TryGetToolTipEnhanced (pos: Position) (lineStr: LineStr) =
member x.TryGetToolTipEnhanced
(pos: Position)
(lineStr: LineStr)
: Result<option<TryGetToolTipEnhancedResult>, string> =
let (|EmptyTooltip|_|) (ToolTipText elems) =
match elems with
| [] -> Some()
Expand All @@ -347,21 +365,38 @@ type ParseAndCheckResults
match identIsland with
| [ ident ] ->
match KeywordList.keywordTooltips.TryGetValue ident with
| true, tip -> Ok(Some(tip, ident, "", None))
| true, tip ->
{ ToolTipText = tip
Signature = ident
Footer = ""
SymbolInfo = TryGetToolTipEnhancedResult.Keyword ident }
|> Some
|> Ok
| _ -> Error "No tooltip information"
| _ -> Error "No tooltip information"
| _ ->
match symbol with
| None -> Error "No tooltip information"
| Some symbol ->

// Retrieve the FSharpSymbol instance so we can find the XmlDocSig
// This mimic, the behavior of the Info Panel on hover
// 1. If this is a concrete type it returns that type reference
// 2. If this a type alias, it returns the aliases type reference
let resolvedType = symbol.Symbol.GetAbbreviatedParent()

match SignatureFormatter.getTooltipDetailsFromSymbolUse symbol with
| None -> Error "No tooltip information"
| Some(signature, footer) ->
let typeDoc =
getTypeIfConstructor symbol.Symbol |> Option.map (fun n -> n.XmlDocSig)

Ok(Some(tip, signature, footer, typeDoc))
{ ToolTipText = tip
Signature = signature
Footer = footer
SymbolInfo =
TryGetToolTipEnhancedResult.Symbol
{| XmlDocSig = resolvedType.XmlDocSig
Assembly = symbol.Symbol.Assembly.SimpleName |} }
|> Some
|> Ok

member __.TryGetFormattedDocumentation (pos: Position) (lineStr: LineStr) =
match Lexer.findLongIdents (pos.Column, lineStr) with
Expand All @@ -380,7 +415,7 @@ type ParseAndCheckResults
match identIsland with
| [ ident ] ->
match KeywordList.keywordTooltips.TryGetValue ident with
| true, tip -> Ok(Some tip, None, (ident, (DocumentationFormatter.emptyTypeTip)), "", "")
| true, tip -> Ok(Some tip, None, (ident, DocumentationFormatter.EntityInfo.Empty), "", "")
| _ -> Error "No tooltip information"
| _ -> Error "No documentation information"
| _ ->
Expand Down
Loading

0 comments on commit 37648cb

Please sign in to comment.