File paths in a Roslyn analyzer or source generator
In Roslyn, a SyntaxTree
represents the content of a source file. If you need to know the source file that created this SyntaxTree
, you can use the FilePath
property. This property represents the file path on the disk. But, the file path on the disk may not be what you want.
- On CI, you should use reproducible builds to get deterministic paths (
ContinuousIntegrationBuild=true
and<SourceRoot>
). In this case, the file paths used for the[CallerFilePathAttribute]
and PDB are deterministic paths that do not correspond to the disk path. Instead, it should be something starting with/_/
. - You can use the
#line
preprocessor directive to change the file path of the next line. This directive is often used by code generators. For instance, when a XAML file generates a C# file, the C# files contain#line
directives to map the original XAML node.
C#
SyntaxTree syntaxTree = ...;
// Get the actual file path on disk
syntaxTree.FilePath;
// Get the mapped file path
_ = syntaxTree.GetLocation().GetMappedLineSpan().Path;
Another useful type is SourceReferenceResolver
. You can access an instance from the Compilation
instance using compilation.Options.SourceReferenceResolver
. Note that it may be null
.
C#
static string GetDisplayPath(this SyntaxTree tree, TextSpan span, SourceReferenceResolver? resolver)
{
var mappedSpan = tree.GetMappedLineSpan(span);
if (resolver == null || mappedSpan.Path.Length == 0)
return mappedSpan.Path;
return resolver.NormalizePath(mappedSpan.Path, baseFilePath: mappedSpan.HasMappedPath ? tree.FilePath : null) ?? mappedSpan.Path;
}
If you have an IOperation
, you can get the path through the Syntax
property.
C#
IOperation operation = ...;
_ = operation.Syntax.SyntaxTree.FilePath;
If you have an ISymbol
, you can get the paths through the Locations
property.
C#
ISymbol operation = ...;
foreach (var location in symbol.Locations)
{
_ = location.SourceTree?.FilePath;
}
Do you have a question or a suggestion about this post? Contact me!
Enjoy this blog?💖 Sponsor on GitHub