Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GetSymbolUsesAtLocation API. #15285

Merged
merged 3 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2089,6 +2089,36 @@ type internal TypeCheckInfo
Trace.TraceInformation(sprintf "FCS: recovering from error in GetSymbolUseAtLocation: '%s'" msg)
None)

member _.GetSymbolUsesAtLocation(line, lineStr, colAtEndOfNames, names) =
nojaf marked this conversation as resolved.
Show resolved Hide resolved
DiagnosticsScope.Protect
range0
(fun () ->
let declItemsOpt =
GetDeclItemsForNamesAtPosition(
None,
Some names,
None,
None,
line,
lineStr,
colAtEndOfNames,
ResolveTypeNamesToCtors,
ResolveOverloads.Yes,
None,
(fun () -> [])
)

match declItemsOpt with
| None -> List.empty
| Some (items, denv, _, m) ->
items
|> List.map (fun item ->
let symbol = FSharpSymbol.Create(cenv, item.Item)
symbol, item.ItemWithInst, denv, m))
(fun msg ->
Trace.TraceInformation(sprintf "FCS: recovering from error in GetSymbolUsesAtLocation: '%s'" msg)
nojaf marked this conversation as resolved.
Show resolved Hide resolved
List.empty)

member _.PartialAssemblySignatureForFile =
FSharpAssemblySignature(g, thisCcu, ccuSigForFile, tcImports, None, ccuSigForFile)

Expand Down Expand Up @@ -2796,12 +2826,16 @@ type FSharpCheckFileResults
| None -> emptyFindDeclResult
| Some (scope, _builderOpt) -> scope.GetDeclarationLocation(line, lineText, colAtEndOfNames, names, preferFlag)

member _.GetSymbolUseAtLocation(line, colAtEndOfNames, lineText, names) =
member this.GetSymbolUseAtLocation(line, colAtEndOfNames, lineText, names) =
this.GetSymbolUsesAtLocation(line, colAtEndOfNames, lineText, names)
|> List.tryHead

member _.GetSymbolUsesAtLocation(line, colAtEndOfNames, lineText, names) =
match details with
| None -> None
| None -> List.empty
| Some (scope, _builderOpt) ->
scope.GetSymbolUseAtLocation(line, lineText, colAtEndOfNames, names)
|> Option.map (fun (sym, itemWithInst, denv, m) ->
scope.GetSymbolUsesAtLocation(line, lineText, colAtEndOfNames, names)
|> List.map (fun (sym, itemWithInst, denv, m) ->
FSharpSymbolUse(denv, sym, itemWithInst.TyparInstantiation, ItemOccurence.Use, m))

member _.GetMethodsAsSymbols(line, colAtEndOfNames, lineText, names) =
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/Service/FSharpCheckerResults.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ type public FSharpCheckFileResults =
member GetSymbolUseAtLocation:
line: int * colAtEndOfNames: int * lineText: string * names: string list -> FSharpSymbolUse option

/// <summary>Similar to GetSymbolUseAtLocation, but returns all found symbols if there are multiple.</summary>
///
/// <param name="line">The line number where the information is being requested.</param>
/// <param name="colAtEndOfNames">The column number at the end of the identifiers where the information is being requested.</param>
/// <param name="lineText">The text of the line where the information is being requested.</param>
/// <param name="names">The identifiers at the location where the information is being requested.</param>
member GetSymbolUsesAtLocation:
line: int * colAtEndOfNames: int * lineText: string * names: string list -> FSharpSymbolUse list

/// <summary>Get any extra colorization info that is available after the typecheck</summary>
member GetSemanticClassification: range option -> SemanticClassificationItem[]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,7 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSh
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] OpenDeclarations
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] get_OpenDeclarations()
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Text.Range[] GetFormatSpecifierLocations()
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUsesAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetDeclarationListSymbols(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUseAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position)
Expand Down Expand Up @@ -5156,14 +5157,14 @@ FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_HasFields()
FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_IsUnresolved()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType ReturnType
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType get_ReturnType()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range DeclarationLocation
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range get_DeclarationLocation()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity()
FSharp.Compiler.Symbols.FSharpUnionCase: Int32 GetHashCode()
FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes
FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes()
Expand Down Expand Up @@ -11375,4 +11376,4 @@ FSharp.Compiler.Xml.XmlDoc: System.String GetXmlText()
FSharp.Compiler.Xml.XmlDoc: System.String[] GetElaboratedXmlLines()
FSharp.Compiler.Xml.XmlDoc: System.String[] UnprocessedLines
FSharp.Compiler.Xml.XmlDoc: System.String[] get_UnprocessedLines()
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
Original file line number Diff line number Diff line change
Expand Up @@ -2005,6 +2005,7 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSh
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] OpenDeclarations
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Symbols.FSharpOpenDeclaration[] get_OpenDeclarations()
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Text.Range[] GetFormatSpecifierLocations()
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUsesAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetDeclarationListSymbols(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUseAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String])
FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position)
Expand Down Expand Up @@ -5156,14 +5157,14 @@ FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_HasFields()
FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_IsUnresolved()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType ReturnType
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType get_ReturnType()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range DeclarationLocation
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range get_DeclarationLocation()
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity
FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity()
FSharp.Compiler.Symbols.FSharpUnionCase: Int32 GetHashCode()
FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes
FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes()
Expand Down
50 changes: 49 additions & 1 deletion tests/service/Symbols.fs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,54 @@ type Foo =
(:? FSharpMemberOrFunctionOrValue as setMfv) ->
Assert.AreNotEqual(getMfv.CurriedParameterGroups, setMfv.CurriedParameterGroups)
| _ -> Assert.Fail "Expected symbols to be FSharpMemberOrFunctionOrValue"

