-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Labels
Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.This issue involves adding, removing, clarification, or modification of an API.
Milestone
Description
Version Used:
v2.3.2
Steps to Reproduce:
Get an ISymbol for a partial method.
e.g. Console App with Microsoft.CodeAnalysis Nuget package
static void Main(string[] args)
{
var ws = new AdhocWorkspace();
var project = ws.AddProject("Ass1", LanguageNames.CSharp);
ws.AddDocument(project.Id, "DefinitionPart.cs", SourceText.From(
@"
namespace N1
{
partial class C1
{
partial void PartialM();
}
}
"));
ws.AddDocument(project.Id, "ImplementationPart.cs", SourceText.From(
@"
namespace N1
{
partial class C1
{
partial void PartialM() { }
}
}
"));
var compilation = ws.CurrentSolution.Projects.First().GetCompilationAsync().GetAwaiter().GetResult();
var methodSymbols = compilation.GetSymbolsWithName(s => s == "PartialM");
var method = methodSymbols.First() as IMethodSymbol;
Console.WriteLine($"Number of symbols : { methodSymbols.Count() }");
Console.WriteLine($"DeclaringSyntaxReferences : { method.DeclaringSyntaxReferences.Count() }");
Console.WriteLine($"DeclaringSyntaxReference.Location : { method.DeclaringSyntaxReferences.First().SyntaxTree.FilePath }");
Console.WriteLine($"Locations : { method.Locations.Count() }");
Console.WriteLine($"Location : { method.Locations.First().SourceTree.FilePath }");
Console.WriteLine($"Has PartialDefinitionPart : { method.PartialDefinitionPart != null }");
Console.WriteLine($"Has PartialImplementationPart : { method.PartialImplementationPart != null }");
Console.WriteLine($"PartialImplementationPart.Location : { method.PartialImplementationPart.Locations.First().SourceTree.FilePath }");
Console.ReadLine();
}Expected Behavior:
method.DeclaringSyntaxReferences and method.Locations contain references to both files (as does the ISymbol for class C1).
Actual Behavior:
Number of symbols : 1
DeclaringSyntaxReferences : 1
DeclaringSyntaxReference.Location : DefinitionPart.cs
Locations : 1
Location : DefinitionPart.cs
Has PartialDefinitionPart : False
Has PartialImplementationPart : True
PartialImplementationPart.Location : ImplementationPart.cs
From the documentation comment of DeclaringSyntaxReferences and Locations
.. Some Symbols (for example, partial classes) may be defined in more than one location. ..
I would expect that for partial methods the implementation and definition part would be included in the DeclaringSyntaxReferences and/or Locations collections.
It requires a cast to IMethodSymbol to get both locations and to be sure to get all locations you have to something along the lines:
var methodSymbols =
Enumerable.Repeat(method, 1)
.Union(Enumerable.Repeat(method.PartialDefinitionPart, 1)
.Union(Enumerable.Repeat(method.PartialImplementationPart, 1)))
.Where(methodSymbol => methodSymbol != null)
.Distinct(); This is hard to discover and get right as an API consumer.
It would be nice to
- Extend the documentation for
DeclaringSyntaxReferencesandLocationsto mention thePartial...Partproperties ofIMethodSymbol. - Provide an extension method to get all source code locations relevant to an ISymbol.
Copilot
Metadata
Metadata
Assignees
Labels
Area-CompilersConcept-APIThis issue involves adding, removing, clarification, or modification of an API.This issue involves adding, removing, clarification, or modification of an API.