Skip to content

Commit 17447cd

Browse files
committed
Merge pull request #297 from 7sharp9/GetMethodsAsSymbols
Added GetMethodsAsSymbols
2 parents 8561a9c + a9ba4d2 commit 17447cd

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

src/fsharp/vs/service.fs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,39 @@ type TypeCheckInfo
11641164
(fun msg ->
11651165
FSharpMethodGroup(msg,[| |]))
11661166

1167+
member scope.GetMethodsAsSymbols (line, lineStr, colAtEndOfNames, names) =
1168+
match GetDeclItemsForNamesAtPosition (None,Some(names), None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors, ResolveOverloads.No, fun _ -> false) with
1169+
| None | Some ([], _, _) -> None
1170+
| Some (items, denv, m) ->
1171+
let allItems =
1172+
items
1173+
|> List.collect (fun item ->
1174+
match item with
1175+
| Item.MethodGroup(nm,minfos) -> minfos |> List.map (fun minfo -> Item.MethodGroup(nm,[minfo]))
1176+
| Item.CtorGroup(nm,cinfos) -> cinfos |> List.map (fun minfo -> Item.CtorGroup(nm,[minfo]))
1177+
| Item.FakeInterfaceCtor _
1178+
| Item.DelegateCtor _ -> [item]
1179+
| Item.NewDef _
1180+
| Item.ILField _ -> []
1181+
| Item.Event _ -> []
1182+
| Item.RecdField(rfinfo) -> if isFunction g rfinfo.FieldType then [item] else []
1183+
| Item.Value v -> if isFunction g v.Type then [item] else []
1184+
| Item.UnionCase(ucr) -> if not ucr.UnionCase.IsNullary then [item] else []
1185+
| Item.ExnCase(ecr) -> if recdFieldsOfExnDefRef ecr |> nonNil then [item] else []
1186+
| Item.Property(_,pinfos) ->
1187+
let pinfo = List.head pinfos
1188+
if pinfo.IsIndexer then [item] else []
1189+
#if EXTENSIONTYPING
1190+
| Params.ItemIsTypeWithStaticArguments g _ -> [item] // we pretend that provided-types-with-static-args are method-like in order to get ParamInfo for them
1191+
#endif
1192+
| Item.CustomOperation(_name, _helpText, _minfo) -> [item]
1193+
| Item.TypeVar _ -> []
1194+
| Item.CustomBuilder _ -> []
1195+
| _ -> [] )
1196+
1197+
let symbols = allItems |> List.map (fun item -> FSharpSymbol.Create(g, thisCcu, tcImports, item))
1198+
Some (symbols, denv, m)
1199+
11671200
member scope.GetDeclarationLocation (line, lineStr, colAtEndOfNames, names, preferFlag) =
11681201
match GetDeclItemsForNamesAtPosition (None,Some(names), None, line, lineStr, colAtEndOfNames, ResolveTypeNamesToCtors,ResolveOverloads.Yes, fun _ -> false) with
11691202
| None
@@ -1789,6 +1822,12 @@ type FSharpCheckFileResults(errors: FSharpErrorInfo[], scopeOptX: TypeCheckInfo
17891822
scope.GetSymbolUseAtLocation (line, lineStr, colAtEndOfNames, names)
17901823
|> Option.map (fun (sym,denv,m) -> FSharpSymbolUse(scope.TcGlobals,denv,sym,ItemOccurence.Use,m)))
17911824

