Обработка обнаруженных символов, а также доступ к SemanticModel в Roslyn

в проекте Roslyn Analyzer я хочу пометить все символы, отмеченные определенным атрибутом. Например, если символ является методом, то мне нужен этот метод (точнее, его определение, хотя это различие не столь актуально, поскольку GetAttributes в любом случае дает мне то, что мне нужно) для проверки этого атрибута везде, где он вызывается или даже просто используется без какого-либо прямого вызова (например, как в группе методов). Точно так же я хотел бы, чтобы любые ссылки (объявление переменной, приведение, параметр типа, тип возвращаемого значения и т. д.) на определенный (именованный) тип проверялись, чтобы увидеть, украшен ли тип соответствующим атрибутом.

Теперь я подумал, что могу просто зарегистрировать действие символа, используя RegisterSymbolAction на AnalysisContext, но дело в том, что, хотя у меня есть возможность разбивать символы напрямую (без каких-либо синтаксических манипуляций), у меня нет SemanticModel для интерпретации найденных символов, поскольку его нет на SymbolAnalysisContext тип. Это означает, что я не могу даже проверить, имеет ли атрибут правильный тип, не говоря уже о любой другой связанной операции сравнения.

Теперь, из того, что я собрал из исходного кода, семантическая модель не гарантируется, что она будет действительной, когда вызов метода-обработчика, предоставленного RegisterSymbolAction, вызывается для определенного символа (поскольку он может быть еще даже не завершен) . При этом существует ли способ одновременно получить символ (или, по крайней мере, набор встречающихся символов) и соответствующую действительную семантическую модель? Чего я пытаюсь избежать, если я могу, так это того, чтобы быть вынужденным пройти через все синтаксическое дерево (скорее всего, полученное из SemanticModelAnalysisContext) и интерпретировать каждый узел в его потенциальном эквиваленте символа.

Я не говорю, что это неправильное решение, я просто ищу потенциальную альтернативу, о которой я не знаю. Возможно, я думал о чем-то вроде CompilationAnalysisContext или CodeBlockAnalysisContext, но пока мне не везло.


person Phil Gref    schedule 09.06.2015    source источник


Ответы (1)


Если я правильно понимаю, вы пытаетесь получить доступ к SemanticModel от SymbolAnalysisContext?

В свойстве Compilation можно использовать < a href="http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis/Compilation/Compilation.cs,53e11cf29c3c4036,references" rel="nofollow">GetSemanticModel() и передать синтаксическое дерево символ, на который вы смотрите.

private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
    var compilation = context.Compilation;
    var syntax = context.Symbol.DeclaringSyntaxReferences.First(); //Careful, partial methods might burn you
    var model = compilation.GetSemanticModel(syntax.SyntaxTree);
    //Use your model however you please!
}
person JoshVarty    schedule 09.06.2015
comment
Я думаю, что я мог бы пойти DeclaringSyntaxReferences путем, но, как вы упомянули, частичные методы могут омрачить мой парад. Кроме того, у меня есть ощущение, что DeclaringSyntaxReferences может быть не самой легкой операцией с точки зрения производительности (в этом я могу ошибаться), и я буду вызывать ее для каждого символа, с которым столкнется анализатор. Хорошая альтернатива однако. Мне было бы любопытно узнать, более ли это целесообразно, чем пройтись по синтаксическому дереву и получить символы. - person Phil Gref; 09.06.2015
comment
Эмпирическое правило заключается в том, что если он не отмечен async, он не должен быть слишком дорогим для анализатора. DeclaringSyntaxReferences, в частности, является свойством, которое наводит меня на мысль, что мы можем ожидать от него хорошей производительности. - person JoshVarty; 09.06.2015
comment
Хорошо, я не заметил, что это свойство. Я только что посмотрел исходный код, и он не кажется таким уж плохим. Я по-прежнему оставлю вопрос открытым, чтобы посмотреть, есть ли у кого-нибудь еще какие-либо идеи, но в остальном я, вероятно, в конечном итоге пойду так, как вы предложили. - person Phil Gref; 09.06.2015