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

Expected behavior for Go To Definition for metadata references #24349

Open
sharwell opened this issue Jan 19, 2018 · 84 comments
Open

Expected behavior for Go To Definition for metadata references #24349

sharwell opened this issue Jan 19, 2018 · 84 comments

Comments

@sharwell
Copy link
Member

sharwell commented Jan 19, 2018

The Navigate to Decompiled Sources feature recently added is the first step towards a better F12 experience. This issue describes the more complete picture for how this experience should eventually look.

🔗 AB#624702

⚠️ This workflow is currently just a draft

  1. Start with the metadata reference
  2. Locate the correct runtime assembly from the metadata reference (accounting for execution environment and assembly binding redirection)
  3. Locate the symbols for the runtime assembly
  4. Using the symbol file and/or symbol server, locate the original source file(s) for the symbol getting decompiled
  5. If step 3 or 4 fails, decompile the symbol from the runtime assembly using ILSpy
  6. If step 2 fails, attempt steps 3-5 using the metadata reference instead of the runtime assembly
  7. Otherwise, don't attempt to decompile
@sharwell
Copy link
Member Author

@tmat
Copy link
Member

tmat commented Jan 19, 2018

A few comments:

  • I think we should first determine if we can find the original source locally - in the PDB (embedded), in debugger source cache, etc. If we can we should display it.
  • Otherwise, we should use the current Metadata As Source implementation that only displays signatures and doc comments. The benefit is that you don't need to agree to anything legal at that point and it's fast. Based on my personal experience in most cases I just want to see the signatures of the public APIs and doc comments.
  • Then we should have 2 gestures (like expanding a collapsed method body or buttons in gold bar etc.):
    1. One that triggers symbol and source resolution from symbol servers.
    2. One that runs disassembly.

@sharwell
Copy link
Member Author

I think we should first determine if we can find the original source locally - in the PDB (embedded), in debugger source cache, etc.

This is step 4 of the original workflow.

Otherwise, we should use the current Metadata As Source implementation that only displays signatures and doc comments. The benefit is that you don't need to agree to anything legal at that point and it's fast.

This is a somewhat orthogonal discussion (if/how to trigger Go To Definition separately from "Show Signatures"). Given the decompiler is currently only enabled at the explicit request of a developer, I believe it's reasonable to assume that the use of ILSpy in these cases is the desired behavior.

@Shayan-To
Copy link

I would love to see this. If this feature is implemented in sync with SourceLink, it can make debugging libraries so so much easier.

Now, if you want to put a break-point inside a class, you have to find a path of step-into's that lead to the source file to be opened. Then, you can put you break-point and see how the code works.

In fact, finding the "path of step-into's" can be very tricky, as the assemblies are optimized. I once spent nearly 4-5 hours and couldn't find the source of my problem. Then I switched to using ILSpy and I found it in less than an hour. And I was just disappointed that I couldn't put a break-point there and see the code live and in action.

@athinboy
Copy link

athinboy commented Nov 22, 2018

Is true! Is true:

I support this:

dotnet/sourcelink#169

"
@ctaggart Yes, we need a tool that navigates directly to the source in the IDE so that we can analyze the underlying implementation and debug the current code directly at run time.
@chuckries Java in the IDE to download the source code, can be directly in the current project to view the source code, such as the JDK source code, observe these implementations, can improve their development capabilities, and. NET to view the source code is complex, we need to use the Anti-compilation tool (Ilspy) or from git to get the source code

I think it has a positive effect on the development of the community and can benefit more. NET Developers
"

https://github.com/dotnet/sourcelink

@athinboy
Copy link

I think the people of dotnet foundation are "stand still and refuse to make progress ", they don't and wouldn't to think about why more and more .net programmer turn to Java!

@oliverjanik
Copy link

Is there any progress on this? Resharper has had this for a decade now.

This is extremely useful functionality, for quickly verifying assumptions instead of scouring the internet for source files and documentation!

@jogibear9988
Copy link

isnt dnspy the right tool for the debugging? https://github.com/0xd4d/dnSpy

@gautelo
Copy link

gautelo commented Apr 7, 2019

@oliverjanik I agree. Visual Studio is getting to a point where I almost don't need resharper anymore. With IntelisenseExtender (which btw, should also be a standard option), this is basically the only thing I really need to be able to move to a leaner non-resharper world.

When you've split your business code across several nuget packages with interdependencies, this sort of support is a pretty vital analysis feature, so I hope this will get some more attention soon.

Wish I could help, but I'm way too scared of anything this close to metal. ;)

@jinujoseph jinujoseph moved this from Priority 1 to Planned in IDE: InternalPriority Apr 23, 2019
@zippy72
Copy link

zippy72 commented Oct 4, 2022

Is there any way to turn off all source view / decompilation? Personally I find the metadata is usually what I'm looking for

@KieranDevvs
Copy link

Is there any way to turn off all source view / decompilation? Personally I find the metadata is usually what I'm looking for

