Skip to content
This repository was archived by the owner on Aug 26, 2026. It is now read-only.

Add component debugger - #726

Merged
jmarolf merged 12 commits into
dotnet:masterfrom
chsienki:ComponentDebugger
Feb 17, 2021
Merged

jmarolf merged 12 commits into
dotnet:masterfrom
chsienki:ComponentDebugger

Conversation

@chsienki

@chsienki chsienki commented Feb 9, 2021

Copy link
Copy Markdown
Member

Adds the prototype Roslyn component debugger to the SDK.

UX

User adds <IsRoslynComponent>true</IsRoslynComponent> to their generator project file

This enables the 'Roslyn Component' debugger option in debug settings (Project Properties -> Debug)

image

A user chooses the appropriate target project

image

User F5's the generator project which starts CSC.exe/VBC.exe building the target project allowing them to debug the generator code.

Known Issues

  • Project filtering was hanging on some projects, so is disabled for now. The UI just displays all available projects as targets.
  • Localization support is missing
  • Target framework support when multi-targeting. Can we add another option?

FAQ

  1. How will this work with VSCode?
    • VSCode supports launchsettings.json so we should be able to write an equivalent VSCode extension that reads the target and does the launching

Comment thread src/VisualStudio.Roslyn.SDK/ComponentDebugger/Roslyn.ComponentDebugger.csproj Outdated
Comment thread src/VisualStudio.Roslyn.SDK/ComponentDebugger/DebugProfileProvider.cs Outdated
// PROTOTYPE: is there a way to get this other than hardcoding it?
static readonly string[] CommandLineSchemaRuleNames = new[] { "CompilerCommandLineArgs" };

public static async Task<IList<string>> GetCompilationArgumentsAsync(this ConfiguredProject project)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

📝This is a place I'd like to get the project system folks to take a look at how we're getting the value.

@chsienki

Copy link
Copy Markdown
Member Author

@mikadumont @jaredpar @jasonmalinowski @sharwell for initial review of this. The code is in a fairly good shape, but there are PROTOTYPE comments that we'll want to address before shipping.

I'd also like to get the project system folks involved as it's based on their stuff. @jjmew Can we get some of your folks to take a look at the implementation?


