分析器能否验证名称空间是否与文件位置正确匹配

Can an analyzer validate that namespaces properly match the file location

在 C# 解决方案中命名命名空间是一种惯例,因此它们与项目的默认命名空间加上包含文件的任何子目录的名称相匹配。

例如,名为 Haddock.cs 的文件位于名为 Fish 的目录中,默认命名空间(在 VS 项目属性的第一个选项卡中)为 Lakes 那么文件应包含类似

的内容
namespace Lakes.Fish
{
    public class Haddock
    {
    }
}

StyleCop analyzers 项目包含一个很好的规则,用于验证 class 名称是否与文件名匹配。

有什么方法可以编写规则来验证名称空间名称是否正确?

您可以使用 SyntaxTreeContextTree.FilePathSyntaxTreeAction 访问文件路径。

获得路径后,您可以对其进行解析并将其与树中 NamesSpaceDeclarationSyntax 节点的所有名称的名称进行比较。

遗憾的是,我认为目前没有办法获取项目的默认命名空间。

这是我拼凑的一个快速示例,到目前为止它可以做到。命名空间路径的 processing/comparing 是基本的,可能有更好的方法,但这应该可以帮助您入门。

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