[<Test>]
let ``Multiple symbols are resolved for property`` () =
let source = """
type X(y: string) =
member val Y = y with get, set
"""

let _, checkResults = getParseAndCheckResults source
let symbolUses =
checkResults.GetSymbolUsesAtLocation(3, 16, " member val Y = y with get, set", [ "Y" ])
|> List.map (fun su -> su.Symbol)

match symbolUses with
| [ :? FSharpMemberOrFunctionOrValue as setMfv
:? FSharpMemberOrFunctionOrValue as getMfv ] ->
Assert.AreEqual("set_Y", setMfv.CompiledName)
Assert.AreEqual("get_Y", getMfv.CompiledName)
| _ -> Assert.Fail "Expected symbols"

[<Test>]
let ``Multiple relevant symbols for type name`` () =
let _, checkResults = getParseAndCheckResults """
// This is a generated file; the original input is 'FSInteractiveSettings.txt'
namespace FSInteractiveSettings
type internal SR () =
static let mutable swallowResourceText = false
/// If set to true, then all error messages will just return the filled 'holes' delimited by ',,,'s - this is for language-neutral testing (e.g. localization-invariant baselines).
static member SwallowResourceText with get () = swallowResourceText
and set (b) = swallowResourceText <- b
// END BOILERPLATE
"""

let symbols =
checkResults.GetSymbolUsesAtLocation(5, 16, "type internal SR () =", [ "" ])
|> List.map (fun su -> su.Symbol)

match symbols with
| [ :? FSharpMemberOrFunctionOrValue as cctor
:? FSharpMemberOrFunctionOrValue as ctor
:? FSharpEntity as entity ] ->
Assert.AreEqual(".cctor", cctor.CompiledName)
Assert.AreEqual(".ctor", ctor.CompiledName)
Assert.AreEqual("SR", entity.DisplayName)
| _ -> Assert.Fail "Expected symbols"

module Expressions =
[<Test>]
Expand Down Expand Up @@ -566,4 +614,4 @@ match Unchecked.defaultof<R> with
"""
getSymbolUses checkResults
|> Seq.exists (fun symbolUse -> symbolUse.IsFromUse && symbolUse.Symbol.DisplayName = "F2")
|> shouldEqual true
|> shouldEqual true