в проекте Roslyn Analyzer, я хочу отметить все символы, отмеченные определенным атрибутом. Например, если символ является методом, то я хочу этот метод (или, скорее, его определение, хотя это различие не так важно, потому что дает мне то, что мне нужно), чтобы быть проверенным для этого атрибута в любом месте, где он вызывается или даже просто используется без какого-либо прямого вызова (например, в группе методов). Аналогично, я хотел бы, чтобы любые ссылки (объявление переменной, тип, тип, возвращаемый тип и т. Д.) Были проверены на определенный (именованный) тип, чтобы проверить, украшен ли этот тип соответствующим атрибутом.Обработанные символы, также имеющие доступ к SemanticModel в Roslyn
Теперь я думал, что могу просто пропустить регистрацию действия символа с помощью RegisterSymbolAction
по адресу AnalysisContext
, но дело в том, что, хотя у меня есть возможность разбить символы напрямую (без каких-либо синтаксических манипуляций), я не имеют SemanticModel
для интерпретации символов, которые я нахожу, поскольку они не относятся к типу SymbolAnalysisContext
. Это означает, что я даже не могу проверить, имеет ли атрибут правильный тип, не говоря уже о какой-либо другой связанной сравнительной операции.
Теперь, из того, что я собрал из исходного кода, семантическая модель не гарантируется, когда вызов метода обработчика, который предоставляется в RegisterSymbolAction
, вызывается для определенного символа (поскольку он может даже не иметь готовое здание еще). Говоря это, есть ли способ фактически предоставить символ (или, по крайней мере, набор встречающихся символов) и соответствующую действительную семантическую модель одновременно? То, что я пытаюсь избежать, если я могу, должно быть вынуждено пройти через синтаксическое дерево (скорее всего, полученное из SemanticModelAnalysisContext
) и интерпретировать каждый узел к его эквиваленту потенциального символа.
Я не говорю, что это неправдоподобное решение, я просто ищу потенциальную альтернативу, о которой я не знаю. Возможно, я думал о чем-то вроде строк CompilationAnalysisContext
или CodeBlockAnalysisContext
, но до сих пор мне не повезло.
Я предполагаю, что я мог бы пойти на путь 'DeclaringSyntaxReferences', но, как вы уже упоминали, частичные методы могут нанести некоторый дождь на мой парад. Кроме того, у меня возникает ощущение, что 'DeclaringSyntaxReferences' может быть не самым легким операционным действием (я мог бы ошибаться в этом), и я бы назвал его для каждого символа, с которым сталкивается анализатор. Хорошая альтернатива, хотя. Мне было бы интересно узнать, стоит ли это более эффективно, чем идти, используя синтаксическое дерево и получать символы. –
Правило большого пальца похоже, если оно не отмечено 'async', оно не должно быть слишком дорого для анализатора. 'DeclaringSyntaxReferences' в частности является свойством, которое заставляет меня думать, что мы можем ожидать хорошей производительности. – JoshVarty
Хорошо, я не заметил, что это было свойство. Я просто посмотрел как исходный код, и это не кажется таким уж плохим. Я по-прежнему оставляю вопрос открытым, чтобы узнать, есть ли у кого-нибудь еще идеи, но в противном случае я, вероятно, в конечном итоге пойду так, как вы предложили. –