2017-08-25 52 views
0

我正在嘗試使代碼分析器檢查完全限定的使用語句。這個鏈接非常有用,也是我解決方案的基礎(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],但這些並不是指我使用的具體使用方法,我已經在這個頭髮上拉了幾個小時,並且非常感謝一些清晰度。

在此先感謝!

回答

2

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