2015-09-15 31 views
6

傳統方式是在C#解決方案中命名命名空間,使其與項目的默認命名空間以及包含文件的任何子目錄的名稱匹配。分析器是否可以驗證命名空間是否與文件位置正確匹配

例如,一個名爲Haddock.cs是在一個名爲Fish目錄和默認命名空間(在該項目的屬性在VS的第一選項卡)被Lakes則該文件應該包含這樣的

StyleCop analyzers項目包含一個很好的規則,用於驗證類名是否與文件名匹配。

有沒有什麼辦法可以編寫一個規則來驗證名稱空間的名稱是否正確?

回答

5

您可以使用SyntaxTreeContext以外的Tree.FilePath訪問SyntaxTreeAction的文件路徑。

一旦你有了路徑,你就可以解析並將其與樹中NamesSpaceDeclarationSyntax節點的所有名稱進行比較。

不幸的是,我不認爲有一種方法可以在此時獲取項目的默認名稱空間。

這是一個快速樣本,我扔在一起,做到目前爲止它可以做到。處理/比較命名空間的路徑是基本的,可能有更好的方法來做到這一點,但這應該讓你開始。

public override void Initialize(AnalysisContext context) 
{ 
    context.RegisterCompilationStartAction((compilationSyntax) => 
    { 
     compilationSyntax.RegisterSyntaxTreeAction((syntaxTreeContext) => 
     { 
      var semModel = compilationSyntax.Compilation.GetSemanticModel(syntaxTreeContext.Tree); 
      var filePath = syntaxTreeContext.Tree.FilePath; 

      if (filePath == null) 
       return; 

      var namespaceNodes = syntaxTreeContext.Tree.GetRoot().DescendantNodes().OfType<NamespaceDeclarationSyntax>(); 
      var parentDirectory = System.IO.Path.GetDirectoryName(filePath); 

      // This will only work on windows and is not very robust. 
      var parentDirectoryWithDots = parentDirectory.Replace("\\", ".").ToLower(); 

      foreach (var ns in namespaceNodes) 
      { 
       var symbolInfo = semModel.GetDeclaredSymbol(ns) as INamespaceSymbol; 
       var name = symbolInfo.ToDisplayString(); 

       if (!parentDirectoryWithDots.EndsWith(name.ToLower().Trim())) 
       { 
        syntaxTreeContext.ReportDiagnostic(Diagnostic.Create(
         Rule, ns.Name.GetLocation(), parentDirectoryWithDots)); 
       } 
      } 
     }); 
    }); 
} 
+1

這不會檢查嵌套'命名空間'聲明。 – SLaks

+0

@SLaks很好的捕獲,修復。 –

+1

這仍然是錯誤的; 'ns.Name'將不包含外部塊。 – SLaks

相關問題