Skip to content

Commit

Permalink
Render parameters that are function-typed with parens for accessibili…
Browse files Browse the repository at this point in the history
…ty (#785)
  • Loading branch information
baronfel authored Jun 13, 2021
1 parent b013245 commit 0df6261
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 246 deletions.
2 changes: 1 addition & 1 deletion src/FsAutoComplete.Core/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,7 @@ type Commands (checker: FSharpCompilerServiceChecker, state: State, backgroundSe
let parseOpts = Utils.projectOptionsToParseOptions opts
let! ast = checker.ParseFile(file, text, parseOpts)
match ast.ParseTree with
| None -> return! Error (ast.Errors |> Array.map string |> String.concat "\n")
| None -> return! Error (ast.Errors |> Array.map string |> String.concat Environment.NewLine)
| Some ast' ->
let ranges = Structure.getOutliningRanges (text.ToString().Split("\n")) ast'
return ranges
Expand Down
19 changes: 10 additions & 9 deletions src/FsAutoComplete.Core/DocumentationFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module DocumentationFormatter =
open System
open System.Text

let nl = Environment.NewLine
let maxPadding = 200

let mutable lastDisplayContext : FSharpDisplayContext = FSharpDisplayContext.Empty
Expand Down Expand Up @@ -295,14 +296,14 @@ module DocumentationFormatter =
|> List.map(fun (paramTypes, length) ->
paramTypes
|> List.map (formatParameterPadded length)
|> String.concat (" *\n"))
|> String.concat ("->\n")
|> String.concat $" *{nl}")
|> String.concat $"->{nl}"

let typeArguments =
allParams + "\n" + indent + (String.replicate (max (padLength-1) 0) " ") + "->" ++ retType ++ retTypeConstraint
allParams + nl + indent + (String.replicate (max (padLength-1) 0) " ") + "->" ++ retType ++ retTypeConstraint

if isDelegate then typeArguments
else modifiers ++ functionName + ": \n" + typeArguments
else modifiers ++ $"{functionName}:{nl}{typeArguments}"

let getFuncSignatureForTypeSignature displayContext (func: FSharpMemberOrFunctionOrValue) (getter: bool) (setter : bool) =
let functionName =
Expand Down Expand Up @@ -478,25 +479,25 @@ module DocumentationFormatter =
| _ -> "type"

let enumtip () =
" =\n |" ++
$" ={nl} |" ++
(fse.FSharpFields
|> Seq.filter (fun f -> not f.IsCompilerGenerated)
|> Seq.sortBy (fun f -> match f.LiteralValue with | None -> -1 | Some lv -> Int32.Parse (string lv) )
|> Seq.map (fun field -> match field.LiteralValue with
| Some lv -> field.Name + " = " + (string lv)
| None -> field.Name )
|> String.concat ("\n | " ) )
|> String.concat $"{nl} | ")

let uniontip () =
" =\n |" ++ (fse.UnionCases
$" ={nl} |" ++ (fse.UnionCases
|> Seq.map (getUnioncaseSignature displayContext)
|> String.concat ("\n | " ) )
|> String.concat ("{nl} | " ) )

let delegateTip () =
let invoker =
fse.MembersFunctionsAndValues |> Seq.find (fun f -> f.DisplayName = "Invoke")
let invokerSig = getFuncSignatureWithIdent displayContext invoker 6
" =\n delegate of\n" + invokerSig
$" ={nl} delegate of{nl}{invokerSig}"

let typeTip () =
let constrc =
Expand Down
2 changes: 1 addition & 1 deletion src/FsAutoComplete.Core/DotnetNewTemplate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module DotnetNewTemplate =
let mutable output = ""
while not proc.StandardOutput.EndOfStream do
let line = proc.StandardOutput.ReadLine()
output <- output + "\n" + line
output <- output + Environment.NewLine + line
output

let parseTemplateOutput (x: string) =
Expand Down
77 changes: 47 additions & 30 deletions src/FsAutoComplete.Core/SignatureFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module SignatureFormatter =
open System
open System.Text

let nl = Environment.NewLine
let maxPadding = 20

/// Concat two strings with a space between if both a and b are not IsNullOrWhiteSpace
Expand Down Expand Up @@ -245,7 +246,11 @@ module SignatureFormatter =
| _ -> false

let formatParameter (p:FSharpParameter) =
try formatFSharpType displayContext p.Type
try
let formatted = formatFSharpType displayContext p.Type
if p.Type.IsFunctionType
then $"({formatted})"
else formatted
with :? InvalidOperationException -> p.DisplayName

