Skip to content

Commit d70a450

Browse files
nosamiKevinRansom
authored andcommitted
Get declaration list symbols (#4204)
* Update GetDeclarationListSymbols to add getAllEntities * Don't group types with the same display name as function overloads. Now that we can include all entities for top level completions, the grouping function can incorrectly group types with the same display name as function overloads. Use the compiled name instead as this includes the namespace. * Get logical name from ExnCase * Make getAllEntities optional Also renamed getAllSymbols to getAllEntities everywhere for consistency
1 parent 09fc352 commit d70a450

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

src/fsharp/service/service.fs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -930,11 +930,11 @@ type TypeCheckInfo
930930
scope.IsRelativeNameResolvable(cursorPos, plid, symbol.Item)
931931

932932
/// Get the auto-complete items at a location
933-
member __.GetDeclarations (ctok, parseResultsOpt, line, lineStr, partialName, getAllSymbols, hasTextChangedSinceLastTypecheck) =
933+
member __.GetDeclarations (ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck) =
934934
let isInterfaceFile = SourceFileImpl.IsInterfaceFile mainInputFileName
935935
ErrorScope.Protect Range.range0
936936
(fun () ->
937-
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllSymbols, hasTextChangedSinceLastTypecheck) with
937+
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllEntities, hasTextChangedSinceLastTypecheck) with
938938
| None -> FSharpDeclarationListInfo.Empty
939939
| Some (items, denv, ctx, m) ->
940940
let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items
@@ -950,11 +950,11 @@ type TypeCheckInfo
950950
FSharpDeclarationListInfo.Error msg)
951951

