Skip to content

Use LineSpan.Path instead of SourceTree?.FilePath when trimming Location#163

Open
ivarne wants to merge 1 commit intoeiriktsarpalis:mainfrom
ivarne:patch-1
Open

Use LineSpan.Path instead of SourceTree?.FilePath when trimming Location#163
ivarne wants to merge 1 commit intoeiriktsarpalis:mainfrom
ivarne:patch-1

Conversation

@ivarne
Copy link
Copy Markdown

@ivarne ivarne commented May 6, 2025

If the Location is created without referencing the SourceTree, the previous implementation of GetLocationTrimmed lost the file path resulting in diagnostic messages without clickable file paths.

This might not be relevant for this project (yet), but I'm copying the code for my own SourceGenerator and ran into this issue when adding diagnostics for AdditionalFiles where created the location using Location.Create instead of getting it from syntax.

PS: I'm pretty new to Roslyn, so I don't know whether the lineSpan always have the path, but the implementation of Location.GetDebuggerDisplay seems to indicate that it usually does.

If the Location is created without referencing the SourceTree, the previous implementation of GetLocationTrimmed lost the file path resulting in diagnostic messages without clickable files.
return Location.Create(location.SourceTree?.FilePath ?? string.Empty, location.SourceSpan, location.GetLineSpan().Span);
var lineSpan = location.GetLineSpan();

return Location.Create(lineSpan.Path ?? string.Empty, location.SourceSpan, lineSpan.Span);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The fact that diagnostics are not clickable is due to a known issue with Roslyn not supporting incremental Location values. I'm curious about your fix though, does LineSpan.Path return something different compared to SourceTree.FilePath and does that address the issue in question?

Copy link
Copy Markdown
Author

@ivarne ivarne May 7, 2025

Choose a reason for hiding this comment

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

The problem arrises when I use Location.Create before instantiating the EquatableDiagnostic, because Location.Create leaves SourceTree set to null and thus the filePath is not propagated through GetLocationTrimmed.

Eg:

new EquatableDiagnostic(
    diagnosticDescriptor,
    Location.Create(
        filePath,
        new TextSpan(startIndex, endIndex.HasValue ? endIndex.Value - startIndex : 0),
        new LinePositionSpan(
            GetLinePosition(startIndex, fileContent),
            GetLinePosition(endIndex ?? startIndex, fileContent)
        )
    )
)

the filePath i provide gets wiped out because it is stored in the span and not in the SourceTree (which is null)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I see, does this address the issue of diagnostics not being clickable though? I'm not sure that it does, because fundamentally the issue is with Location.Create producing external locations that are not clickable.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Not sure what you mean by "clickable". The important part for me is that the path I provide is visible in the terminal output. It's probably the VSCode terminal that makes the location clickable for me.

Are you talking about the diagnostic issues not showing up inline in the IDE editor?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I was referring to this issue: dotnet/runtime#92509. Generally speaking, diagnostics pointing to locations created via Location.Create suffer from issues such as them not being suppressible.

@teneko
Copy link
Copy Markdown

teneko commented Feb 16, 2026

Regarding this topic @eiriktsarpalis.. I just had a talk with 333fred (GitHub and Discord handle) and viceroypenguin (GitHub and Discord handle) that letting the location being part of the (source generator) model leads to too many model updates (and thus reaching (too) far in source generation pipeline if not even complete), and thus poses a performance issue.

According to viceroypenguin should locations only be processed by diagnostic analyzer, and thus a separate class being the diagnostics analyzer would have been introduced, viceroypenguin called it a twin generator, to report diagnostics with the result to be able to eliminate the location usage in the source generator altogether.

333fred also mentioned that you should be aware of this.

Edit: This is for informational purposes only, without any judgement on my part. 🙂

@eiriktsarpalis
Copy link
Copy Markdown
Owner

Adding @333fred for transparency.

Yep, I am aware. The nature of what triggers this particular class of source generator (changes in the structure of the transitive closure of a set of types) means that the occasional tracking of location metadata does not fundamentally alter the calculus of how frequently the generator gets triggered.

@teneko
Copy link
Copy Markdown

teneko commented Feb 22, 2026

For the references: I did not know how you leverage the source generator to make PolyType work. I did not deep dive yet into the source code. Sorry. @333fred mentioned something similiar. Regarding the tagging, I am not allowed to tag him. GitHub does not offer me the option to tag @333fred (does not appear in the list of taggable names), nor does it offer me the option to tag @viceroypenguin.

Edit: but it seems, that just writing it without the mentioned list of taggable names, it works. I'll remember that next time.

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.

3 participants