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