2015-06-09 4 views
0

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

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

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

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

ответ

1

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

На собственности Compilation вы можете использовать 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! 
} 
+0

Я предполагаю, что я мог бы пойти на путь 'DeclaringSyntaxReferences', но, как вы уже упоминали, частичные методы могут нанести некоторый дождь на мой парад. Кроме того, у меня возникает ощущение, что 'DeclaringSyntaxReferences' может быть не самым легким операционным действием (я мог бы ошибаться в этом), и я бы назвал его для каждого символа, с которым сталкивается анализатор. Хорошая альтернатива, хотя. Мне было бы интересно узнать, стоит ли это более эффективно, чем идти, используя синтаксическое дерево и получать символы. –

+0

Правило большого пальца похоже, если оно не отмечено 'async', оно не должно быть слишком дорого для анализатора. 'DeclaringSyntaxReferences' в частности является свойством, которое заставляет меня думать, что мы можем ожидать хорошей производительности. – JoshVarty

+0

Хорошо, я не заметил, что это было свойство. Я просто посмотрел как исходный код, и это не кажется таким уж плохим. Я по-прежнему оставляю вопрос открытым, чтобы узнать, есть ли у кого-нибудь еще идеи, но в противном случае я, вероятно, в конечном итоге пойду так, как вы предложили. –

 Смежные вопросы

  • Нет связанных вопросов^_^