Skip to content

Conversation

@TIHan
Copy link
Contributor

@TIHan TIHan commented Jan 27, 2021

This is a partial implementation that allows go-to-definition on external IL symbols by generating metadata source files; currently only generating "C#" metadata code.

This is partial, meaning that it doesn't generate a proper metadata-as-source C# file as it is missing formatting and doesn't navigate to the given symbol. We also can't do go-to-def on external "F#" symbols yet.

Roslyn has internal services that could help with the formatting, but there must be additions to F#'s external access in order to take advantage of it.

I thought about re-using Roslyn's whole metadata-as-source implementation by adding a F# external access API, but we really can't use the API as it relies on ISymbol. See here: http://sourceroslyn.io/#Microsoft.CodeAnalysis.Features/MetadataAsSource/IMetadataAsSourceFileService.cs,25

(projectInfo, documentInfo)

let DecompileCSharp (symbolFullTypeName: string, assemblyLocation: string) =
let logger = new StringBuilder();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no semicolon needed

// Try to decompile; if an exception is thrown the caller will handle it
let mutable text = decompiler.DecompileTypeAsString(fullTypeName)

text <- text + "#if false // " + Environment.NewLine
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better without mutable, use let text = text + ...

let mutable hierarchy = Unchecked.defaultof<_>
let mutable itemId = Unchecked.defaultof<_>
let mutable windowFrame = Unchecked.defaultof<_>
openDocumentService.OpenDocumentViaProject(filePath, ref VSConstants.LOGVIEWID.TextView_guid, &localServiceProvider, &hierarchy, &itemId, &windowFrame) |> ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use output tuples?

    let _, localServiceProvider, hierarchy, itemId, windowFrame = openDocumentService.OpenDocumentViaProject(filePath, ref VSConstants.LOGVIEWID.TextView_guid)

projectContext.DisplayName <- projInfo.Name
projectContext.AddSourceFile(docInfo.FilePath, sourceCodeKind = SourceCodeKind.Regular)

projInfo.MetadataReferences
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use a for loop

@cartermp
Copy link
Contributor

doesn't navigate to the given symbol

Is there a way to make this happen? We do support navigating to C# symbols in a referenced project, so in theory we might have the tools needed to navigate


SourceText.From(text)

let ShowDocument (filePath, name, serviceProvider: IServiceProvider) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: lowercase


(projectInfo, documentInfo)

let DecompileCSharp (symbolFullTypeName: string, assemblyLocation: string) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: lowercase

open ICSharpCode.Decompiler.CSharp.Transforms
open ICSharpCode.Decompiler.TypeSystem

let GenerateTemporaryCSharpDocument (asmIdentity: AssemblyIdentity, name: string, metadataReferences) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: lowercase

let! location = symbol.Locations |> Seq.tryHead
return (FSharpGoToDefinitionNavigableItem(project.GetDocument(location.SourceTree), location.SourceSpan), idRange)
let projectOpt = originDocument.Project.Solution.Projects |> Seq.tryFind (fun p -> p.AssemblyName.Equals(assembly, StringComparison.OrdinalIgnoreCase))
if projectOpt.IsSome then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

match?

@TIHan TIHan merged commit e935115 into dotnet:main Jan 29, 2021
nosami pushed a commit to xamarin/visualfsharp that referenced this pull request Jan 26, 2022
…ls (dotnet#10956)

* Initial commit

* Openining document, but incorrect project association

* Partial implementation for go-to-def of external symbols

* Feedback
@xperiandri
Copy link
Contributor

Looks like you've missed a few piece
https://developercommunity.visualstudio.com/t/F-Go-to-definition-does-not-display-a/10038353
and #11765

But at least his is great 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants