【问题标题】:Fully Qualified Namespace Metadata Error with RoslynRoslyn 的完全限定的命名空间元数据错误
【发布时间】:2018-02-03 22:20:16
【问题描述】:

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

    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],但这些并不是指我感兴趣的使用特定用途。我已经为此努力了好几个小时,非常感谢一些清晰.

提前致谢!

【问题讨论】:

    标签: c# location metadata roslyn fully-qualified-naming


    【解决方案1】:

    Symbol 包含MetadateLocation,因此如果您想查看SourceLocation,只需从相应的SyntaxNode 中检索它:

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

    而不是

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

    【讨论】:

    • 这个解决方案就像一个魅力。非常感谢你分享你的知识,你是一个善良的灵魂。 :)
    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2015-02-23
    • 2019-07-10
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2017-03-04
    相关资源
    最近更新 更多