match argInfos with
Expand All @@ -267,35 +272,38 @@ module SignatureFormatter =

let allParamsLengths =
many |> List.map (List.map (fun p -> (formatParameter p).Length) >> List.sum)
let maxLength = (allParamsLengths |> List.maxUnderThreshold maxPadding)+1

let parameterTypeWithPadding (p: FSharpParameter) length =
(formatParameter p) + (String.replicate (if length >= maxLength then 1 else maxLength - length) " ")
let maxLength = (allParamsLengths |> List.maxUnderThreshold maxPadding)+1

let formatParameterPadded length p =
let paddedParam = formatName indent padLength p ++ (parameterTypeWithPadding p length)
let namePart = formatName indent padLength p
let paramType = formatParameter p
let paramFormat = namePart ++ paramType

if p.Type.IsGenericParameter then
let padding = String.replicate (if length >= maxLength then 1 else maxLength - length) " "
let paramConstraint =
let formattedParam = formatGenericParameter false displayContext p.Type.GenericParameter
if String.IsNullOrWhiteSpace formattedParam then formattedParam
else "(requires " + formattedParam + " )"
if paramConstraint = retTypeConstraint then paddedParam
else paddedParam + paramConstraint
else paddedParam
if paramConstraint = retTypeConstraint then paramFormat
else paramFormat + padding + paramConstraint
else paramFormat

let allParams =
List.zip many allParamsLengths
|> List.map(fun (paramTypes, length) ->
paramTypes
|> List.map (formatParameterPadded length)
|> String.concat (" *\n"))
|> String.concat ("->\n")
|> String.concat $" *{nl}")
|> String.concat $" ->{nl}"

let typeArguments =
allParams + "\n" + indent + (String.replicate (max (padLength-1) 0) " ") + "->" ++ retType ++ retTypeConstraint
let padding = String.replicate (max (padLength-1) 0) " "
$"{allParams}{nl}{indent}{padding}->" ++ retType ++ retTypeConstraint

if isDelegate then typeArguments
else modifiers ++ functionName + ": \n" + typeArguments
else modifiers ++ $"{functionName}:{nl}{typeArguments}"

let getFuncSignatureForTypeSignature displayContext (func: FSharpMemberOrFunctionOrValue) (overloads : int) (getter: bool) (setter : bool) =
let functionName =
Expand Down Expand Up @@ -379,7 +387,10 @@ module SignatureFormatter =
| many ->
let formatParameter (p:FSharpParameter) =
try
formatFSharpType displayContext p.Type
let formatted = formatFSharpType displayContext p.Type
if p.Type.IsFunctionType
then $"({formatted})"
else formatted
with
| :? InvalidOperationException -> p.DisplayName

Expand Down Expand Up @@ -473,24 +484,24 @@ module SignatureFormatter =
| _ -> "type"

let enumtip () =
" =\n |" ++
$" ={nl} |" ++
(fse.FSharpFields
|> Seq.filter (fun f -> not f.IsCompilerGenerated)
|> Seq.map (fun field -> match field.LiteralValue with
| Some lv -> field.Name + " = " + (string lv)
| None -> field.Name )
|> String.concat ("\n | " ) )
|> String.concat $"{nl} | " )

let uniontip () =
" =\n |" ++ (fse.UnionCases
$" ={nl} |" ++ (fse.UnionCases
|> Seq.map (getUnioncaseSignature displayContext)
|> String.concat ("\n | " ) )
|> String.concat $"{nl} | " )

let delegateTip () =
let invoker =
fse.MembersFunctionsAndValues |> Seq.find (fun f -> f.DisplayName = "Invoke")
let invokerSig = getFuncSignatureWithIdent displayContext invoker 6
" =\n delegate of\n" + invokerSig
$" ={nl} delegate of{nl}{invokerSig}"

let typeTip () =
let constrc =
Expand Down Expand Up @@ -533,13 +544,13 @@ module SignatureFormatter =
[ yield constrc
if not fse.IsFSharpModule then
yield! fields
if Seq.length fields > 0 then yield "\n"
if Seq.length fields > 0 then yield nl
yield! funcs
]
|> Seq.distinct
|> String.concat "\n "
|> String.concat $"{nl} "

if String.IsNullOrWhiteSpace res then "" else "\n " + res
if String.IsNullOrWhiteSpace res then "" else $"{nl} {res}"