You get the metadata with the decompilation, you can use CTRL + M + O within VS to collapse everything so you just get the method signatures and attributes on screen.

@CyrusNajmabadi
Copy link
Member

Yes, disable the first two of these:

image

@CyrusNajmabadi
Copy link
Member

@sharwell with decompilatino and source-link, do we need anything else here?

@TFTomSun
Copy link

@CyrusNajmabadi
Is there already a possibility to authenticate in an enterprise network to resolve the source link sources?

@davidwengier
Copy link
Contributor

Is there already a possibility to authenticate in an enterprise network to resolve the source link sources?

That would be a question that hopefully @chuckries can answer.

@chuckries
Copy link
Contributor

@TFTomSun It depends.

  1. There is not currently an interactive auth mechanism for F12. You could possibly authenticate through the External Sources Node
  2. What exactly do you mean by "enterprise network"? Where are your repositories hosted?

@TFTomSun
Copy link

TFTomSun commented Nov 1, 2022

@chuckries The sources are hosted on an on premise gitlab instance. To reach that instance via https you need to authorize via 2FA. In the past Visual Studio had a built in browser window. Some people with on premise gitlab instances reported that it was possible to do the 2FA there to make source link work. I never tried it. The browser window was removed with VS2022.

Anyways, you would always have the same problem, if you are working with private repositories, even on public git instances. There should be a solution to reach the private source files, for developers who are authorized.

@TFTomSun
Copy link

TFTomSun commented Nov 1, 2022

@chuckries Can you explain a bit more how I could authenticate for such scenarios via an external source node?

@cjmld5
Copy link

cjmld5 commented Sep 6, 2023

for about four years,it seems things still not resolved on VS17.7.2
for example :
0:turn on the enable navigation to source link or decompile
1:create a new project with net 6.0
2:F12 to view the net6.0 source code
image

it seems source link and inner ilspy decompile dont works as well,all we got is the metadata not the source code
for such a mount of time,should we could think make it eaiser and reduce the complex:
remove the view to metadata,and just decompile the source code through F12 and make it works on edit mode and debugger mode?

on the other side:jetbrains resharper is really good,they really thinks about the developers

@CyrusNajmabadi
Copy link
Member

@cjmld5 prs welcome.

@zhyy2008z
Copy link

for about four years,it seems things still not resolved on VS17.7.2 for example : 0:turn on the enable navigation to source link or decompile 1:create a new project with net 6.0 2:F12 to view the net6.0 source code image

it seems source link and inner ilspy decompile dont works as well,all we got is the metadata not the source code for such a mount of time,should we could think make it eaiser and reduce the complex: remove the view to metadata,and just decompile the source code through F12 and make it works on edit mode and debugger mode?

on the other side:jetbrains resharper is really good,they really thinks about the developers

It may be due to GFW, try jailbreaking it. I can see the source link normally work here.
image

@cjmld5
Copy link

cjmld5 commented Sep 8, 2023

for about four years,it seems things still not resolved on VS17.7.2 for example : 0:turn on the enable navigation to source link or decompile 1:create a new project with net 6.0 2:F12 to view the net6.0 source code image
it seems source link and inner ilspy decompile dont works as well,all we got is the metadata not the source code for such a mount of time,should we could think make it eaiser and reduce the complex: remove the view to metadata,and just decompile the source code through F12 and make it works on edit mode and debugger mode?
on the other side:jetbrains resharper is really good,they really thinks about the developers

It may be due to GFW, try jailbreaking it. I can see the source link normally work here. image

@zhyy2008z if due to the GFW,i mean,the inner ILSpy should also works as well,but it seems not work and fallback to the view of metadata

@davidwengier
Copy link
Contributor

davidwengier commented Sep 8, 2023

Whats GFW?

The reason for the lack of real source in your situation is likely due to targeting .NET 6, but using a later SDK. In that case your projects are probably referencing nuget packages that literally do not contain any code, or SourceLink information, so there is nothing that Roslyn can use to find the right code. At runtime you'll roll forward and use whatever SDK is installed based on various rules and logic in the SDK resolvers, but Roslyn does not have that logic or information. We made it a little smarter, and it has some logic to pull the real info from SDK targetting packs, and nuget packages that contain both reference and implementation assemblies, but it doesn't cover all scenarios.

There is probably a little bit of input in the Output window, the "Navigate to External Sources" category, that could validate my guess here.

@zhyy2008z
Copy link

for about four years,it seems things still not resolved on VS17.7.2 for example : 0:turn on the enable navigation to source link or decompile 1:create a new project with net 6.0 2:F12 to view the net6.0 source code image
it seems source link and inner ilspy decompile dont works as well,all we got is the metadata not the source code for such a mount of time,should we could think make it eaiser and reduce the complex: remove the view to metadata,and just decompile the source code through F12 and make it works on edit mode and debugger mode?
on the other side:jetbrains resharper is really good,they really thinks about the developers

It may be due to GFW, try jailbreaking it. I can see the source link normally work here. image