namespace Roslyn.ComponentDebugger
{
internal class Constants

@jaredpar jaredpar Feb 10, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
internal class Constants
internal static class Constants
``` #Resolved

Comment thread src/VisualStudio.Roslyn.SDK/ComponentDebugger/DebugProfileProvider.cs Outdated
Comment thread src/VisualStudio.Roslyn.SDK/ComponentDebugger/DebugProfileProvider.cs Outdated

@jaredpar jaredpar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Modulo getting the prototype comments shifted to point to an issue that we can trakc

- Implement token replacment for the launch settings file
- Add issues for other prototypes
@chsienki

Copy link
Copy Markdown
Member Author

Created #728, #729, #730, #731 to track remaining prototype comments

// an alternative design could be to have 'IsRoslynComponent' just define the <Capability... directly in the managed.core targets
// but that would require a specific roslyn version to work, this allows it to be backwards compatible with older SDKs
var caps = Empty.CapabilitiesSet;
if (await IsRoslynComponentAsync(this.ConfiguredProject, cancellationToken).ConfigureAwait(false))

@davkean davkean Feb 16, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is mixing dataflow and live project data, which you can't do.

You need to listen to and pull on the ProjectInstance to get the property via dataflow, here's an example: https://github.com/dotnet/project-system/blob/b7fd4c439d1d39b656d89a8b88464fabffcc8e59/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Web/ProjectTypeGuidsDataSource.cs.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@davkean Oh, interesting. There are classes in the devdiv repo that use this exact pattern. The base class seems to subscribe to events, so I figured it was designed to explicitly not need dataflow stuff.

I'll try and use the example to create a dataflow version.

@tmeschter tmeschter left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Other than working out the data flow issue, mostly looks good.

Comment thread src/VisualStudio.Roslyn.SDK/ComponentDebugger/DebugProfileProvider.cs Outdated
Ordinal comparison for debug command
more nuget
var caps = Empty.CapabilitiesSet;
if (await IsRoslynComponentAsync(this.ConfiguredProject, cancellationToken).ConfigureAwait(false))

var snapshot = await snapshotService.GetLatestVersionAsync(ConfiguredProject, cancellationToken: cancellationToken).ConfigureAwait(false);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks @davkean and @tmeschter. I switched the cap provider over to this, which is the same way the 'get command line args' stuff works. Is that a valid way to handle getting it via dataflow?

@davkean davkean Feb 17, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No. This needs to chain similar to what I pointed out here: https://github.com/dotnet/project-system/blob/feature/AspNet/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Web/ProjectTypeGuidsDataSource.cs.

These systems flow data from one data source -> another, you need to transform the data as it flows along the pipe. This code just grabs the latest version from the snapshot pipe and sets up no relationship between the pipes, so we never know to call this pipe when the data changes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

But isn't that handled by the base class? It sets up the pipe stuff and calls this method as it changes? I guess thats the bit I don't understand.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No. Here you basically saying "I am the start of a pipe, and I will tell you when there are changes". What you want to say is "My pipe is based on the snapshot data, so when it changes, call me".

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This stuff is complicated and hard to get right - I can sit down and write it with you.

@chsienki
chsienki marked this pull request as ready for review February 17, 2021 22:12
@chsienki
chsienki requested a review from a team as a code owner February 17, 2021 22:12
@jmarolf
jmarolf merged commit eb99474 into dotnet:master Feb 17, 2021
namespace Roslyn.ComponentDebugger
{
[Export(ExportContractNames.Scopes.ConfiguredProject, typeof(IProjectCapabilitiesProvider))]
[AppliesTo(ProjectCapabilities.CSharp + " | " + ProjectCapabilities.VB)]

@davkean davkean Feb 17, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This component will load for every C# and VB project, we need a better approach for this. Is there something unique about these projects?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This also loads for Shared Projects.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It can apply to any project that has the <IsRoslyComponent>true</IsRoslynComponent>. So we load the provider for all projects and add the capability to any that match that.

Is there some better way to achieve that? I mentioned in the comments we could do it via the targets, but that does require a matching roslyn version.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a targets file that it imports we can match on?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, its just a regular old csharp project.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I mentioned in the comments we could do it via the targets, but that does require a matching roslyn version.

Can you expand on what you mean by this? You mean if the project itself has a package reference to a different version of the compiler?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah. We could drop the capability provider altogether if we just added the following to the targets file

<ItemGroup Condition="'$(IsRoslynComponent)' == 'true'">
    <Capability Include="RoslynComponent">
</ItemGroup>

But anyone using an older version of the compiler via NuGet wouldn't get the capability, and be able to use it. That might be worth the tradeoff to remove some of the complexity here tho.

@davkean

davkean commented Feb 17, 2021

Copy link
Copy Markdown
Member

This got merged in without any sign off from any project-system folks, can we please undo that?

@jmarolf

jmarolf commented Feb 17, 2021

Copy link
Copy Markdown

I've reverted this change, sorry @chsienki! I think you will need to submit a new one.

@chsienki chsienki mentioned this pull request Feb 24, 2021
chsienki added a commit that referenced this pull request Mar 8, 2021
* Component Debugger 
- See #726

* Add command line data source:
- add data source to obtain command line args
- use data source in extension method
- extract out shared logic into launchsettingsmanager
- clean up VM code

* Remove capability provider
- Use targets directly instead
dibarbet pushed a commit to dotnet/roslyn that referenced this pull request Aug 18, 2026
* Component Debugger 
- See dotnet/roslyn-sdk#726

* Add command line data source:
- add data source to obtain command line args
- use data source in extension method
- extract out shared logic into launchsettingsmanager
- clean up VM code

* Remove capability provider
- Use targets directly instead
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants