Как получить тип из псевдонима с помощью автономного анализа Roslyn

Если я использую псевдоним типа в своем источнике:

using Something = DateTime;

И затем позже я обращаюсь к его членам:

var date = Something.Now;

Когда я анализирую синтаксическое дерево с помощью Roslyn, у меня будет SimpleMemberAccessExpression для Something, не зная, что это просто псевдоним для DateTime. сильный>.

Есть ли способ узнать, что Something является семантически псевдонимом? Я бы не хотел анализировать весь файл и отслеживать все псевдонимы.


person Stefano d'Antonio    schedule 16.03.2016    source источник


Ответы (1)


Чтобы получить тип члена, вам необходимо разрешить его с помощью семантической модели.

Для следующего фрагмента кода я предполагаю, что у вас есть документ или иным образом можно получить SyntaxTree и SemanticModel:

    public static async Task GetNameFromDocument(Document document)
    {
        var syntaxTree = await document.GetSyntaxTreeAsync();
        var semanticModel = await document.GetSemanticModelAsync();
        var root = syntaxTree.GetRoot();


        MemberAccessExpressionSyntax member = GetMemberAccessExpressionSyntax(root);
        if (member != null)
        {
            var firstChild = member.ChildNodes().ElementAt(0);
            var typeInfo = semanticModel.GetTypeInfo(firstChild).Type as INamedTypeSymbol;
            var typeName = typeInfo.Name;
        }
    }

    public static MemberAccessExpressionSyntax GetMemberAccessExpressionSyntax(SyntaxNode node)
    {
        return node.DescendantNodes().Where(curr => curr is MemberAccessExpressionSyntax)
            .ToList().FirstOrDefault() as MemberAccessExpressionSyntax;
    }

Вы используете SyntaxTree, чтобы найти свое выражение — как считаете нужным (поэтому вам нужно заменить GetMemberAccessExpressionSyntax) — и впоследствии можете использовать семантическую модель для разрешения типа MemberAccessExpression.

Первым дочерним элементом MemberAccessExpressionSyntax всегда должен быть доступный член, чтобы вы могли взять узел и получить его тип с помощью семантической модели. Предоставленный Type является фактическим типом, а не псевдонимом - typeName будет соответствовать DateTime.

person SJP    schedule 16.03.2016
comment
Спасибо, это выглядит именно так, как я хотел, я проверю это позже; повлияет ли это на производительность моего автономного анализатора? (Учитывая, что теперь потребуется еще и семантический анализ, а не только синтаксический). - person Stefano d'Antonio; 16.03.2016
comment
Я никогда не испытывал проблем с производительностью после получения семантической модели. Он всегда работает довольно быстро, однако я никогда явно не тестировал такой код на скорость. - person SJP; 16.03.2016
comment
Семантические модели медленнее, но если вам нужно их использовать, используйте их. Вот для чего они там! Люди слишком часто тяготеют к нашей синтаксической модели и пишут ошибки в процессе. :-) - person Jason Malinowski; 16.03.2016