From 0d5eaaac66fed062dd0c0464884751ab3d955477 Mon Sep 17 00:00:00 2001
From: Thomas Boby
Date: Sun, 3 Apr 2022 17:42:29 +0100
Subject: [PATCH 1/3] Limit to types in some SynType locations
---
src/FsAutoComplete.Core/ParseAndCheckResults.fs | 16 ++++++++++------
src/FsAutoComplete.Core/UntypedAstUtils.fs | 3 +++
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/FsAutoComplete.Core/ParseAndCheckResults.fs b/src/FsAutoComplete.Core/ParseAndCheckResults.fs
index 14078ebed..c44eb944a 100644
--- a/src/FsAutoComplete.Core/ParseAndCheckResults.fs
+++ b/src/FsAutoComplete.Core/ParseAndCheckResults.fs
@@ -324,6 +324,7 @@ type ParseAndCheckResults
member x.TryGetToolTipEnhanced (pos: Position) (lineStr: LineStr) =
match Completion.atPos (pos, x.GetParseResults.ParseTree) with
| Completion.Context.StringLiteral -> Ok None
+ | Completion.Context.SynType
| Completion.Context.Unknown ->
match Lexer.findLongIdents (pos.Column, lineStr) with
| None -> Error "Cannot find ident for tooltip"
@@ -551,9 +552,11 @@ type ParseAndCheckResults
member x.TryGetCompletions (pos: Position) (lineStr: LineStr) filter (getAllSymbols: unit -> AssemblySymbol list) =
async {
- match Completion.atPos (pos, x.GetParseResults.ParseTree) with
+ let completionContext = Completion.atPos (pos, x.GetParseResults.ParseTree)
+ match completionContext with
| Completion.Context.StringLiteral -> return None
- | Completion.Context.Unknown ->
+ | Completion.Context.Unknown
+ | Completion.Context.SynType ->
try
let longName =
QuickParse.GetPartialLongNameEx(lineStr, pos.Column - 1)
@@ -565,10 +568,12 @@ type ParseAndCheckResults
>> Log.addContextDestructured "longName" longName
)
- let getAllSymbols () =
+ let getSymbols () =
getAllSymbols ()
|> List.filter (fun entity ->
- entity.FullName.Contains "."
+ // Attempt to filter to types when we know we're in a type and FCS uses all symbols
+ (completionContext <> Completion.Context.SynType || entity.Kind LookupType.Fuzzy = EntityKind.Type)
+ && entity.FullName.Contains "."
&& not (PrettyNaming.IsOperatorDisplayName entity.Symbol.DisplayName))
let token = Lexer.getSymbol pos.Line (pos.Column - 1) lineStr SymbolLookupKind.Simple [||]
@@ -590,8 +595,7 @@ type ParseAndCheckResults
| _ ->
let results =
- checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineStr, longName, getAllSymbols)
-
+ checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineStr, longName, getSymbols)
let getKindPriority =
function
| CompletionItemKind.CustomOperation -> -1
diff --git a/src/FsAutoComplete.Core/UntypedAstUtils.fs b/src/FsAutoComplete.Core/UntypedAstUtils.fs
index 24572194f..715eab69b 100644
--- a/src/FsAutoComplete.Core/UntypedAstUtils.fs
+++ b/src/FsAutoComplete.Core/UntypedAstUtils.fs
@@ -1910,6 +1910,7 @@ module Completion =
type Context =
| StringLiteral
| Unknown
+ | SynType
let atPos (pos: Position, ast: ParsedInput): Context =
let visitor =
@@ -1930,6 +1931,8 @@ module Completion =
)
| _ -> defaultTraverse expr
else None
+
+ member x.VisitType(path, defaultTraverse, synType) : Context option = Some Context.SynType
}
SyntaxTraversal.Traverse(pos, ast, visitor)
|> Option.defaultValue Context.Unknown
From a6dd71780fdcf85155958bdf9127a46938441497 Mon Sep 17 00:00:00 2001
From: Thomas Boby
Date: Sun, 3 Apr 2022 17:54:20 +0100
Subject: [PATCH 2/3] Add a simple test
---
.../CompletionTests.fs | 33 +++++++++++++++++++
.../TestCases/Completion/Script.fsx | 4 +++
2 files changed, 37 insertions(+)
diff --git a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
index 6ba07172a..9853fc41c 100644
--- a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
@@ -113,6 +113,39 @@ let tests state =
"first member should be List.Empty, since properties are preferred over functions"
| Ok None -> failtest "Should have gotten some completion items"
| Error e -> failtestf "Got an error while retrieving completions: %A" e
+ })
+ testCaseAsync
+ "completion in record defn field type"
+ (async {
+ let! server, path = server
+
+ let completionParams: CompletionParams =
+ { TextDocument = { Uri = Path.FilePathToUri path }
+ Position = { Line = 13; Character = 10 } // after str
+ Context =
+ Some
+ { triggerKind = CompletionTriggerKind.Invoked
+ triggerCharacter = None } }
+
+ let! response = server.TextDocumentCompletion completionParams
+
+ match response with
+ | Ok (Some completions) ->
+ Expect.isLessThan
+ completions.Items.Length
+ 300
+ "shouldn't have a very long list of completion items that are only types"
+ Expect.isGreaterThan
+ completions.Items.Length
+ 100
+ "should have a reasonable number of completion items that are only types"
+
+ Expect.exists
+ completions.Items
+ (fun item -> item.Label = "list")
+ "completion should contain the list type"
+ | Ok None -> failtest "Should have gotten some completion items"
+ | Error e -> failtestf "Got an error while retrieving completions: %A" e
}) ]
///Tests for getting autocomplete
diff --git a/test/FsAutoComplete.Tests.Lsp/TestCases/Completion/Script.fsx b/test/FsAutoComplete.Tests.Lsp/TestCases/Completion/Script.fsx
index a37d4d040..118937757 100644
--- a/test/FsAutoComplete.Tests.Lsp/TestCases/Completion/Script.fsx
+++ b/test/FsAutoComplete.Tests.Lsp/TestCases/Completion/Script.fsx
@@ -7,3 +7,7 @@ async {
List.
let tail = List.
+
+type A = {
+ Id : Lis
+}
From e2068f1132ef0837c26a36669ac1a1af1dfada7a Mon Sep 17 00:00:00 2001
From: Chet Husk
Date: Sun, 3 Apr 2022 14:37:56 -0500
Subject: [PATCH 3/3] Update test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
---
test/FsAutoComplete.Tests.Lsp/CompletionTests.fs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
index 9853fc41c..b00601296 100644
--- a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
+++ b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs
@@ -121,7 +121,7 @@ let tests state =
let completionParams: CompletionParams =
{ TextDocument = { Uri = Path.FilePathToUri path }
- Position = { Line = 13; Character = 10 } // after str
+ Position = { Line = 13; Character = 10 } // after Lis partial type name in Id record field declaration
Context =
Some
{ triggerKind = CompletionTriggerKind.Invoked