952952
/// Get the symbols for auto-complete items at a location
953-
member __.GetDeclarationListSymbols (ctok, parseResultsOpt, line, lineStr, partialName, hasTextChangedSinceLastTypecheck) =
953+
member __.GetDeclarationListSymbols (ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck) =
954954
let isInterfaceFile = SourceFileImpl.IsInterfaceFile mainInputFileName
955955
ErrorScope.Protect Range.range0
956956
(fun () ->
957-
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, (fun () -> []), hasTextChangedSinceLastTypecheck) with
957+
match GetDeclItemsForNamesAtPosition(ctok, parseResultsOpt, Some partialName.QualifyingIdents, Some partialName.PartialIdent, partialName.LastDotPos, line, lineStr, partialName.EndColumn + 1, ResolveTypeNamesToCtors, ResolveOverloads.Yes, getAllEntities, hasTextChangedSinceLastTypecheck) with
958958
| None -> List.Empty
959959
| Some (items, denv, _, m) ->
960960
let items = if isInterfaceFile then items |> List.filter (fun x -> IsValidSignatureFileItem x.Item) else items
@@ -966,7 +966,7 @@ type TypeCheckInfo
966966
// - show types with fewer generic parameters first
967967
// - show types before over other related items - they usually have very useful XmlDocs
968968
let items =
969-
items |> List.sortBy (fun d ->
969+
items |> List.sortBy (fun d ->
970970
let n =
971971
match d.Item with
972972
| Item.Types (_,(TType_app(tcref,_) :: _)) -> 1 + tcref.TyparsNoRange.Length
@@ -981,8 +981,18 @@ type TypeCheckInfo
981981
// Remove all duplicates. We've put the types first, so this removes the DelegateCtor and DefaultStructCtor's.
982982
let items = items |> RemoveDuplicateCompletionItems g
983983

984-
// Group by display name
985-
let items = items |> List.groupBy (fun d -> d.Item.DisplayName)
984+
// Group by compiled name for types, display name for functions
985+
// (We don't want types with the same display name to be grouped as overloads)
986+
let items =
987+
items |> List.groupBy (fun d ->
988+
match d.Item with
989+
| Item.Types (_,(TType_app(tcref,_) :: _))
990+
| Item.ExnCase tcref -> tcref.LogicalName
991+
| Item.UnqualifiedType(tcref :: _)
992+
| Item.FakeInterfaceCtor (TType_app(tcref,_))
993+
| Item.DelegateCtor (TType_app(tcref,_)) -> tcref.CompiledName
994+
| Item.CtorGroup (_, (cinfo :: _)) -> (tcrefOfAppTy g cinfo.EnclosingType).CompiledName
995+
| _ -> d.Item.DisplayName)
986996

987997
// Filter out operators (and list)
988998
let items =
@@ -1928,16 +1938,18 @@ type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOp
19281938
member info.HasFullTypeCheckInfo = details.IsSome
19291939

19301940
/// Intellisense autocompletions
1931-
member info.GetDeclarationListInfo(parseResultsOpt, line, lineStr, partialName, getAllEntities, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) =
1941+
member info.GetDeclarationListInfo(parseResultsOpt, line, lineStr, partialName, ?getAllEntities, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) =
19321942
let userOpName = defaultArg userOpName "Unknown"
1943+
let getAllEntities = defaultArg getAllEntities (fun() -> [])
19331944
let hasTextChangedSinceLastTypecheck = defaultArg hasTextChangedSinceLastTypecheck (fun _ -> false)
19341945
reactorOp userOpName "GetDeclarations" FSharpDeclarationListInfo.Empty (fun ctok scope ->
19351946
scope.GetDeclarations(ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck))
19361947

1937-
member info.GetDeclarationListSymbols(parseResultsOpt, line, lineStr, partialName, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) =
1948+
member info.GetDeclarationListSymbols(parseResultsOpt, line, lineStr, partialName, ?getAllEntities, ?hasTextChangedSinceLastTypecheck, ?userOpName: string) =
19381949
let userOpName = defaultArg userOpName "Unknown"
19391950
let hasTextChangedSinceLastTypecheck = defaultArg hasTextChangedSinceLastTypecheck (fun _ -> false)
1940-
reactorOp userOpName "GetDeclarationListSymbols" List.empty (fun ctok scope -> scope.GetDeclarationListSymbols(ctok, parseResultsOpt, line, lineStr, partialName, hasTextChangedSinceLastTypecheck))
1951+
let getAllEntities = defaultArg getAllEntities (fun() -> [])
1952+
reactorOp userOpName "GetDeclarationListSymbols" List.empty (fun ctok scope -> scope.GetDeclarationListSymbols(ctok, parseResultsOpt, line, lineStr, partialName, getAllEntities, hasTextChangedSinceLastTypecheck))
19411953

19421954
/// Resolve the names at the given location to give a data tip
19431955
member info.GetStructuredToolTipText(line, colAtEndOfNames, lineStr, names, tokenTag, ?userOpName: string) =

src/fsharp/service/service.fsi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,16 @@ type public FSharpCheckFileResults =
119119
/// The text of the line where the completion is happening. This is only used to make a couple
120120
/// of adhoc corrections to completion accuracy (e.g. checking for "..")
121121
/// </param>
122-
/// <param name="getAllSymbols">
123-
/// Function that returns all symbols from current and referenced assemblies.
122+
/// <param name="getAllEntities">
123+
/// Function that returns all entities from current and referenced assemblies.
124124
/// </param>
125125
/// <param name="hasTextChangedSinceLastTypecheck">
126126
/// If text has been used from a captured name resolution from the typecheck, then
127127
/// callback to the client to check if the text has changed. If it has, then give up
128128
/// and assume that we're going to repeat the operation later on.
129129
/// </param>
130130
/// <param name="userOpName">An optional string used for tracing compiler operations associated with this request.</param>
131-
member GetDeclarationListInfo : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * getAllSymbols: (unit -> AssemblySymbol list) * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async<FSharpDeclarationListInfo>
131+
member GetDeclarationListInfo : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async<FSharpDeclarationListInfo>
132132

133133
/// <summary>Get the items for a declaration list in FSharpSymbol format</summary>
134134
///
@@ -145,16 +145,16 @@ type public FSharpCheckFileResults =
145145
/// The text of the line where the completion is happening. This is only used to make a couple
146146
/// of adhoc corrections to completion accuracy (e.g. checking for "..")
147147
/// </param>
148-
/// <param name="getAllSymbols">
149-
/// Function that returns all symbols from current and referenced assemblies.
148+
/// <param name="getAllEntities">
149+
/// Function that returns all entities from current and referenced assemblies.
150150
/// </param>
151151
/// <param name="hasTextChangedSinceLastTypecheck">
152152
/// If text has been used from a captured name resolution from the typecheck, then
153153
/// callback to the client to check if the text has changed. If it has, then give up
154154
/// and assume that we're going to repeat the operation later on.
155155
/// </param>
156156
/// <param name="userOpName">An optional string used for tracing compiler operations associated with this request.</param>
157-
member GetDeclarationListSymbols : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async<FSharpSymbolUse list list>
157+
member GetDeclarationListSymbols : ParsedFileResultsOpt:FSharpParseFileResults option * line: int * lineText:string * partialName: PartialLongName * ?getAllEntities: (unit -> AssemblySymbol list) * ?hasTextChangedSinceLastTypecheck: (obj * range -> bool) * ?userOpName: string -> Async<FSharpSymbolUse list list>
158158

159159

160160
/// <summary>Compute a formatted tooltip for the given location</summary>

tests/service/EditorTests.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ type Test() =
348348
let file = "/home/user/Test.fsx"
349349
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
350350

351-
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), fun _ -> false)|> Async.RunSynchronously
351+
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(20), (fun () -> []), fun _ -> false)|> Async.RunSynchronously
352352
//decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A"
353353
decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true
354354

@@ -365,7 +365,7 @@ type Test() =
365365
let file = "/home/user/Test.fsx"
366366
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
367367

368-
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), fun _ -> false)|> Async.RunSynchronously
368+
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(21), (fun () -> []), fun _ -> false)|> Async.RunSynchronously
369369
//decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A"
370370
decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true
371371

@@ -382,7 +382,7 @@ type Test() =
382382
let file = "/home/user/Test.fsx"
383383
let parseResult, typeCheckResults = parseAndCheckScript(file, input)
384384

385-
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), fun _ -> false)|> Async.RunSynchronously
385+
let decls = typeCheckResults.GetDeclarationListSymbols(Some parseResult, 4, inputLines.[3], PartialLongName.Empty(14), (fun () -> []), fun _ -> false)|> Async.RunSynchronously
386386
//decls |> List.map (fun d -> d.Head.Symbol.DisplayName) |> printfn "---> decls = %A"
387387
decls |> Seq.exists (fun d -> d.Head.Symbol.DisplayName = "abc") |> shouldEqual true
388388

0 commit comments

Comments
 (0)