diff --git a/.github/workflows/bump-fcs.yml b/.github/workflows/bump-fcs.yml
index cfbf40366..6a11213ba 100644
--- a/.github/workflows/bump-fcs.yml
+++ b/.github/workflows/bump-fcs.yml
@@ -23,6 +23,7 @@ jobs:
- name: bump FCS
run: dotnet paket update FSharp.Compiler.Service
- name: check if there are changes
+ continue-on-error: true # nonzero exit codes are expected if there are changes
id: check
run: |
git diff --exit-code
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 818c44fef..771841b93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## [0.59.2] - 2023-03-12
+
+### Added
+
+* [A new codefix that converts 'bare' ///-comments to full XML documentation comments](https://github.com/fsharp/fsautocomplete/pull/1068) (thanks @dawedawe!)
+
+### Changed
+
+* [Enhancements to Find All References and Rename operations](https://github.com/fsharp/fsautocomplete/pull/1037) (thanks @BooksBaum and @theangrybyrd!)
+* [Internal errors no longer report as LSP protocol errors](https://github.com/fsharp/fsautocomplete/pull/1069)
+* [TestAdapterEntry items now include module information as well](https://github.com/fsharp/fsautocomplete/pull/1071) (thanks @kojo12228!)
+
+### Fixed
+
+* [IndexOutOfRange issue in signatureHelp](https://github.com/fsharp/fsautocomplete/pull/1067) (thanks @vain0x!)
+* [ThreadPool exhaustion issue with ProgressListener](https://github.com/fsharp/fsautocomplete/pull/1070) (thanks @theangrybyrd!)
+* [The 'convert positional DU usage to named patterns' codefix now works with multiple match clauses in the same pattern](https://github.com/fsharp/fsautocomplete/pull/1073) (thanks @dawedawe!)
+
## [0.59.1] - 2023-02-26
### Added
diff --git a/src/FsAutoComplete.Core/Commands.fs b/src/FsAutoComplete.Core/Commands.fs
index 5e753e46d..99544e501 100644
--- a/src/FsAutoComplete.Core/Commands.fs
+++ b/src/FsAutoComplete.Core/Commands.fs
@@ -58,9 +58,10 @@ type DocumentEdit =
module private Result =
let ofCoreResponse (r: CoreResponse<'a>) =
match r with
- | CoreResponse.Res a -> Ok a
- | CoreResponse.ErrorRes msg
- | CoreResponse.InfoRes msg -> Error msg
+ | CoreResponse.Res a -> Ok(Some a)
+ | CoreResponse.InfoRes _ -> Ok None
+ | CoreResponse.ErrorRes msg -> Error msg
+
module AsyncResult =
@@ -1894,47 +1895,50 @@ type Commands(checker: FSharpCompilerServiceChecker, state: State, hasAnalyzers:
let indentLength = lineStr.Length - trimmed.Length
let indentString = String.replicate indentLength " "
- let! (_, memberParameters, genericParameters) =
- Commands.SignatureData tyRes triggerPosition lineStr |> Result.ofCoreResponse
+ match! Commands.SignatureData tyRes triggerPosition lineStr |> Result.ofCoreResponse with
+ | None -> return None
+ | Some(_, memberParameters, genericParameters) ->
- let summarySection = "/// "
- let parameterSection (name, _type) =
- $"/// "
+ let summarySection = "/// "
- let genericArg name =
- $"/// "
+ let parameterSection (name, _type) =
+ $"/// "
- let returnsSection = "/// "
+ let genericArg name =
+ $"/// "
- let formattedXmlDoc =
- seq {
- yield summarySection
+ let returnsSection = "/// "
- match memberParameters with
- | [] -> ()
- | parameters ->
- yield!
- parameters
- |> List.concat
- |> List.mapi (fun _index parameter -> parameterSection parameter)
+ let formattedXmlDoc =
+ seq {
+ yield summarySection
- match genericParameters with
- | [] -> ()
- | generics -> yield! generics |> List.mapi (fun _index generic -> genericArg generic)
+ match memberParameters with
+ | [] -> ()
+ | parameters ->
+ yield!
+ parameters
+ |> List.concat
+ |> List.mapi (fun _index parameter -> parameterSection parameter)
- yield returnsSection
- }
- |> Seq.map (fun s -> indentString + s)
- |> String.concat Environment.NewLine
- |> fun s -> s + Environment.NewLine // need a newline at the very end
+ match genericParameters with
+ | [] -> ()
+ | generics -> yield! generics |> List.mapi (fun _index generic -> genericArg generic)
+
+ yield returnsSection
+ }
+ |> Seq.map (fun s -> indentString + s)
+ |> String.concat Environment.NewLine
+ |> fun s -> s + Environment.NewLine // need a newline at the very end
- // always insert at the start of the line, because we've prepended the indent to the start of the summary section
- let insertPosition = Position.mkPos triggerPosition.Line 0
+ // always insert at the start of the line, because we've prepended the indent to the start of the summary section
+ let insertPosition = Position.mkPos triggerPosition.Line 0
- return
- { InsertPosition = insertPosition
- InsertText = formattedXmlDoc }
+ return
+ Some
+ { InsertPosition = insertPosition
+ InsertText = formattedXmlDoc }
}
member private x.GetDeclarationLocation(symbolUse, text) =
diff --git a/src/FsAutoComplete.Core/TestAdapter.fs b/src/FsAutoComplete.Core/TestAdapter.fs
index 7da530192..622d89723 100644
--- a/src/FsAutoComplete.Core/TestAdapter.fs
+++ b/src/FsAutoComplete.Core/TestAdapter.fs
@@ -10,6 +10,7 @@ type TestAdapterEntry<'range> =
Childs: ResizeArray>
Id: int
List: bool
+ ModuleType: string
Type: string }
[]
@@ -21,6 +22,18 @@ let private NUnitType = "NUnit"
[]
let private XUnitType = "XUnit"
+[]
+let private NoneModuleType = "NoneModule"
+
+[]
+let private ModuleType = "Module"
+
+[]
+let private TypeInModule = "TypeInModule"
+
+[]
+let private ModuleWithSuffixType = "ModuleWithSuffix"
+
let rec private (|Sequentials|_|) =
function
| SynExpr.Sequential(_, _, e, Sequentials es, _) -> Some(e :: es)
@@ -86,6 +99,7 @@ let getExpectoTests (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = NoneModuleType
Type = ExpectoType }
parent.Childs.Add entry
@@ -103,6 +117,7 @@ let getExpectoTests (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = false
+ ModuleType = NoneModuleType
Type = ExpectoType }
parent.Childs.Add entry
@@ -131,6 +146,7 @@ let getExpectoTests (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = false
+ ModuleType = NoneModuleType
Type = ExpectoType }
parent.Childs.Add entry
@@ -208,6 +224,7 @@ let getExpectoTests (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = -1
List = false
+ ModuleType = NoneModuleType
Type = "" }
match ast with
@@ -256,6 +273,13 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
let (SynTypeDefn(typeInfo = ci; typeRepr = om; members = members)) = t
let (SynComponentInfo(longId = ids; range = r)) = ci
let name = String.concat "." [ for i in ids -> i.idText ]
+
+ let moduleType =
+ if parent.ModuleType = ModuleType || parent.ModuleType = ModuleWithSuffixType then
+ TypeInModule
+ else
+ NoneModuleType
+
ident <- ident + 1
let entry =
@@ -264,6 +288,7 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = NUnitType }
parent.Childs.Add entry
@@ -292,11 +317,27 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = false
+ ModuleType = NoneModuleType
Type = NUnitType }
parent.Childs.Add entry
let rec visitDeclarations (parent: TestAdapterEntry) decls =
+ let typeNames =
+ decls
+ |> List.fold
+ (fun types declaration ->
+ match declaration with
+ | SynModuleDecl.Types(typeDefns, _) ->
+ typeDefns
+ |> List.map (fun (SynTypeDefn(typeInfo = ci)) ->
+ let (SynComponentInfo(longId = ids)) = ci
+ String.concat "." [ for i in ids -> i.idText ])
+ |> List.append types
+ | _ -> types)
+ ([])
+ |> Set.ofList
+
for declaration in decls do
match declaration with
| SynModuleDecl.Let(_, bindings, _) ->
@@ -305,6 +346,13 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
| SynModuleDecl.NestedModule(moduleInfo = ci; decls = decls) ->
let (SynComponentInfo(longId = ids; range = r)) = ci
let name = String.concat "." [ for i in ids -> i.idText ]
+
+ let moduleType =
+ if Set.contains name typeNames then
+ ModuleWithSuffixType
+ else
+ ModuleType
+
ident <- ident + 1
let entry =
@@ -313,6 +361,7 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = NUnitType }
parent.Childs.Add entry
@@ -327,8 +376,9 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
let visitModulesAndNamespaces parent modulesOrNss =
Seq.iter
- (fun (SynModuleOrNamespace(longId = ids; decls = decls; range = r)) ->
+ (fun (SynModuleOrNamespace(longId = ids; decls = decls; range = r; kind = kind)) ->
let name = String.concat "." [ for i in ids -> i.idText ]
+ let moduleType = if kind.IsModule then ModuleType else NoneModuleType
ident <- ident + 1
let entry =
@@ -337,6 +387,7 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = NUnitType }
parent.Childs.Add entry
@@ -352,6 +403,7 @@ let getNUnitTest (ast: ParsedInput) : TestAdapterEntry list =
Childs = ResizeArray()
Id = -1
List = false
+ ModuleType = NoneModuleType
Type = "" }
match ast with
@@ -395,6 +447,13 @@ let getXUnitTest ast : TestAdapterEntry list =
let (SynTypeDefn(typeInfo = ci; typeRepr = om; members = members)) = t
let (SynComponentInfo(longId = ids; range = r)) = ci
let name = String.concat "." [ for i in ids -> i.idText ]
+
+ let moduleType =
+ if parent.ModuleType = ModuleType || parent.ModuleType = ModuleWithSuffixType then
+ TypeInModule
+ else
+ NoneModuleType
+
ident <- ident + 1
let entry =
@@ -403,6 +462,7 @@ let getXUnitTest ast : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = XUnitType }
parent.Childs.Add entry
@@ -431,13 +491,27 @@ let getXUnitTest ast : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = false
- Type = XUnitType
-
- }
+ ModuleType = NoneModuleType
+ Type = XUnitType }
parent.Childs.Add entry
let rec visitDeclarations (parent: TestAdapterEntry) decls =
+ let typeNames =
+ decls
+ |> List.fold
+ (fun types declaration ->
+ match declaration with
+ | SynModuleDecl.Types(typeDefns, _) ->
+ typeDefns
+ |> List.map (fun (SynTypeDefn(typeInfo = ci)) ->
+ let (SynComponentInfo(longId = ids)) = ci
+ String.concat "." [ for i in ids -> i.idText ])
+ |> List.append types
+ | _ -> types)
+ ([])
+ |> Set.ofList
+
for declaration in decls do
match declaration with
| SynModuleDecl.Let(_, bindings, _) ->
@@ -446,6 +520,13 @@ let getXUnitTest ast : TestAdapterEntry list =
| SynModuleDecl.NestedModule(moduleInfo = ci; decls = decls) ->
let (SynComponentInfo(longId = ids; range = r)) = ci
let name = String.concat "." [ for i in ids -> i.idText ]
+
+ let moduleType =
+ if Set.contains name typeNames then
+ ModuleWithSuffixType
+ else
+ ModuleType
+
ident <- ident + 1
let entry =
@@ -454,6 +535,7 @@ let getXUnitTest ast : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = XUnitType }
parent.Childs.Add entry
@@ -468,8 +550,9 @@ let getXUnitTest ast : TestAdapterEntry list =
let visitModulesAndNamespaces parent modulesOrNss =
Seq.iter
- (fun (SynModuleOrNamespace(longId = ids; decls = decls; range = r)) ->
+ (fun (SynModuleOrNamespace(longId = ids; decls = decls; range = r; kind = kind)) ->
let name = String.concat "." [ for i in ids -> i.idText ]
+ let moduleType = if kind.IsModule then ModuleType else NoneModuleType
ident <- ident + 1
let entry =
@@ -478,6 +561,7 @@ let getXUnitTest ast : TestAdapterEntry list =
Childs = ResizeArray()
Id = ident
List = true
+ ModuleType = moduleType
Type = XUnitType }
parent.Childs.Add entry
@@ -493,6 +577,7 @@ let getXUnitTest ast : TestAdapterEntry list =
Childs = ResizeArray()
Id = -1
List = false
+ ModuleType = NoneModuleType
Type = "" }
match ast with
diff --git a/src/FsAutoComplete/CodeFixes/ConvertPositionalDUToNamed.fs b/src/FsAutoComplete/CodeFixes/ConvertPositionalDUToNamed.fs
index de7c949f0..9261194f8 100644
--- a/src/FsAutoComplete/CodeFixes/ConvertPositionalDUToNamed.fs
+++ b/src/FsAutoComplete/CodeFixes/ConvertPositionalDUToNamed.fs
@@ -24,6 +24,7 @@ open FsAutoComplete
open FsAutoComplete.LspHelpers
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Symbols
+open FSharp.Compiler.Text.Range
open FsAutoComplete.FCSPatches
open FSharp.Compiler.Syntax
open FSharp.Compiler.Syntax.SyntaxTraversal
@@ -65,14 +66,18 @@ type ParseAndCheckResults with
| None ->
clauses
|> List.tryPick (function
- | SynMatchClause(pat = UnionNameAndPatterns(ident, duFieldPatterns, parenRange)) ->
+ | SynMatchClause(pat = UnionNameAndPatterns(ident, duFieldPatterns, parenRange)) when
+ rangeContainsPos parenRange pos
+ ->
Some(ident, duFieldPatterns, parenRange)
| _ -> None)
| _ -> defaultTraverse expr
member x.VisitMatchClause(path, defaultTraverse, matchClause) =
match matchClause with
- | SynMatchClause(pat = UnionNameAndPatterns(ident, duFieldPatterns, parenRange)) ->
+ | SynMatchClause(pat = UnionNameAndPatterns(ident, duFieldPatterns, parenRange)) when
+ rangeContainsPos parenRange pos
+ ->
Some(ident, duFieldPatterns, parenRange)
| _ -> defaultTraverse matchClause }
diff --git a/src/FsAutoComplete/CodeFixes/ConvertTripleSlashCommentToXmlTaggedDoc.fs b/src/FsAutoComplete/CodeFixes/ConvertTripleSlashCommentToXmlTaggedDoc.fs
new file mode 100644
index 000000000..ba46ceb52
--- /dev/null
+++ b/src/FsAutoComplete/CodeFixes/ConvertTripleSlashCommentToXmlTaggedDoc.fs
@@ -0,0 +1,198 @@
+module FsAutoComplete.CodeFix.ConvertTripleSlashCommentToXmlTaggedDoc
+
+open FsToolkit.ErrorHandling
+open FsAutoComplete.CodeFix.Types
+open Ionide.LanguageServerProtocol.Types
+open FsAutoComplete
+open FsAutoComplete.LspHelpers
+open FSharp.Compiler.Syntax
+open FSharp.Compiler.Text.Range
+open FSharp.Compiler.Xml
+open System
+
+let title = "Convert '///' comment to XML-tagged doc comment"
+
+let private containsPosAndNotEmptyAndNotElaborated (pos: FSharp.Compiler.Text.Position) (xmlDoc: PreXmlDoc) =
+ let containsPosAndNoSummaryPresent (xd: PreXmlDoc) =
+ let d = xd.ToXmlDoc(false, None)
+
+ if rangeContainsPos d.Range pos then
+ let summaryPresent =
+ d.UnprocessedLines |> Array.exists (fun s -> s.Contains(""))
+
+ not summaryPresent
+ else
+ false
+
+ not xmlDoc.IsEmpty && containsPosAndNoSummaryPresent xmlDoc
+
+let private isLowerAstElemWithPreXmlDoc input pos =
+ SyntaxTraversal.Traverse(
+ pos,
+ input,
+ { new SyntaxVisitorBase<_>() with
+ member _.VisitBinding(_, defaultTraverse, synBinding) =
+ match synBinding with
+ | SynBinding(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> defaultTraverse synBinding
+
+ member _.VisitComponentInfo(_, synComponentInfo) =
+ match synComponentInfo with
+ | SynComponentInfo(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> None
+
+ member _.VisitRecordDefn(_, fields, _) =
+ let isInLine c =
+ match c with
+ | SynField(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> None
+
+ fields |> List.tryPick isInLine
+
+ member _.VisitUnionDefn(_, cases, _) =
+ let isInLine c =
+ match c with
+ | SynUnionCase(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> None
+
+ cases |> List.tryPick isInLine
+
+ member _.VisitEnumDefn(_, cases, _) =
+ let isInLine b =
+ match b with
+ | SynEnumCase(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> None
+
+ cases |> List.tryPick isInLine
+
+ member _.VisitLetOrUse(_, _, defaultTraverse, bindings, _) =
+ let isInLine b =
+ match b with
+ | SynBinding(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | _ -> defaultTraverse b
+
+ bindings |> List.tryPick isInLine
+
+ member _.VisitExpr(_, _, defaultTraverse, expr) = defaultTraverse expr } // needed for nested let bindings
+ )
+
+let private isModuleOrNamespaceOrAutoPropertyWithPreXmlDoc input pos =
+ SyntaxTraversal.Traverse(
+ pos,
+ input,
+ { new SyntaxVisitorBase<_>() with
+
+ member _.VisitModuleOrNamespace(_, synModuleOrNamespace) =
+ match synModuleOrNamespace with
+ | SynModuleOrNamespace(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc -> Some xmlDoc
+ | SynModuleOrNamespace(decls = decls) ->
+
+ let rec findNested decls =
+ decls
+ |> List.tryPick (fun d ->
+ match d with
+ | SynModuleDecl.NestedModule(moduleInfo = moduleInfo; decls = decls) ->
+ match moduleInfo with
+ | SynComponentInfo(xmlDoc = xmlDoc) when containsPosAndNotEmptyAndNotElaborated pos xmlDoc ->
+ Some xmlDoc
+ | _ -> findNested decls
+ | SynModuleDecl.Types(typeDefns = typeDefns) ->
+ typeDefns
+ |> List.tryPick (fun td ->
+ match td with
+ | SynTypeDefn(typeRepr = SynTypeDefnRepr.ObjectModel(_, members, _)) ->
+ members
+ |> List.tryPick (fun m ->
+ match m with
+ | SynMemberDefn.AutoProperty(xmlDoc = xmlDoc) when
+ containsPosAndNotEmptyAndNotElaborated pos xmlDoc
+ ->
+ Some xmlDoc
+ | _ -> None)
+ | _ -> None)
+ | _ -> None)
+
+ findNested decls }
+ )
+
+let private isAstElemWithPreXmlDoc input pos =
+ match isLowerAstElemWithPreXmlDoc input pos with
+ | Some xml -> Some xml
+ | _ -> isModuleOrNamespaceOrAutoPropertyWithPreXmlDoc input pos
+
+let private collectCommentContents
+ (startPos: FSharp.Compiler.Text.Position)
+ (endPos: FSharp.Compiler.Text.Position)
+ (sourceText: NamedText)
+ =
+ let rec loop (p: FSharp.Compiler.Text.Position) acc =
+ if p.Line > endPos.Line then
+ acc
+ else
+ let currentLine = sourceText.GetLine p
+
+ match currentLine with
+ | None -> acc
+ | Some line ->
+ let idx = line.IndexOf("///")
+
+ if idx >= 0 then
+ let existingComment = line.TrimStart().Substring(3).TrimStart()
+ let acc = acc @ [ existingComment ]
+
+ match sourceText.NextLine p with
+ | None -> acc
+ | Some nextLinePos -> loop nextLinePos acc
+ else
+ acc
+
+ loop startPos List.empty
+
+let private wrapInSummary indent comments =
+ let indentation = String.replicate indent " "
+
+ match comments with
+ | [] -> $"{indentation}/// "
+ | [ c ] -> $"{indentation}/// %s{c}"
+ | cs ->
+ seq {
+ yield $"{indentation}/// {Environment.NewLine}"
+ yield! cs |> List.map (fun s -> $"%s{indentation}/// %s{s}{Environment.NewLine}")
+ yield $"%s{indentation}/// "
+ }
+ |> String.concat ""
+
+let fix (getParseResultsForFile: GetParseResultsForFile) (getRangeText: GetRangeText) : CodeFix =
+ fun codeActionParams ->
+ asyncResult {
+ let filePath = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath
+ let fcsPos = protocolPosToPos codeActionParams.Range.Start
+ let! (parseAndCheck, lineStr, sourceText) = getParseResultsForFile filePath fcsPos
+ let showFix = isAstElemWithPreXmlDoc parseAndCheck.GetAST fcsPos
+
+ match showFix with
+ | Some xmlDoc ->
+ let d = xmlDoc.ToXmlDoc(false, None)
+
+ let origCommentContents =
+ collectCommentContents d.Range.Start d.Range.End sourceText
+
+ let indent = lineStr.IndexOf("///")
+ let summaryXmlDoc = wrapInSummary indent origCommentContents
+
+ let range =
+ { Start = fcsPosToLsp (d.Range.Start.WithColumn 0)
+ End = fcsPosToLsp (d.Range.End) }
+
+ let e =
+ { Range = range
+ NewText = summaryXmlDoc }
+
+ return
+ [ { Edits = [| e |]
+ File = codeActionParams.TextDocument
+ Title = title
+ SourceDiagnostic = None
+ Kind = FixKind.Refactor } ]
+ | None -> return []
+ }
diff --git a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
index 5258578c0..252966fbe 100644
--- a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
+++ b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
@@ -582,6 +582,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
List = r.List
Name = r.Name
Type = r.Type
+ ModuleType = r.ModuleType
Range = fcsRangeToLsp r.Range
Childs = ResizeArray(r.Childs |> Seq.map map) }
@@ -1534,6 +1535,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
AddMissingInstanceMember.fix
AddExplicitTypeAnnotation.fix tryGetParseResultsForFile
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText
+ ConvertTripleSlashCommentToXmlTaggedDoc.fix tryGetParseResultsForFile getRangeText
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText
RenameParamToMatchSignature.fix tryGetParseResultsForFile |])
@@ -2434,7 +2436,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
| Some insertText ->
helpText insertText
|> Result.ofCoreResponse
- |> Result.fold (mapHelpText ci) (fun _ -> ci)
+ |> Result.fold
+ (function
+ | None -> ci
+ | Some text -> mapHelpText ci text)
+ (fun _ -> ci)
|> success
with e ->
@@ -2863,17 +2869,19 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
Commands.symbolImplementationProject getProjectOptions getUsesOfSymbol getAllProjects tyRes pos lineStr
|> AsyncResult.ofCoreResponse
+ match res with
+ | None -> return None
+ | Some res ->
+ let ranges: FSharp.Compiler.Text.Range[] =
+ match res with
+ | LocationResponse.Use(_, uses) -> uses |> Array.map (fun u -> u.Range)
- let ranges: FSharp.Compiler.Text.Range[] =
- match res with
- | LocationResponse.Use(_, uses) -> uses |> Array.map (fun u -> u.Range)
-
- let mappedRanges = ranges |> Array.map fcsRangeToLspLocation
+ let mappedRanges = ranges |> Array.map fcsRangeToLspLocation
- match mappedRanges with
- | [||] -> return None
- | [| single |] -> return Some(GotoResult.Single single)
- | multiple -> return Some(GotoResult.Multiple multiple)
+ match mappedRanges with
+ | [||] -> return None
+ | [| single |] -> return Some(GotoResult.Single single)
+ | multiple -> return Some(GotoResult.Multiple multiple)
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -3826,7 +3834,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
and! tyRes = forceGetTypeCheckResults filePath |> Result.ofStringErr
let! tip = Commands.typesig tyRes pos lineStr |> Result.ofCoreResponse
- return { Content = CommandResponse.typeSig FsAutoComplete.JsonSerializer.writeJson tip }
+ return
+ tip
+ |> Option.map (fun tip -> { Content = CommandResponse.typeSig FsAutoComplete.JsonSerializer.writeJson tip })
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -3861,7 +3871,8 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! (typ, parms, generics) = tyRes.TryGetSignatureData pos lineStr |> Result.ofStringErr
return
- { Content = CommandResponse.signatureData FsAutoComplete.JsonSerializer.writeJson (typ, parms, generics) }
+ Some
+ { Content = CommandResponse.signatureData FsAutoComplete.JsonSerializer.writeJson (typ, parms, generics) }
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -3893,24 +3904,27 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! lineStr = namedText.Lines |> tryGetLineStr pos |> Result.ofStringErr
and! tyRes = forceGetTypeCheckResults filePath |> Result.ofStringErr
- let! { InsertPosition = insertPos
- InsertText = text } =
+ match!
Commands.GenerateXmlDocumentation(tyRes, pos, lineStr)
|> AsyncResult.ofStringErr
+ with
+ | None -> return ()
+ | Some { InsertPosition = insertPos
+ InsertText = text } ->
+
+ let edit: ApplyWorkspaceEditParams =
+ { Label = Some "Generate Xml Documentation"
+ Edit =
+ { DocumentChanges =
+ Some
+ [| { TextDocument = p.TextDocument
+ Edits =
+ [| { Range = fcsPosToProtocolRange insertPos
+ NewText = text } |] } |]
+ Changes = None } }
- let edit: ApplyWorkspaceEditParams =
- { Label = Some "Generate Xml Documentation"
- Edit =
- { DocumentChanges =
- Some
- [| { TextDocument = p.TextDocument
- Edits =
- [| { Range = fcsPosToProtocolRange insertPos
- NewText = text } |] } |]
- Changes = None } }
-
- let! _ = lspClient.WorkspaceApplyEdit edit
- return ()
+ let! _ = lspClient.WorkspaceApplyEdit edit
+ return ()
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -3924,7 +3938,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.FSharpLineLense(p: ProjectParms) =
+ override __.FSharpLineLens(p: ProjectParms) =
asyncResult {
let tags = [ "ProjectParms", box p ]
use trace = fsacActivitySource.StartActivityForType(thisType, tags = tags)
@@ -3942,7 +3956,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
| Some decls ->
let decls = decls |> Array.map (fun d -> d, fn)
- return { Content = CommandResponse.declarations FsAutoComplete.JsonSerializer.writeJson decls }
+ return Some { Content = CommandResponse.declarations FsAutoComplete.JsonSerializer.writeJson decls }
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -3956,39 +3970,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return! LspResult.internalError (string e)
}
- override __.FSharpCompilerLocation(p: obj) =
- asyncResult {
- use trace = fsacActivitySource.StartActivityForType(thisType)
-
- try
- logger.info (
- Log.setMessage "FSharpCompilerLocation Request: {parms}"
- >> Log.addContextDestructured "parms" p
- )
-
- let checker = checker |> AVal.force
- let! (fsc, fsi, msbuild, sdk) = Commands.CompilerLocation checker |> Result.ofCoreResponse
-
- return
- { Content =
- CommandResponse.compilerLocation
- FsAutoComplete.JsonSerializer.writeJson
- fsc
- fsi
- msbuild
- (sdk |> Option.map (fun (di: DirectoryInfo) -> di.FullName)) }
- with e ->
- trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
-
- logger.error (
- Log.setMessage "FSharpCompilerLocation Request Errored {p}"
- >> Log.addContextDestructured "p" p
- >> Log.addExn e
- )
-
- return! LspResult.internalError (string e)
- }
-
override __.FSharpWorkspaceLoad(p: WorkspaceLoadParms) =
asyncResult {
let tags = [ "WorkspaceLoadParms", box p ]
@@ -4124,8 +4105,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
)
- let! funcs = Commands.DotnetNewList() |> AsyncResult.ofCoreResponse
- return { Content = CommandResponse.dotnetnewlist FsAutoComplete.JsonSerializer.writeJson funcs }
+ match! Commands.DotnetNewList() |> AsyncResult.ofCoreResponse with
+ | Some funcs ->
+ return Some { Content = CommandResponse.dotnetnewlist FsAutoComplete.JsonSerializer.writeJson funcs }
+ | None -> return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4152,8 +4135,9 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.DotnetNewRun p.Template p.Name p.Output []
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore // mapping unit option to unit
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4177,9 +4161,13 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
)
- do! Commands.DotnetAddProject p.Target p.Reference |> AsyncResult.ofCoreResponse
+ do!
+ Commands.DotnetAddProject p.Target p.Reference
+ |> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore // mapping unit option to unit
+
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4203,9 +4191,13 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
)
- do! Commands.DotnetRemoveProject p.Target p.Reference |> AsyncResult.ofCoreResponse
+ do!
+ Commands.DotnetRemoveProject p.Target p.Reference
+ |> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
+
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4229,9 +4221,13 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
)
- do! Commands.DotnetSlnAdd p.Target p.Reference |> AsyncResult.ofCoreResponse
+ do!
+ Commands.DotnetSlnAdd p.Target p.Reference
+ |> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
+
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4259,8 +4255,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! (namedText) = forceFindOpenFileOrRead filePath |> Result.ofStringErr
let! lineStr = namedText.Lines |> tryGetLineStr pos |> Result.ofStringErr
and! tyRes = forceGetTypeCheckResults filePath |> Result.ofStringErr
- let! t = Commands.Help tyRes pos lineStr |> Result.ofCoreResponse
- return { Content = CommandResponse.help FsAutoComplete.JsonSerializer.writeJson t }
+
+ match! Commands.Help tyRes pos lineStr |> Result.ofCoreResponse with
+ | Some t -> return Some { Content = CommandResponse.help FsAutoComplete.JsonSerializer.writeJson t }
+ | None -> return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4289,8 +4287,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let! lineStr = namedText.Lines |> tryGetLineStr pos |> Result.ofStringErr
and! tyRes = forceGetTypeCheckResults filePath |> Result.ofStringErr
lastFSharpDocumentationTypeCheck <- Some tyRes
- let! t = Commands.FormattedDocumentation tyRes pos lineStr |> Result.ofCoreResponse
- return { Content = CommandResponse.formattedDocumentation FsAutoComplete.JsonSerializer.writeJson t }
+
+ match! Commands.FormattedDocumentation tyRes pos lineStr |> Result.ofCoreResponse with
+ | Some t ->
+ return Some { Content = CommandResponse.formattedDocumentation FsAutoComplete.JsonSerializer.writeJson t }
+ | None -> return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4319,24 +4320,28 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> Result.ofOption (fun () -> $"No typecheck results from FSharpDocumentation")
|> Result.ofStringErr
- let! (xml, assembly, doc, signature, footer, cn) =
+ match!
Commands.FormattedDocumentationForSymbol tyRes p.XmlSig p.Assembly
|> Result.ofCoreResponse
+ with
+ | None -> return None
+ | Some(xml, assembly, doc, signature, footer, cn) ->
- let xmldoc =
- match doc with
- | FSharpXmlDoc.None -> [||]
- | FSharpXmlDoc.FromXmlFile _ -> [||]
- | FSharpXmlDoc.FromXmlText d -> d.GetElaboratedXmlLines()
+ let xmldoc =
+ match doc with
+ | FSharpXmlDoc.None -> [||]
+ | FSharpXmlDoc.FromXmlFile _ -> [||]
+ | FSharpXmlDoc.FromXmlText d -> d.GetElaboratedXmlLines()
- return
- { Content =
- CommandResponse.formattedDocumentationForSymbol
- FsAutoComplete.JsonSerializer.writeJson
- xml
- assembly
- xmldoc
- (signature, footer, cn) }
+ return
+ { Content =
+ CommandResponse.formattedDocumentationForSymbol
+ FsAutoComplete.JsonSerializer.writeJson
+ xml
+ assembly
+ xmldoc
+ (signature, footer, cn) }
+ |> Some
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4386,9 +4391,11 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
let filePath = p.TextDocument.GetFilePath() |> Utils.normalizePath
let! tyRes = forceGetTypeCheckResults filePath |> Result.ofStringErr
- let! res = Commands.pipelineHints forceFindSourceText tyRes |> Result.ofCoreResponse
- return { Content = CommandResponse.pipelineHint FsAutoComplete.JsonSerializer.writeJson res }
+ match! Commands.pipelineHints forceFindSourceText tyRes |> Result.ofCoreResponse with
+ | None -> return None
+ | Some res ->
+ return Some { Content = CommandResponse.pipelineHint FsAutoComplete.JsonSerializer.writeJson res }
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4415,9 +4422,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.FsProjMoveFileUp p.FsProj p.FileVirtualPath
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4445,9 +4453,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.FsProjMoveFileDown p.FsProj p.FileVirtualPath
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4475,9 +4484,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.addFileAbove p.FsProj p.FileVirtualPath p.NewFile
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4504,9 +4514,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.addFileBelow p.FsProj p.FileVirtualPath p.NewFile
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4531,9 +4542,13 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
>> Log.addContextDestructured "parms" p
)
- do! Commands.addFile p.FsProj p.FileVirtualPath |> AsyncResult.ofCoreResponse
+ do!
+ Commands.addFile p.FsProj p.FileVirtualPath
+ |> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
+
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4558,12 +4573,17 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
)
let fullPath = Path.Combine(Path.GetDirectoryName p.FsProj, p.FileVirtualPath)
- do! Commands.removeFile p.FsProj p.FileVirtualPath |> AsyncResult.ofCoreResponse
+
+ do!
+ Commands.removeFile p.FsProj p.FileVirtualPath
+ |> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
+
forceLoadProjects () |> ignore
let fileUri = Path.FilePathToUri fullPath
diagnosticCollections.ClearFor fileUri
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4590,9 +4610,10 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
do!
Commands.addExistingFile p.FsProj p.FileVirtualPath
|> AsyncResult.ofCoreResponse
+ |> AsyncResult.map ignore
forceLoadProjects () |> ignore
- return { Content = "" }
+ return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
@@ -4666,8 +4687,7 @@ module AdaptiveFSharpLspServer =
|> Map.add "fsharp/signature" (serverRequestHandling (fun s p -> s.FSharpSignature(p)))
|> Map.add "fsharp/signatureData" (serverRequestHandling (fun s p -> s.FSharpSignatureData(p)))
|> Map.add "fsharp/documentationGenerator" (serverRequestHandling (fun s p -> s.FSharpDocumentationGenerator(p)))
- |> Map.add "fsharp/lineLens" (serverRequestHandling (fun s p -> s.FSharpLineLense(p)))
- |> Map.add "fsharp/compilerLocation" (serverRequestHandling (fun s p -> s.FSharpCompilerLocation(p)))
+ |> Map.add "fsharp/lineLens" (serverRequestHandling (fun s p -> s.FSharpLineLens(p)))
|> Map.add "fsharp/workspaceLoad" (serverRequestHandling (fun s p -> s.FSharpWorkspaceLoad(p)))
|> Map.add "fsharp/workspacePeek" (serverRequestHandling (fun s p -> s.FSharpWorkspacePeek(p)))
|> Map.add "fsharp/project" (serverRequestHandling (fun s p -> s.FSharpProject(p)))
diff --git a/src/FsAutoComplete/LspServers/Common.fs b/src/FsAutoComplete/LspServers/Common.fs
index 8cf5ba530..22e6d3205 100644
--- a/src/FsAutoComplete/LspServers/Common.fs
+++ b/src/FsAutoComplete/LspServers/Common.fs
@@ -30,18 +30,15 @@ open FSharp.Compiler.Symbols
open Fantomas.Client.Contracts
open Fantomas.Client.LSPFantomasService
-
-
-
module Result =
let ofStringErr r =
r |> Result.mapError JsonRpc.Error.InternalErrorMessage
let ofCoreResponse (r: CoreResponse<'a>) =
match r with
- | CoreResponse.Res a -> Ok a
- | CoreResponse.ErrorRes msg
- | CoreResponse.InfoRes msg -> Error(JsonRpc.Error.InternalErrorMessage msg)
+ | CoreResponse.Res a -> Ok(Some a)
+ | CoreResponse.ErrorRes msg -> Error(JsonRpc.Error.InternalErrorMessage msg)
+ | CoreResponse.InfoRes _ -> Ok None
module AsyncResult =
let ofCoreResponse (ar: Async>) = ar |> Async.map Result.ofCoreResponse
diff --git a/src/FsAutoComplete/LspServers/FSharpLspClient.fs b/src/FsAutoComplete/LspServers/FSharpLspClient.fs
index 2bebff8bb..2ddbce748 100644
--- a/src/FsAutoComplete/LspServers/FSharpLspClient.fs
+++ b/src/FsAutoComplete/LspServers/FSharpLspClient.fs
@@ -219,7 +219,7 @@ type ProgressListener(lspClient: FSharpLspClient, traceNamespace: string array)
| None ->
// if we don't get an event in 250 ms just loop again so we can analyze inflightEvents
()
- | Some(action, activity: Activity, reply: AsyncReplyChannel) ->
+ | Some(action, activity: Activity) ->
match action with
| "start" ->
@@ -258,17 +258,14 @@ type ProgressListener(lspClient: FSharpLspClient, traceNamespace: string array)
| _ -> ()
- reply.Reply()
})
let shouldListenTo (act: ActivitySource) = act.Name = Tracing.fscServiceName
- let activityStarted (act: Activity) =
- mbp.PostAndReply(fun reply -> "start", act, reply)
+ let activityStarted (act: Activity) = mbp.Post("start", act)
- let activityStopped (act: Activity) =
- mbp.PostAndReply(fun reply -> "stop", act, reply)
+ let activityStopped (act: Activity) = mbp.Post("stop", act)
let listener =
new ActivityListener(
diff --git a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs
index 5b828fcb5..5e2d2ebb4 100644
--- a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs
+++ b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs
@@ -368,6 +368,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
List = r.List
Name = r.Name
Type = r.Type
+ ModuleType = r.ModuleType
Range = fcsRangeToLsp r.Range
Childs = ResizeArray(r.Childs |> Seq.map map) }
@@ -853,22 +854,6 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
| Error ex -> return LspResult.internalError ex
}
- member x.LineLensResolve(p) =
- logger.info (
- Log.setMessage "LineLensResolve Request: {parms}"
- >> Log.addContextDestructured "parms" p
- )
-
- p
- |> x.positionHandler (fun p pos tyRes lineStr lines ->
- (match Commands.SignatureData tyRes pos lineStr with
- | CoreResponse.InfoRes msg
- | CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(typ, parms, generics) ->
- { Content = CommandResponse.signatureData FsAutoComplete.JsonSerializer.writeJson (typ, parms, generics) }
- |> success)
- |> async.Return)
-
member private x.handleSemanticTokens
(getTokens: Async option>)
: AsyncLspResult =
@@ -878,16 +863,19 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
| Some rangesAndHighlights ->
let! rangesAndHighlights = rangesAndHighlights |> Result.ofCoreResponse
+ match rangesAndHighlights with
+ | None -> return! success None
+ | Some rangesAndHighlights ->
- let lspTypedRanges =
- rangesAndHighlights
- |> Array.map (fun item ->
- let ty, mods = ClassificationUtils.map item.Type
- struct (fcsRangeToLsp item.Range, ty, mods))
+ let lspTypedRanges =
+ rangesAndHighlights
+ |> Array.map (fun item ->
+ let ty, mods = ClassificationUtils.map item.Type
+ struct (fcsRangeToLsp item.Range, ty, mods))
- match encodeSemanticHighlightRanges lspTypedRanges with
- | None -> return! success None
- | Some encoded -> return! success (Some { Data = encoded; ResultId = None }) // TODO: provide a resultId when we support delta ranges
+ match encodeSemanticHighlightRanges lspTypedRanges with
+ | None -> return! success None
+ | Some encoded -> return! success (Some { Data = encoded; ResultId = None }) // TODO: provide a resultId when we support delta ranges
}
member __.ScriptFileProjectOptions = commands.ScriptFileProjectOptions
@@ -1197,6 +1185,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
AddMissingInstanceMember.fix
AddExplicitTypeAnnotation.fix tryGetParseResultsForFile
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText
+ ConvertTripleSlashCommentToXmlTaggedDoc.fix tryGetParseResultsForFile getRangeText
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText
RenameParamToMatchSignature.fix tryGetParseResultsForFile |]
@@ -1480,7 +1469,11 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let! res =
commands.Helptext ci.InsertText.Value
|> AsyncResult.ofCoreResponse
- |> AsyncResult.foldResult (mapHelpText ci) (fun _ -> ci)
+ |> AsyncResult.foldResult
+ (function
+ | None -> ci
+ | Some text -> mapHelpText ci text)
+ (fun _ -> ci)
return success res
}
@@ -1540,7 +1533,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> x.positionHandler (fun p pos tyRes lineStr lines ->
match commands.ToolTip tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> async.Return(success None)
| CoreResponse.ErrorRes msg -> LspResult.internalError msg |> async.Return
| CoreResponse.Res None -> async.Return(success None)
| CoreResponse.Res(Some(tip, signature, footer, typeDoc)) ->
@@ -1655,7 +1648,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res r -> findDeclToLspLocation r |> GotoResult.Single |> Some |> success
@@ -1675,7 +1668,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res r -> findDeclToLspLocation r |> GotoResult.Single |> Some |> success
@@ -1710,7 +1703,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> x.positionHandler (fun p pos tyRes lineStr lines ->
match commands.SymbolUse tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> async.Return(success None)
| CoreResponse.ErrorRes msg -> async.Return(LspResult.internalError msg)
| CoreResponse.Res(symbol, uses) ->
uses
@@ -1736,7 +1729,8 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let ranges: FSharp.Compiler.Text.Range[] =
match res with
- | LocationResponse.Use(_, uses) -> uses |> Array.map (fun u -> u.Range)
+ | Some(LocationResponse.Use(_, uses)) -> uses |> Array.map (fun u -> u.Range)
+ | None -> [||]
let mappedRanges = ranges |> Array.map fcsRangeToLspLocation
@@ -1759,7 +1753,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res decls ->
decls
@@ -1785,7 +1779,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res(decls) ->
decls
@@ -1919,21 +1913,25 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let fn = p.TextDocument.GetFilePath() |> Utils.normalizePath
- let! decls =
+ let! declsAndPaths =
commands.Declarations fn None (commands.TryGetFileVersion fn)
|> AsyncResult.ofCoreResponse
- |> AsyncResult.map (Array.map fst)
- let res =
- [| if config.LineLens.Enabled <> "replaceCodeLens" then
- if config.CodeLenses.Signature.Enabled then
- yield! decls |> Array.collect (getCodeLensInformation p.TextDocument.Uri "signature")
+ match declsAndPaths with
+ | None -> return None
+ | Some declsAndPaths ->
+ let decls = Array.map fst declsAndPaths
+
+ let res =
+ [| if config.LineLens.Enabled <> "replaceCodeLens" then
+ if config.CodeLenses.Signature.Enabled then
+ yield! decls |> Array.collect (getCodeLensInformation p.TextDocument.Uri "signature")
- // we have two options here because we're deprecating the EnableReferenceCodeLens one (namespacing, etc)
- if config.EnableReferenceCodeLens || config.CodeLenses.References.Enabled then
- yield! decls |> Array.collect (getCodeLensInformation p.TextDocument.Uri "reference") |]
+ // we have two options here because we're deprecating the EnableReferenceCodeLens one (namespacing, etc)
+ if config.EnableReferenceCodeLens || config.CodeLenses.References.Enabled then
+ yield! decls |> Array.collect (getCodeLensInformation p.TextDocument.Uri "reference") |]
- return Some res
+ return Some res
}
override __.CodeLensResolve(p) =
@@ -2167,11 +2165,12 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
|> x.positionHandler (fun p pos tyRes lineStr lines ->
async {
match commands.Typesig tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> return success None
| CoreResponse.ErrorRes msg -> return LspResult.internalError msg
| CoreResponse.Res tip ->
return
{ Content = CommandResponse.typeSig FsAutoComplete.JsonSerializer.writeJson tip }
+ |> Some
|> success
})
}
@@ -2220,10 +2219,11 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> handler (fun p pos tyRes lineStr ->
(match Commands.SignatureData tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res(typ, parms, generics) ->
{ Content = CommandResponse.signatureData FsAutoComplete.JsonSerializer.writeJson (typ, parms, generics) }
+ |> Some
|> success)
|> async.Return)
@@ -2236,27 +2236,30 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> x.positionHandler (fun p pos tyRes lineStr lines ->
asyncResult {
- let! { InsertPosition = insertPos
- InsertText = text } =
+ match!
Commands.GenerateXmlDocumentation(tyRes, pos, lineStr)
|> AsyncResult.ofStringErr
-
- let edit: ApplyWorkspaceEditParams =
- { Label = Some "Generate Xml Documentation"
- Edit =
- { DocumentChanges =
- Some
- [| { TextDocument = p.TextDocument
- Edits =
- [| { Range = fcsPosToProtocolRange insertPos
- NewText = text } |] } |]
- Changes = None } }
-
- let! response = lspClient.WorkspaceApplyEdit edit
- return ()
+ with
+ | None -> return ()
+ | Some { InsertPosition = insertPos
+ InsertText = text } ->
+
+ let edit: ApplyWorkspaceEditParams =
+ { Label = Some "Generate Xml Documentation"
+ Edit =
+ { DocumentChanges =
+ Some
+ [| { TextDocument = p.TextDocument
+ Edits =
+ [| { Range = fcsPosToProtocolRange insertPos
+ NewText = text } |] } |]
+ Changes = None } }
+
+ let! response = lspClient.WorkspaceApplyEdit edit
+ return ()
})
- override __.FSharpLineLense(p) =
+ override __.FSharpLineLens(p) =
async {
logger.info (
Log.setMessage "FSharpLineLense Request: {parms}"
@@ -2269,36 +2272,11 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res(decls) ->
{ Content = CommandResponse.declarations FsAutoComplete.JsonSerializer.writeJson decls }
- |> success
-
- return res
- }
-
- override __.FSharpCompilerLocation(p) =
- async {
- logger.info (
- Log.setMessage "FSharpCompilerLocation Request: {parms}"
- >> Log.addContextDestructured "parms" p
- )
-
- let res = commands.CompilerLocation()
-
- let res =
- match res with
- | CoreResponse.InfoRes msg
- | CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(fsc, fsi, msbuild, sdk) ->
- { Content =
- CommandResponse.compilerLocation
- FsAutoComplete.JsonSerializer.writeJson
- fsc
- fsi
- msbuild
- (sdk |> Option.map (fun (di: DirectoryInfo) -> di.FullName)) }
+ |> Some
|> success
return res
@@ -2396,15 +2374,13 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let! res = Commands.DotnetNewList()
- let res =
- match res with
- | CoreResponse.InfoRes msg
- | CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(funcs) ->
- { Content = CommandResponse.dotnetnewlist FsAutoComplete.JsonSerializer.writeJson funcs }
- |> success
+ match res with
+ | CoreResponse.InfoRes msg -> return success None
+ | CoreResponse.ErrorRes msg -> return LspResult.internalError msg
+ | CoreResponse.Res(funcs) ->
+ return
+ success (Some { Content = CommandResponse.dotnetnewlist FsAutoComplete.JsonSerializer.writeJson funcs })
- return res
}
override __.FSharpDotnetNewRun(p: DotnetNewRunRequest) =
@@ -2418,9 +2394,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2436,9 +2412,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2454,9 +2430,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2472,9 +2448,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2490,9 +2466,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2508,9 +2484,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2526,9 +2502,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2544,9 +2520,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2562,9 +2538,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2580,9 +2556,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2603,9 +2579,9 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
let res =
match res with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
- | CoreResponse.Res(_) -> { Content = "" } |> success
+ | CoreResponse.Res(_) -> success None
return res
}
@@ -2619,10 +2595,11 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> x.positionHandler (fun p pos tyRes lineStr lines ->
(match Commands.Help tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res(t) ->
{ Content = CommandResponse.help FsAutoComplete.JsonSerializer.writeJson t }
+ |> Some
|> success)
|> async.Return)
@@ -2636,7 +2613,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p
|> x.positionHandler (fun p pos tyRes lineStr lines ->
(match Commands.FormattedDocumentation tyRes pos lineStr with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> success None
| CoreResponse.ErrorRes msg -> LspResult.internalError msg
| CoreResponse.Res(tip, xml, signature, footer, cm) ->
let notification: PlainNotification =
@@ -2645,37 +2622,40 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
FsAutoComplete.JsonSerializer.writeJson
(tip, xml, signature, footer, cm) }
- success notification)
+ success (Some notification))
|> async.Return)
override x.FSharpDocumentationSymbol(p: DocumentationForSymbolReuqest) =
- logger.info (
- Log.setMessage "FSharpDocumentationSymbol Request: {parms}"
- >> Log.addContextDestructured "parms" p
- )
+ async {
+ logger.info (
+ Log.setMessage "FSharpDocumentationSymbol Request: {parms}"
+ >> Log.addContextDestructured "parms" p
+ )
- match commands.LastCheckResult with
- | None -> AsyncLspResult.internalError "error"
- | Some tyRes ->
- match Commands.FormattedDocumentationForSymbol tyRes p.XmlSig p.Assembly with
- | (CoreResponse.InfoRes msg)
- | (CoreResponse.ErrorRes msg) -> AsyncLspResult.internalError msg
- | (CoreResponse.Res(xml, assembly, doc, signature, footer, cn)) ->
- let xmldoc =
- match doc with
- | FSharpXmlDoc.None -> [||]
- | FSharpXmlDoc.FromXmlFile _ -> [||]
- | FSharpXmlDoc.FromXmlText d -> d.GetElaboratedXmlLines()
-
- { Content =
- CommandResponse.formattedDocumentationForSymbol
- FsAutoComplete.JsonSerializer.writeJson
- xml
- assembly
- xmldoc
- (signature, footer, cn) }
- |> success
- |> async.Return
+ match commands.LastCheckResult with
+ | None -> return success None
+ | Some tyRes ->
+ match Commands.FormattedDocumentationForSymbol tyRes p.XmlSig p.Assembly with
+ | (CoreResponse.InfoRes msg) -> return success None
+ | (CoreResponse.ErrorRes msg) -> return! AsyncLspResult.internalError msg
+ | (CoreResponse.Res(xml, assembly, doc, signature, footer, cn)) ->
+ let xmldoc =
+ match doc with
+ | FSharpXmlDoc.None -> [||]
+ | FSharpXmlDoc.FromXmlFile _ -> [||]
+ | FSharpXmlDoc.FromXmlText d -> d.GetElaboratedXmlLines()
+
+ return
+ { Content =
+ CommandResponse.formattedDocumentationForSymbol
+ FsAutoComplete.JsonSerializer.writeJson
+ xml
+ assembly
+ xmldoc
+ (signature, footer, cn) }
+ |> Some
+ |> success
+ }
override __.LoadAnalyzers(path) =
async {
@@ -2831,10 +2811,11 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient) =
p.TextDocument
|> x.fileHandler (fun fn tyRes lines ->
match commands.PipelineHints tyRes with
- | CoreResponse.InfoRes msg
+ | CoreResponse.InfoRes msg -> async.Return(success None)
| CoreResponse.ErrorRes msg -> AsyncLspResult.internalError msg
| CoreResponse.Res(res) ->
{ Content = CommandResponse.pipelineHint FsAutoComplete.JsonSerializer.writeJson res }
+ |> Some
|> success
|> async.Return)
@@ -2899,8 +2880,7 @@ module FSharpLspServer =
|> Map.add "fsharp/signature" (serverRequestHandling (fun s p -> s.FSharpSignature(p)))
|> Map.add "fsharp/signatureData" (serverRequestHandling (fun s p -> s.FSharpSignatureData(p)))
|> Map.add "fsharp/documentationGenerator" (serverRequestHandling (fun s p -> s.FSharpDocumentationGenerator(p)))
- |> Map.add "fsharp/lineLens" (serverRequestHandling (fun s p -> s.FSharpLineLense(p)))
- |> Map.add "fsharp/compilerLocation" (serverRequestHandling (fun s p -> s.FSharpCompilerLocation(p)))
+ |> Map.add "fsharp/lineLens" (serverRequestHandling (fun s p -> s.FSharpLineLens(p)))
|> Map.add "fsharp/workspaceLoad" (serverRequestHandling (fun s p -> s.FSharpWorkspaceLoad(p)))
|> Map.add "fsharp/workspacePeek" (serverRequestHandling (fun s p -> s.FSharpWorkspacePeek(p)))
|> Map.add "fsharp/project" (serverRequestHandling (fun s p -> s.FSharpProject(p)))
diff --git a/src/FsAutoComplete/LspServers/IFSharpLspServer.fs b/src/FsAutoComplete/LspServers/IFSharpLspServer.fs
index 154b6560b..0870ef3a1 100644
--- a/src/FsAutoComplete/LspServers/IFSharpLspServer.fs
+++ b/src/FsAutoComplete/LspServers/IFSharpLspServer.fs
@@ -19,30 +19,29 @@ type OptionallyVersionedTextDocumentPositionParams =
[]
type IFSharpLspServer =
inherit ILspServer
- abstract FSharpSignature: TextDocumentPositionParams -> Async>
- abstract FSharpSignatureData: TextDocumentPositionParams -> Async>
+ abstract FSharpSignature: TextDocumentPositionParams -> Async>
+ abstract FSharpSignatureData: TextDocumentPositionParams -> Async>
abstract FSharpDocumentationGenerator: OptionallyVersionedTextDocumentPositionParams -> AsyncLspResult
- abstract FSharpLineLense: ProjectParms -> Async>
- abstract FSharpCompilerLocation: obj -> Async>
+ abstract FSharpLineLens: ProjectParms -> Async>
abstract FSharpWorkspaceLoad: WorkspaceLoadParms -> Async>
abstract FSharpWorkspacePeek: WorkspacePeekRequest -> Async>
abstract FSharpProject: ProjectParms -> Async>
abstract FSharpFsdn: FsdnRequest -> Async>
- abstract FSharpDotnetNewList: DotnetNewListRequest -> Async>
- abstract FSharpDotnetNewRun: DotnetNewRunRequest -> Async>
- abstract FSharpDotnetAddProject: DotnetProjectRequest -> Async>
- abstract FSharpDotnetRemoveProject: DotnetProjectRequest -> Async>
- abstract FSharpDotnetSlnAdd: DotnetProjectRequest -> Async>
- abstract FSharpHelp: TextDocumentPositionParams -> Async>
- abstract FSharpDocumentation: TextDocumentPositionParams -> Async>
- abstract FSharpDocumentationSymbol: DocumentationForSymbolReuqest -> Async>
+ abstract FSharpDotnetNewList: DotnetNewListRequest -> Async>
+ abstract FSharpDotnetNewRun: DotnetNewRunRequest -> Async>
+ abstract FSharpDotnetAddProject: DotnetProjectRequest -> Async>
+ abstract FSharpDotnetRemoveProject: DotnetProjectRequest -> Async>
+ abstract FSharpDotnetSlnAdd: DotnetProjectRequest -> Async>
+ abstract FSharpHelp: TextDocumentPositionParams -> Async>
+ abstract FSharpDocumentation: TextDocumentPositionParams -> Async>
+ abstract FSharpDocumentationSymbol: DocumentationForSymbolReuqest -> Async>
abstract FSharpLiterateRequest: FSharpLiterateRequest -> Async>
abstract LoadAnalyzers: obj -> Async>
- abstract FSharpPipelineHints: FSharpPipelineHintRequest -> Async>
- abstract FsProjMoveFileUp: DotnetFileRequest -> Async>
- abstract FsProjMoveFileDown: DotnetFileRequest -> Async>
- abstract FsProjAddFileAbove: DotnetFile2Request -> Async>
- abstract FsProjAddFileBelow: DotnetFile2Request -> Async>
- abstract FsProjAddFile: DotnetFileRequest -> Async>
- abstract FsProjRemoveFile: DotnetFileRequest -> Async>
- abstract FsProjAddExistingFile: DotnetFileRequest -> Async>
+ abstract FSharpPipelineHints: FSharpPipelineHintRequest -> Async>
+ abstract FsProjMoveFileUp: DotnetFileRequest -> Async>
+ abstract FsProjMoveFileDown: DotnetFileRequest -> Async>
+ abstract FsProjAddFileAbove: DotnetFile2Request -> Async>
+ abstract FsProjAddFileBelow: DotnetFile2Request -> Async>
+ abstract FsProjAddFile: DotnetFileRequest -> Async>
+ abstract FsProjRemoveFile: DotnetFileRequest -> Async>
+ abstract FsProjAddExistingFile: DotnetFileRequest -> Async>
diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs
index fb50240d7..dc63bdb79 100644
--- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs
@@ -573,6 +573,7 @@ let private convertPositionalDUToNamedTests state =
type A = A of a: int * b: bool
match A(1, true) with
+ | A(_, 23) -> ()
| A(a$0, b) -> ()
"""
Diagnostics.acceptAll
@@ -581,6 +582,7 @@ let private convertPositionalDUToNamedTests state =
type A = A of a: int * b: bool
match A(1, true) with
+ | A(_, 23) -> ()
| A(a = a; b = b;) -> ()
"""
testCaseAsync "in parenthesized match" <|
@@ -589,6 +591,7 @@ let private convertPositionalDUToNamedTests state =
type A = A of a: int * b: bool
match A(1, true) with
+ | (A(_, 23)) -> ()
| (A(a$0, b)) -> ()
"""
Diagnostics.acceptAll
@@ -597,6 +600,7 @@ let private convertPositionalDUToNamedTests state =
type A = A of a: int * b: bool
match A(1, true) with
+ | (A(_, 23)) -> ()
| (A(a = a; b = b;)) -> ()
"""
testCaseAsync "when there is one new field on the DU" <|
@@ -627,6 +631,325 @@ let private convertPositionalDUToNamedTests state =
"""
])
+let private convertTripleSlashCommentToXmlTaggedDocTests state =
+ serverTestList (nameof ConvertTripleSlashCommentToXmlTaggedDoc) state defaultConfigDto None (fun server ->
+ [ let selectCodeFix = CodeFix.withTitle ConvertTripleSlashCommentToXmlTaggedDoc.title
+
+ testCaseAsync "single line comment over top level function"
+ <| CodeFix.check
+ server
+ """
+ /// $0line 1
+ let f () = ()
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ /// line 1
+ let f () = ()
+ """
+
+ testCaseAsync "multiline comments over top level function"
+ <| CodeFix.check
+ server
+ """
+ /// $0line 1
+ /// line 2
+ /// line 3
+ /// line 4
+ let f a b c = a + b
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// line 1
+ /// line 2
+ /// line 3
+ /// line 4
+ ///
+ let f a b c = a + b
+ """
+
+ testCaseAsync "multiline comments over nested function"
+ <| CodeFix.check
+ server
+ """
+ /// line 1
+ /// line 2
+ /// line 3
+ let g () =
+ /// line 1
+ /// line 2
+ /// line $03
+ /// line 4
+ let f x = x * x
+ ()
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ /// line 1
+ /// line 2
+ /// line 3
+ let g () =
+ ///
+ /// line 1
+ /// line 2
+ /// line 3
+ /// line 4
+ ///
+ let f x = x * x
+ ()
+ """
+
+ testCaseAsync "single line comment over use"
+ <| CodeFix.check
+ server
+ """
+ let f a b _ =
+ /// line on use$0
+ use r = new System.IO.BinaryReader(null)
+
+ a + b
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ let f a b _ =
+ /// line on use
+ use r = new System.IO.BinaryReader(null)
+
+ a + b
+ """
+
+ testCaseAsync "multiline comments over record type"
+ <| CodeFix.check
+ server
+ """
+ /// line 1
+ /// line 2
+ /// line 3
+ $0/// line 4
+ type MyRecord = { Foo: int }
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// line 1
+ /// line 2
+ /// line 3
+ /// line 4
+ ///
+ type MyRecord = { Foo: int }
+ """
+
+ testCaseAsync "multiline comments over discriminated union type"
+ <| CodeFix.check
+ server
+ """
+ /// line 1 on DU
+ /// $0line 2 on DU
+ /// line 3 on DU
+ type DiscUnionTest =
+ /// line 1 on Field 1
+ /// line 2 on Field 1
+ | Field1
+ /// line 1 on Field 2
+ /// line 2 on Field 2
+ | Field2
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// line 1 on DU
+ /// line 2 on DU
+ /// line 3 on DU
+ ///
+ type DiscUnionTest =
+ /// line 1 on Field 1
+ /// line 2 on Field 1
+ | Field1
+ /// line 1 on Field 2
+ /// line 2 on Field 2
+ | Field2
+ """
+
+ testCaseAsync "multiline comments over discriminated union field"
+ <| CodeFix.check
+ server
+ """
+ /// line 1 on DU
+ /// line 2 on DU
+ /// line 3 on DU
+ type DiscUnionTest =
+ /// line 1 on Field 1
+ /// line 2 on Field 1
+ | Field1
+ /// line 1 $0on Field 2
+ /// line 2 on Field 2
+ | Field2
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ /// line 1 on DU
+ /// line 2 on DU
+ /// line 3 on DU
+ type DiscUnionTest =
+ /// line 1 on Field 1
+ /// line 2 on Field 1
+ | Field1
+ ///
+ /// line 1 on Field 2
+ /// line 2 on Field 2
+ ///
+ | Field2
+ """
+
+ testCaseAsync "multiline comments over enum"
+ <| CodeFix.check
+ server
+ """
+ $0/// line 1 on enum
+ /// line 2 on enum
+ type myEnum =
+ | value1 = 1
+ | value2 = 2
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// line 1 on enum
+ /// line 2 on enum
+ ///
+ type myEnum =
+ | value1 = 1
+ | value2 = 2
+ """
+
+ testCaseAsync "multiline comment over class"
+ <| CodeFix.check
+ server
+ """
+ //$0/ On Class 1
+ /// On Class 2
+ type MyClass() =
+ /// On member 1
+ /// On member 2
+ member val Name = "" with get, set
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// On Class 1
+ /// On Class 2
+ ///
+ type MyClass() =
+ /// On member 1
+ /// On member 2
+ member val Name = "" with get, set
+ """
+
+ testCaseAsync "multiline comment over member"
+ <| CodeFix.check
+ server
+ """
+ type MyClass() =
+ /// on new 1
+ $0/// on new 2
+ new() = MyClass()
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ type MyClass() =
+ ///
+ /// on new 1
+ /// on new 2
+ ///
+ new() = MyClass()
+ """
+
+ testCaseAsync "multiline comment over autoproperty"
+ <| CodeFix.check
+ server
+ """
+ type MyClass() =
+ /// line 1 on autoproperty
+ /// li$0ne 2 on autoproperty
+ member val Name = "" with get, set
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ type MyClass() =
+ ///
+ /// line 1 on autoproperty
+ /// line 2 on autoproperty
+ ///
+ member val Name = "" with get, set
+ """
+
+ testCaseAsync "multiline comment over named module"
+ <| CodeFix.check
+ server
+ """
+ $0/// On named module 1
+ /// On named module 2
+ module M
+ let f x = x
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ ///
+ /// On named module 1
+ /// On named module 2
+ ///
+ module M
+ let f x = x
+ """
+
+ testCaseAsync "multiline comment over nested module"
+ <| CodeFix.check
+ server
+ """
+ module M
+ module MyNestedModule =
+ /// Line 1 on$0 MyNestedNestedModule
+ /// Line 2 on MyNestedNestedModule
+ module MyNestedNestedModule =
+ let x = 3
+ """
+ Diagnostics.acceptAll
+ selectCodeFix
+ """
+ module M
+ module MyNestedModule =
+ ///
+ /// Line 1 on MyNestedNestedModule
+ /// Line 2 on MyNestedNestedModule
+ ///
+ module MyNestedNestedModule =
+ let x = 3
+ """
+
+ testCaseAsync "is not applicable to existing xml tag comment"
+ <| CodeFix.checkNotApplicable
+ server
+ """
+ ///
+ /// foo$0
+ /// ...
+ """
+ Diagnostics.acceptAll
+ selectCodeFix ])
+
let private generateAbstractClassStubTests state =
let config = { defaultConfigDto with AbstractClassStubGeneration = Some true }
serverTestList (nameof GenerateAbstractClassStub) state config None (fun server -> [
@@ -1656,6 +1979,7 @@ let tests state = testList "CodeFix-tests" [
convertDoubleEqualsToSingleEqualsTests state
convertInvalidRecordToAnonRecordTests state
convertPositionalDUToNamedTests state
+ convertTripleSlashCommentToXmlTaggedDocTests state
generateAbstractClassStubTests state
generateRecordStubTests state
generateUnionCasesTests state
diff --git a/test/FsAutoComplete.Tests.Lsp/DetectUnitTests.fs b/test/FsAutoComplete.Tests.Lsp/DetectUnitTests.fs
index 729ff4358..9ad1c1626 100644
--- a/test/FsAutoComplete.Tests.Lsp/DetectUnitTests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/DetectUnitTests.fs
@@ -31,12 +31,23 @@ let tests state =
(async {
let! testNotification = geTestNotification "NUnitTests" "UnitTest1.fs"
Expect.hasLength testNotification.Tests 1 "Expected to have found 1 nunit test"
+
+ Expect.equal testNotification.Tests[0].Childs[1].Childs[0].Name "Inner" "Expect nested module to be named Inner"
+ Expect.equal testNotification.Tests[0].Childs[1].Childs[0].ModuleType "Module" "Expect nested module to be a module type"
+
+ Expect.equal testNotification.Tests[0].Childs[1].Childs[1].Name "InnerClass" "Expect nested module to be named Inner"
+ Expect.equal testNotification.Tests[0].Childs[1].Childs[1].ModuleType "TypeInModule" "Expect nested module to be a module type"
})
testCaseAsync
"Find xunit test"
(async {
let! testNotification = geTestNotification "XUnitTests" "Tests.fs"
- Expect.hasLength testNotification.Tests 1 "Expected to have found 1 xunit test"
+ Expect.hasLength testNotification.Tests 1 "Expected to have found 1 xunit test list"
+ Expect.equal testNotification.Tests[0].ModuleType "Module" "Expected top list to be module"
+
+ Expect.hasLength testNotification.Tests[0].Childs 3 "Expected to have found 3 child tests of top test"
+ Expect.equal testNotification.Tests[0].Childs[0].ModuleType "NoneModule" "Expect My test to be none module type"
+ Expect.equal testNotification.Tests[0].Childs[2].ModuleType "ModuleWithSuffix" "Expect Clashing test to be a module with suffix"
})
testCaseAsync
"Find expecto tests"
diff --git a/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs b/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs
index b60b4c59e..c0b1a6837 100644
--- a/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs
@@ -380,7 +380,7 @@ let signatureTests state =
Position = { Line = line; Character = character } }
match! server.FSharpSignature pos with
- | Ok { Content = content } ->
+ | Ok (Some { Content = content }) ->
let r = JsonSerializer.readJson> (content)
Expect.equal r.Kind "typesig" "Should have a kind of 'typesig'"
@@ -388,6 +388,7 @@ let signatureTests state =
r.Data
expectedSignature
(sprintf "Should have a signature of '%s' at character %d" expectedSignature character)
+ | Ok None -> failtestf "No signature found at character %d" character
| Result.Error errors -> failtestf "Error while getting signature: %A" errors
}
diff --git a/test/FsAutoComplete.Tests.Lsp/InfoPanelTests.fs b/test/FsAutoComplete.Tests.Lsp/InfoPanelTests.fs
index e440a2ccf..c7dd38c16 100644
--- a/test/FsAutoComplete.Tests.Lsp/InfoPanelTests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/InfoPanelTests.fs
@@ -40,7 +40,7 @@ let docFormattingTest state =
match doc with
| Result.Error err -> failtest $"Doc error: {err.Message}"
- | Result.Ok (As ([ [ model: FsAutoComplete.CommandResponse.DocumentationDescription ] ])) ->
+ | Result.Ok (Some(As ([ [ model: FsAutoComplete.CommandResponse.DocumentationDescription ] ]))) ->
Expect.stringContains model.Signature "'Key, 'U" "Formatted doc contains both params separated by (, )"
| Result.Ok _ -> failtest "couldn't parse doc as the json type we expected"
})
@@ -57,7 +57,7 @@ let docFormattingTest state =
match doc with
| Result.Error err -> failtest $"Doc error: {err.Message}"
- | Result.Ok (As ([ [ model: FsAutoComplete.CommandResponse.DocumentationDescription ] ])) ->
+ | Result.Ok (Some (As ([ [ model: FsAutoComplete.CommandResponse.DocumentationDescription ] ]))) ->
Expect.stringContains model.Signature "'T1 * 'T2 * 'T3" "Formatted doc contains 3 params separated by ( * )"
| Result.Ok _ -> failtest "couldn't parse doc as the json type we expected"
}) ]
diff --git a/test/FsAutoComplete.Tests.Lsp/TestCases/NUnitTests/UnitTest1.fs b/test/FsAutoComplete.Tests.Lsp/TestCases/NUnitTests/UnitTest1.fs
index 2f381835c..3663b1410 100644
--- a/test/FsAutoComplete.Tests.Lsp/TestCases/NUnitTests/UnitTest1.fs
+++ b/test/FsAutoComplete.Tests.Lsp/TestCases/NUnitTests/UnitTest1.fs
@@ -9,3 +9,14 @@ let Setup () =
[]
let Test1 () =
Assert.Pass()
+
+module Outer =
+ module Inner =
+ []
+ let Test2 (i: int) =
+ Assert.Pass()
+
+ type InnerClass() =
+ []
+ member this.Test1 () =
+ Assert.Pass()
diff --git a/test/FsAutoComplete.Tests.Lsp/TestCases/XUnitTests/Tests.fs b/test/FsAutoComplete.Tests.Lsp/TestCases/XUnitTests/Tests.fs
index 7d11a6453..85a0e28a9 100644
--- a/test/FsAutoComplete.Tests.Lsp/TestCases/XUnitTests/Tests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/TestCases/XUnitTests/Tests.fs
@@ -6,3 +6,16 @@ open Xunit
[]
let ``My test`` () =
Assert.True(true)
+
+module Inner =
+ []
+ let ``Other test`` () =
+ Assert.True(true)
+
+type NameClash () =
+ do ()
+
+module NameClash =
+ []
+ let ``Clashing test`` () =
+ Assert.True(true)
\ No newline at end of file