1825+
member info.GetMethodsAsSymbols (line, colAtEndOfNames, lineStr, names) =
1826+
reactorOp None (fun scope ->
1827+
scope.GetMethodsAsSymbols (line, lineStr, colAtEndOfNames, names)
1828+
|> Option.map (fun (symbols,denv,m) ->
1829+
symbols |> List.map (fun sym -> FSharpSymbolUse(scope.TcGlobals,denv,sym,ItemOccurence.Use,m))))
1830+
17921831
member info.GetSymbolAtLocationAlternate (line, colAtEndOfNames, lineStr, names) =
17931832
reactorOp None (fun scope ->
17941833
scope.GetSymbolUseAtLocation (line, lineStr, colAtEndOfNames, names)

src/fsharp/vs/service.fsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ type FSharpCheckFileResults =
228228
/// <param name="names">The identifiers at the location where the information is being requested.</param>
229229
member GetMethodsAlternate : line:int * colAtEndOfNames:int * lineText:string * names:string list option -> Async<FSharpMethodGroup>
230230

231+
/// <summary>Compute a set of method overloads to show in a dialog relevant to the given code location. The resulting method overloads are returned as symbols.</summary>
232+
/// <param name="line">The line number where the information is being requested.</param>
233+
/// <param name="colAtEndOfNames">The column number at the end of the identifiers where the information is being requested.</param>
234+
/// <param name="lineText">The text of the line where the information is being requested.</param>
235+
/// <param name="names">The identifiers at the location where the information is being requested.</param>
236+
member GetMethodsAsSymbols : line:int * colAtEndOfNames:int * lineText:string * names:string list -> Async<FSharpSymbolUse list option>
237+
231238
/// <summary>Resolve the names at the given location to the declaration location of the corresponding construct.</summary>
232239
///
233240
/// <param name="line">The line number where the information is being requested.</param>

tests/service/EditorTests.fs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,40 @@ let ``Intro test`` () =
7979
("Concat", ["arg0: obj"; "arg1: obj"; "arg2: obj"; "arg3: obj"]);
8080
("Concat", ["str0: string"; "str1: string"; "str2: string"; "str3: string"])]
8181

82+
[<Test>]
83+
let ``GetMethodsAsSymbols should return all overloads of a method as FSharpSymbolUse`` () =
84+
85+
let extractCurriedParams (symbol:FSharpSymbolUse) =
86+
match symbol.Symbol with
87+
| :? FSharpMemberOrFunctionOrValue as mvf ->
88+
[for pg in mvf.CurriedParameterGroups do
89+
for (p:FSharpParameter) in pg do
90+
yield p.DisplayName, p.Type.Format (symbol.DisplayContext)]
91+
| _ -> []
92+
93+
// Split the input & define file name
94+
let inputLines = input.Split('\n')
95+
let file = "/home/user/Test.fsx"
96+
let untyped, typeCheckResults = parseAndTypeCheckFileInProject(file, input)
97+
let methodsSymbols = typeCheckResults.GetMethodsAsSymbols(5, 27, inputLines.[4], ["String"; "Concat"]) |> Async.RunSynchronously
98+
match methodsSymbols with
99+
| Some methods ->
100+
[ for ms in methods do
101+
yield ms.Symbol.DisplayName, extractCurriedParams ms ]
102+
|> List.sortBy (fun (_name, parameters) -> parameters.Length, (parameters |> List.map snd ))
103+
|> shouldEqual
104+
[("Concat", [("values", "Collections.Generic.IEnumerable<'T>")]);
105+
("Concat", [("values", "Collections.Generic.IEnumerable<string>")]);
106+
("Concat", [("arg0", "obj")]);
107+
("Concat", [("args", "obj []")]);
108+
("Concat", [("values", "string []")]);
109+
("Concat", [("arg0", "obj"); ("arg1", "obj")]);
110+
("Concat", [("str0", "string"); ("str1", "string")]);
111+
("Concat", [("arg0", "obj"); ("arg1", "obj"); ("arg2", "obj")]);
112+
("Concat", [("str0", "string"); ("str1", "string"); ("str2", "string")]);
113+
("Concat", [("arg0", "obj"); ("arg1", "obj"); ("arg2", "obj"); ("arg3", "obj")]);
114+
("Concat", [("str0", "string"); ("str1", "string"); ("str2", "string"); ("str3", "string")])]
115+
| None -> failwith "No symbols returned"
82116

83117

84118
let input2 =

0 commit comments

Comments
 (0)