@zhyy2008z if due to the GFW,i mean,the inner ILSpy should also works as well,but it seems not work and fallback to the view of metadata

Without GFW, you can use the source link, that's what I found! Please forgive me for not mentioning inner ILSpy, I haven't looked into it.

@KieranDevvs
Copy link

KieranDevvs commented Sep 8, 2023

Whats GFW?

@davidwengier With the users appearing to be from Asia, I my guess would be GFW stands for "The Great Firewall". Basically China blocking western servers? I also assume Jailbreaking is referring to bypassing the firewall in some way.

@cjmld5
Copy link

cjmld5 commented Sep 9, 2023

Whats GFW?

The reason for the lack of real source in your situation is likely due to targeting .NET 6, but using a later SDK. In that case your projects are probably referencing nuget packages that literally do not contain any code, or SourceLink information, so there is nothing that Roslyn can use to find the right code. At runtime you'll roll forward and use whatever SDK is installed based on various rules and logic in the SDK resolvers, but Roslyn does not have that logic or information. We made it a little smarter, and it has some logic to pull the real info from SDK targetting packs, and nuget packages that contain both reference and implementation assemblies, but it doesn't cover all scenarios.

There is probably a little bit of input in the Output window, the "Navigate to External Sources" category, that could validate my guess here.

i see then output window,and sometime it says

1: timeout of downloading from pdb server,
2: timeout of downloading from SourceLink,
3: cant find pdb from sysbol server
4: cant find document infomation in the pdb

and each case can not fallback to the inner ILSpy
i think should we could put inner ILSpy before metaview? or in some error like network errors,ILSPY can decompile it ,and the metaview to be the laststep?

@zhyy2008z
Copy link

VS 2022 17.7.3 built-in ilspy's version is too old, about two years ago. May be it cann't work well with reference assemblies?

image

@CyrusNajmabadi
Copy link
Member

We updated to 8.1 here: https://github.com/dotnet/roslyn/pull/69772/files

@davidwengier
Copy link
Contributor

Reference assemblies don't have IL that can be decompiled into useful code. If the downloads timeout, we fall back to decompilatuon if we can, and only if that fails do we use metadata. Also if a download timeout, we stop making you wait, but continue the download in the background, so a future attempt to go to something from that same assembly could succeed.

@dgrunwald
Copy link

It's Roslyn that provides the list of assemblies that the decompiler should load; the decompiler engine doesn't pick files by itself.
If VS ends up uselessly decompiling references assemblies, that's a problem in Roslyn.

@CyrusNajmabadi
Copy link
Member

@dgrunwald prs welcome :-)

@KieranDevvs

This comment was marked as off-topic.

@davidwengier
Copy link
Contributor

If VS ends up uselessly decompiling references assemblies, that's a problem in Roslyn.

To be very clear here: The decompiler is doing nothing wrong, and VS doesn't "end up uselessly decompiling references assemblies". Roslyn is smart enough to know if something is a reference assembly, and in those cases we don't bother calling the decompiler. ILSpy is a wonderful piece of software.

The problem here, as I've written in many comments in this thread, is that we don't have a way of finding the implementation assemblies, and in some cases its entirely possible that the implementation assemblies do not exist on the users machine at all. From a Roslyn point of view as the code is currently written, if a user asks to Go To Definition for a method in .NET 6, then that is what we will try to do. Rolling forward to .NET 8 might happen at runtime on that machine, but its not the code being referenced by that project, so we won't show it. Relaxing that rule, and writing the logic for how to do that lookup, is what it would take to move this issue forward from the Roslyn side.

There are other approaches outside of Roslyn that could help here (see dotnet/sdk#12360 for example) but none of it is straight forward.

@zhyy2008z
Copy link

How does JetBrains Rider do it? Can we borrow anything from it?
image
image

@CyrusNajmabadi
Copy link
Member

@zhyy2008z they likely have some heuristic to do the mapping. As david mentioned, that's something that could be looked into. And we'd probably be open to PRs that help out here, if they're suitably sized and reasonable to maintain. Thanks!

@siegfriedpammer
Copy link
Contributor

siegfriedpammer commented Sep 12, 2023

@zhyy2008z There's always the option to use the logic we employ in ILSpy to find implementation assemblies. However, this means that the framework(s) in question have to be installed on the machine and it would be necessary to implement some "ask the user which assembly to use" escape hatch. In ILSpy this is done by first looking in the active assembly list for references and using them. Only if an assembly cannot be resolved from the current list, we go looking for it in the filesystem using a myriad of hacks and crutches which luckily work most of the time.

@CyrusNajmabadi Do you think it's worth the hassle implementing this feature using the code from ILSpy in VS? Ideally I would prefer to wait for an official solution from the people who designed .NET.

@CyrusNajmabadi
Copy link
Member

@CyrusNajmabadi Do you think it's worth the hassle implementing this feature using the code from ILSpy in VS? Ideally I would prefer to wait for an official solution from the people who designed .NET.

I'm fine with either.

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