let typeDisplay =
let name =
Expand Down Expand Up @@ -573,28 +584,34 @@ module SignatureFormatter =
elif fse.IsDelegate then typeDisplay + delegateTip ()
else typeDisplay + typeTip ()

let footerForType (entity: FSharpSymbolUse) =
let formatFooter (fullName, assyName) =
$"Full name: %s{fullName}{nl}Assembly: %s{assyName}"


let footerForType (entity:FSharpSymbolUse) =
let valFooterData =
try
match entity with
| SymbolUse.MemberFunctionOrValue m ->
sprintf "Full name: %s\nAssembly: %s" m.FullName m.Assembly.SimpleName
Some(m.FullName, m.Assembly.SimpleName)

| SymbolUse.Entity (c, _) ->
sprintf "Full name: %s\nAssembly: %s" c.FullName c.Assembly.SimpleName
Some(c.FullName, c.Assembly.SimpleName)

| SymbolUse.Field f ->
sprintf "Full name: %s\nAssembly: %s" f.FullName f.Assembly.SimpleName
Some(f.FullName, f.Assembly.SimpleName)

| SymbolUse.ActivePatternCase ap ->
sprintf "Full name: %s\nAssembly: %s" ap.FullName ap.Assembly.SimpleName
Some(ap.FullName, ap.Assembly.SimpleName)

| SymbolUse.UnionCase uc ->
sprintf "Full name: %s\nAssembly: %s" uc.FullName uc.Assembly.SimpleName
| _ -> ""
Some(uc.FullName, uc.Assembly.SimpleName)
| _ -> None
with
| _ -> ""
| _ -> None

valFooterData
|> Option.map formatFooter
|> Option.defaultValue ""

///Returns formated symbol signature and footer that can be used to enhance standard FCS' text tooltips
let getTooltipDetailsFromSymbolUse (symbol:FSharpSymbolUse) =
Expand Down
2 changes: 1 addition & 1 deletion src/FsAutoComplete.Core/SignatureHelp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ let getText (lines: ISourceText) (range: Range) =
let line = lineText lines range.Start
line.Substring(range.StartColumn - 1, (range.End.Column - range.Start.Column))
else
String.concat "\n" (seq {
String.concat Environment.NewLine (seq {
let startLine = lineText lines range.Start
yield startLine.Substring(range.StartColumn - 1, (startLine.Length - 1 - range.Start.Column))
for lineNo in (range.Start.Line+1)..(range.End.Line-1) do
Expand Down
24 changes: 12 additions & 12 deletions src/FsAutoComplete.Core/TipFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module private Section =
|> Seq.map (fun line ->
"> " + line.TrimStart()
)
|> String.concat "\n"
|> String.concat Environment.NewLine
|> (+) nl // Start the quote block on a new line
else
kv.Value
Expand Down Expand Up @@ -677,14 +677,14 @@ module private Format =

items
|> List.map (itemListToStringAsMarkdownList "*")
|> String.concat "\n"
|> String.concat Environment.NewLine

| Numbered ->
let items = extractItemList [] innerText

items
|> List.map (itemListToStringAsMarkdownList "1.")
|> String.concat "\n"
|> String.concat Environment.NewLine

| Tablered ->
let columnHeaders = extractColumnHeader [] innerText
Expand Down Expand Up @@ -728,13 +728,13 @@ module private Format =
)
|> String.concat ""
)
|> String.concat "\n"
|> String.concat Environment.NewLine

"\n"
Environment.NewLine
+ columnHeadersText
+ "\n"
+ Environment.NewLine
+ seprator
+ "\n"
+ Environment.NewLine
+ itemsText
|> Some
}
Expand Down Expand Up @@ -794,7 +794,7 @@ type private XmlDocMember(doc: XmlDocument, indentationSize : int, columnOffset
else
line
)
|> String.concat "\n"
|> String.concat Environment.NewLine

let readChildren name (doc: XmlDocument) =
doc.DocumentElement.GetElementsByTagName name
Expand Down Expand Up @@ -972,7 +972,7 @@ let private buildFormatComment cmt (formatStyle : FormatCommentStyle) (typeDoc:
match cmt with
| FSharpXmlDoc.Text (unprocessed, processed) ->
try
let document = processed |> String.concat "\n"
let document = processed |> String.concat Environment.NewLine
// We create a "fake" XML document in order to use the same parser for both libraries and user code
let xml = sprintf "<fake>%s</fake>" document
let doc = XmlDocument()
Expand Down Expand Up @@ -1080,8 +1080,8 @@ let formatTipEnhanced (FSharpToolTipText tips) (signature : string) (footer : st
buildFormatComment i.XmlDoc formatCommentStyle typeDoc
else
buildFormatComment i.XmlDoc formatCommentStyle typeDoc
+ "\n\n**Generic Parameters**\n\n"
+ (i.TypeMapping |> List.map formatGenericParamInfo |> String.concat "\n")
+ nl + nl + "**Generic Parameters**" + nl + nl
+ (i.TypeMapping |> List.map formatGenericParamInfo |> String.concat nl)
(signature, comment, footer)))
| FSharpToolTipElement.CompositionError (error) -> Some [("<Note>", error, "")]
| _ -> None)
Expand All @@ -1096,7 +1096,7 @@ let formatDocumentation (FSharpToolTipText tips) ((signature, (constructors, fie
buildFormatComment i.XmlDoc FormatCommentStyle.Documentation None
else
buildFormatComment i.XmlDoc FormatCommentStyle.Documentation None
+ "\n\n**Generic Parameters**\n\n"
+ nl + nl + "**Generic Parameters**" + nl + nl
+ (i.TypeMapping |> List.map formatGenericParamInfo |> String.concat "\n")

(signature, constructors, fields, functions, interfaces, attrs, ts, comment, footer, cn)))
Expand Down
4 changes: 2 additions & 2 deletions src/FsAutoComplete/CommandResponse.fs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ module CommandResponse =
yield! getMessageLines er |> Seq.map (fun line -> sprintf " - %s" line)]) ]
|Ionide.ProjInfo.Types.GenericError (_, errorMessage) -> [errorMessage]
|Ionide.ProjInfo.Types.ProjectNotRestored _ -> ["Project not restored"]
let msg = getMessageLines errorDetails |> fun s -> String.Join("\n", s)
let msg = getMessageLines errorDetails |> String.concat Environment.NewLine
match errorDetails with
|Ionide.ProjInfo.Types.ProjectNotFound (project) -> errorG serialize (ErrorData.GenericProjectError { Project = project }) msg
|Ionide.ProjInfo.Types.LanguageNotSupported (project) -> errorG serialize (ErrorData.GenericProjectError { Project = project }) msg
Expand Down Expand Up @@ -515,7 +515,7 @@ module CommandResponse =

