Ошибка полностью метаданных пространства имен с 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], но это не относится к конкретному использованию, которое меня интересует. Я вырывал свои волосы в течение нескольких часов, и некоторая ясность была бы очень признательна.

Заранее спасибо!

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)
Другие вопросы по тегам