Uh oh!
There was an error while loading. Please reload this page.
VS Go to definition from C# to F# - #14377
Conversation
Uh oh!
There was an error while loading. Please reload this page.
vzarytovskii
commented
Nov 28, 2022
This is ready for the first iteration, please see comments in the OP, regarding tests and what's supported. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| let mutable locations = Seq.empty | ||
| for project in projects do |
There was a problem hiding this comment.
We could probably do this in parallel.
There was a problem hiding this comment.
This is just a fool-proof, we expect it always be only a single project, parallel then will give you a bunch of overhead
There was a problem hiding this comment.
Right, didn't notice where it's coming from. Is it even theoretically possible there will be multiple projects with the same assembly name? Because maybe you could replace filter with tryFind and it would be a bit simpler.
There was a problem hiding this comment.
Is it even theoretically possible there will be multiple projects with the same assembly name?
Very unlikely, I have never seen it before.
Because maybe you could replace
filterwithtryFindand it would be a bit simpler.
I'll see how it looks with option
There was a problem hiding this comment.
With option it could look something like this (After also adding DocCommentId.EntityPath):
letproject= workspace.CurrentSolution.Projects |> Seq.tryFind (fun p -> p.IsFSharp && p.AssemblyName = assemblyName)letlocations= project
|> Option.map (fun project ->let!checker,_,_,options = project.GetFSharpCompilationOptionsAsync(cancellationToken)let!result= checker.ParseAndCheckProject(options)letentity= path.EntityPath |> result.AssemblySignature.FindEntityByPath
match path with| DocCommentId.Member ({ MemberOrValName = memberOrVal; GenericParameters = genericParametersCount }, memberType)->
entity |> tryFindVal memberOrVal documentationCommentId memberType genericParametersCount
| DocCommentId.Field { MemberOrValName = memberOrVal }->
entity |> tryFindFieldByName memberOrVal
| DocCommentId.Type _-> Seq.singleton entity.DeclarationLocation
| DocCommentId.None -> Seq.empty |> Seq.map (fun m ->(m, project)))|> Option.defaultValue Seq.emptyA bit easier to see what's going on with arrows only going in one direction :)
| | DocCommentId.Member ({ EntityPath = entityPath; MemberOrValName = memberOrVal; GenericParameters = genericParametersCount }, memberType) -> | ||
| let entity = result.AssemblySignature.FindEntityByPath (entityPath) | ||
| match entity with | ||
| | Some e -> |
There was a problem hiding this comment.
probably should replace with Option.map/iter or something
psfinaki
commented
Nov 29, 2022
Annoying question - any idea/chance to test this? |
vzarytovskii
commented
Nov 29, 2022
No, I've asked the same question in the first paragraph |
KevinRansom
left a comment
There was a problem hiding this comment.
Looks pretty good, no tests yet though. (That's rich coming from me :-))
vzarytovskii
commented
Dec 2, 2022
Yeah, that's the question - I'm not yet entirely sure how to do that. |
…ytovskii/fsharp into vs-external-goto-definition
vzarytovskii
commented
Jan 5, 2023
Ok, this is ready, I failed (gave up really) to add proper tests in headless VS, but added to the important part - parser for doccomment id. |
WIP VS Go to definition from C# to F#Uh oh!
There was an error while loading. Please reload this page.
| let mutable locations = Seq.empty | ||
| for project in projects do |
There was a problem hiding this comment.
With option it could look something like this (After also adding DocCommentId.EntityPath):
letproject= workspace.CurrentSolution.Projects |> Seq.tryFind (fun p -> p.IsFSharp && p.AssemblyName = assemblyName)letlocations= project
|> Option.map (fun project ->let!checker,_,_,options = project.GetFSharpCompilationOptionsAsync(cancellationToken)let!result= checker.ParseAndCheckProject(options)letentity= path.EntityPath |> result.AssemblySignature.FindEntityByPath
match path with| DocCommentId.Member ({ MemberOrValName = memberOrVal; GenericParameters = genericParametersCount }, memberType)->
entity |> tryFindVal memberOrVal documentationCommentId memberType genericParametersCount
| DocCommentId.Field { MemberOrValName = memberOrVal }->
entity |> tryFindFieldByName memberOrVal
| DocCommentId.Type _-> Seq.singleton entity.DeclarationLocation
| DocCommentId.None -> Seq.empty |> Seq.map (fun m ->(m, project)))|> Option.defaultValue Seq.emptyA bit easier to see what's going on with arrows only going in one direction :)
T:prefix for typesT:N.X.Nested- typeT:N.X.D- delegateM:prefix is for methodsM:N.X.#ctor- constructorM:N.X.#ctor(System.Int32)- constructor with one parameterM:N.X.f- method with unit parameterM:N.X.bb(System.String,System.Int32@)- method with two parametersM:N.X.gg(System.Int16[],System.Int32[0:,0:])- method with two parameters, 1d and 2d arrayM:N.X.op_Addition(N.X,N.X)- operatorM:N.X.op_Explicit(N.X)~System.Int32- operator with return typeM:N.GenericMethod.WithNestedType``1(N.GenericType{``0}.NestedType)- generic type with one parameterM:N.GenericMethod.WithIntOfNestedType``1(N.GenericType{System.Int32}.NestedType)- generic type with one parameterM:N.X.N#IX{N#KVP{System#String,System#Int32}}#IXA(N.KVP{System.String,System.Int32})- explicit interface implementationE:prefix for eventsE:N.X.d.F:prefix for fieldsF:N.X.q- fieldP:prefix for propertiesP:N.X.prop- property with getter and setterSupported scenarios:
The following are out of scope for this 1st implementation:
Next steps:
IStreamingFindUsagesPresenterwhen we can't distinguish which exact method/function to go to.