let formattedDocumentationForSymbol (serialize : Serializer) xml assembly (xmlDoc : string list) (signature, footer, cn) =
let data = TipFormatter.formatDocumentationFromXmlSig xml assembly signature footer cn |> List.map(List.map(fun (n,cns, fds, funcs, intf, attrs, ts, m,f, cn) ->
let m = if String.IsNullOrWhiteSpace m then xmlDoc |> String.concat "\n" else m
let m = if String.IsNullOrWhiteSpace m then xmlDoc |> String.concat Environment.NewLine else m
{XmlKey = cn; Constructors = cns |> Seq.toList; Fields = fds |> Seq.toList; Functions = funcs |> Seq.toList; Interfaces = intf |> Seq.toList; Attributes = attrs |> Seq.toList; Types = ts |> Seq.toList; Footer =f; Signature = n; Comment = m} ))
serialize { Kind = "formattedDocumentation"; Data = data }

Expand Down
6 changes: 3 additions & 3 deletions src/FsAutoComplete/FsAutoComplete.Lsp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -884,11 +884,11 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS
| (sigCommentFooter::_)::_ ->
let signature, comment, footer = sigCommentFooter
let markStr lang (value:string) = MarkedString.WithLanguage { Language = lang ; Value = value }
let fsharpBlock (lines: string[]) = lines |> String.concat "\n" |> markStr "fsharp"
let fsharpBlock (lines: string[]) = lines |> String.concat Environment.NewLine |> markStr "fsharp"

let sigContent =
let lines =
signature.Split '\n'
signature.Split Environment.NewLine
|> Array.filter (not << String.IsNullOrWhiteSpace)

match lines |> Array.splitAt (lines.Length - 1) with
Expand All @@ -903,7 +903,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS
|> MarkedString.String

let footerContent =
footer.Split '\n'
footer.Split Environment.NewLine
|> Array.filter (not << String.IsNullOrWhiteSpace)
|> Array.map (fun n -> MarkedString.String ("*" + n + "*"))

Expand Down
Loading

0 comments on commit 0df6261

Please sign in to comment.