I am trying to make a code analyzer which checks for fully qualified using statements. This link has been incredibly helpful, and the basis for my solution (How can I get the fully qualified namespace from a using directive in Roslyn?) but I am running into a problem when I try to access the location of the symbol for the using directive. My code looks like this:
private static void AnalyzeModel(SemanticModelAnalysisContext semanticModelAnalysisContext)
{
var semanticModel = semanticModelAnalysisContext.SemanticModel;
var root = semanticModel.SyntaxTree.GetRoot();
// compare each using statement's name with its fully qualified name
foreach (var usingDirective in root.DescendantNodes().OfType<UsingDirectiveSyntax>())
{
var symbol = semanticModel.GetSymbolInfo(usingDirective.Name).Symbol;
var fullyQualifiedName = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
if (fullyQualifiedName.Contains(GlobalTag))
{
fullyQualifiedName = fullyQualifiedName.Substring(GlobalTag.Length);
}
if (usingDirective.Name.ToString() != fullyQualifiedName)
{
// for each name that is not fully qualified, produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name);
semanticModelAnalysisContext.ReportDiagnostic(diagnostic);
}
}
}
The problem is the symbol.Locations[0] only contains items in metadata, not items in source. This leads to the following error:
Assert.IsTrue failed. Test base does not currently handle diagnostics in metadata locations.
My source in my unit tests looks like this:
private const string incorrectSourceCode = @"
namespace System
{
using IO;
using Threading;
}";
Why are there no items in symbol.Locations that are in source? Is there another place I can get this location? I've tried using symbol.ContainingSymbol.Locations[0] or symbol.ContainingNamespace.Locations[0], but those are not referring to the using specific using that I am interested in. I've been pulling out my hair over this for hours, and some clarity would be very greatly appreciated.
Thanks in advance!
SymbolcontainsMetadateLocation, so if you want to seeSourceLocationjust retrieve it from the appropriateSyntaxNode:instead of