Roslyn完全限定名称空间元数据错误

问题描述:

我正在尝试使代码分析器检查完全限定的使用语句。这个链接非常有用,也是我解决方案的基础(How can I get the fully qualified namespace from a using directive in Roslyn?),但是当我尝试访问using指令的符号位置时,我遇到了一个问题。我的代码如下所示:Roslyn完全限定名称空间元数据错误

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); 
      } 
     } 
    } 

的问题是symbol.Locations[0]只包含元数据项,在源没有项目。这导致了以下错误:

Assert.IsTrue failed. Test base does not currently handle diagnostics in metadata locations.

我在我的单元测试源看起来是这样的:

private const string incorrectSourceCode = @" namespace System { using IO; using Threading; }";

为什么在symbol.Locations没有项目是源?有另一个地方我可以得到这个位置?我已经尝试过使用symbol.ContainingSymbol.Locations[0]symbol.ContainingNamespace.Locations[0],但这些并不是指我使用的具体使用方法,我已经在这个头发上拉了几个小时,并且非常感谢一些清晰度。

在此先感谢!

Symbol包含MetadateLocation,所以如果你想看到SourceLocation距离适当SyntaxNode检索:中

var diagnostic = Diagnostic.Create(Rule, usingDirective.Name.GetLocation(), symbol.Name) 

代替

var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name) 
+0

该解决方案的工作就像一个魅力。非常感谢你分享你的知识,你是一个善良的灵魂。 :) – CynicalPassion63