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 component source mapping #9672

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

jjonescz
Copy link
Contributor

@jjonescz jjonescz commented Dec 6, 2023

Fixes #7213.
Fixes #7097.

@jjonescz jjonescz marked this pull request as ready for review December 11, 2023 14:21
@jjonescz jjonescz requested review from a team as code owners December 11, 2023 14:21
{
ranges.Add(new(kind, hostDocumentIndex, length));
var mappedLength = hostDocumentEndIndex - hostDocumentStartIndex;
if (mappedLength > 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

This makes me a little nervous, as it would be surprising if spell check was the only endpoint that needed special handling of 0-length spans. eg does renaming a component error? Are there any diagnostics that could be reported on the typename, and therefore does the diagnostics endpoints have to be updated?

Copy link
Contributor Author

@jjonescz jjonescz Dec 13, 2023

Choose a reason for hiding this comment

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

I'm not sure what renaming a component should do even today (like renaming a file in VS doesn't update component type references even without this PR), but it doesn't error with this PR. Although it's probably slightly broken since in some cases (renaming type reference from C#), the .razor is updated to contain the new name at the beginning of the file. Do you know where that should be fixed?

Diagnostics on the typename (e.g., when deriving from a static class) seem to be reported just fine on the first character of the razor file (even if the file is completely empty).

Copy link
Contributor

Choose a reason for hiding this comment

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

@maryamariyan has good insight onto what renaming behavior is/should be

Copy link
Contributor

Choose a reason for hiding this comment

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

For rename initiated from a Razor file, things would go through document mapping service, and we could add a bool flag for whether we want to consider generated only mappings. Could pass in false for that in spell check too, etc.

The problem is renames initiated in C# code, which are handled entirely in Roslyn using the SpanMappingService to change where edits occur. The problem there is that sometimes we want that service to consider generated only spans, eg in Go To Def and Go To All search results, but sometimes we don't, like rename. Sadly the current API doesn't let us know what operation is happening.

Maybe we just leave it like this and see if anyone complains? We could, presumably on the tooling side, follow up with an API change in Roslyn perhaps, to add a flag to the span mapping service to indicate if the operation is going to perform an edit, or is just data retrieval.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we just leave it like this and see if anyone complains?

I don't know, I would be inclined not to break the experience like this, but it seems like a tooling's call :D

We could, presumably on the tooling side, follow up with an API change in Roslyn perhaps, to add a flag to the span mapping service to indicate if the operation is going to perform an edit, or is just data retrieval.

The alternative is I guess to first do the API change and only then merge this PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

Pulled down the branch and gave this a try, and Go To Def from a Razor file works, Go To Def from a C# file works, but then shows an error (Roslyn issue we can file once this is in), and All-In-One search navigation works, but the filename still shows the generated file:
image

The latter is presumably because there is no #line. Would it be a problem to add that in future?

All-in-all, from my testing, this PR doesn't make anything worse, and does fix a couple of gaps, so I have no problem with it going in. There might be oddities going on with rename making edits that then get overwritten or something, but it doesn't surface as any user facing problems, so its okay by me!

Copy link
Contributor Author

@jjonescz jjonescz Jan 12, 2024

Choose a reason for hiding this comment

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

Go To Def from a C# file works, but then shows an error (Roslyn issue we can file once this is in)

This is reproducible even in main, so probably an orthogonal issue. It happens when you go to def from C# to a def of a C# class that's defined in razor (like a nested class, e.g., @code { public class MyNestedClass { } } that you can reference from a C# like _ = new MyComponent.MyNestedClass();).

The latter is presumably because there is no #line. Would it be a problem to add that in future?

I will look into that, thanks.

There might be oddities going on with rename making edits that then get overwritten or something, but it doesn't surface as any user facing problems, so its okay by me!

I'm not sure if you've seen this:

  1. Have a component Test1.razor referenced from another, e.g., <LayoutView Layout="@(typeof(Test1))" />.
  2. Hit F2 on the Test1 reference in the typeof.
  3. Rename to something else, e.g., Example.
  4. Inside Test1.razor, the word Example is written
    • Obviously, the component wasn't even renamed, since the filename stayed the same.
    • Plus, bogus text was written inside the razor file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ohh, yeah. I didn't notice that because I was just renaming SurveyPrompt to SurveyPrompt1, and didn't notice that that had caused a 1 to be added to the start of the document. That's not good.

From a quick look, my suggestion for adding an element of why a span is being asked for won't work either, as it looks like Rename just uses Find All Refs to get refs to rename.

@davidwengier
Copy link
Contributor

With cohosting the current plan is to stop using any kind of span mapping service, and just rely on enhanced #line directives. We'll have to come up with another approach with that in mind, maybe after cohosting so we have the option of new Roslyn services or something.

@jjonescz jjonescz marked this pull request as draft February 28, 2024 10:00
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.

'Go to definition' doesn't work for component type name in C# Ctrl+T shows .razor.g.cs files
3 participants