2015-09-15 4 views
6

C#ソリューションの名前空間には、プロジェクトのデフォルトの名前空間とそれに含まれるファイルのサブディレクトリの名前を合わせるのが一般的です。アナライザは、名前空間がファイルの場所と適切に一致するかどうかを確認することができます。

例えば、Haddock.csというファイルがFishと呼ばれるディレクトリ内にあり、(VSでプロジェクトのプロパティの最初のタブで)デフォルトの名前空間がLakesそのファイルが

のようなものが含まれている必要がありありStyleCop analyzersプロジェクトには、クラス名がファイル名と一致することを検証する優れたルールが含まれています。

名前空間の名前が正しいことを確認するルールを書く方法はありますか?

答えて

5

SyntaxTreeActionからファイルパスにアクセスするには、SyntaxTreeContextTree.FilePathを使用します。

パスを取得したら、そのパスを解析し、ツリー内の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

これはネストされた 'namespace'宣言をチェックしません。 – SLaks

+0

@SLaksいいキャッチ、修正。 –

+1

これはまだ間違っています。 'ns.Name'は外側のブロックを含みません。 – SLaks

関連する問題