Предоставляет ли Roslyn сгенерированные компилятором преобразования yield в синтаксические деревья?

Оператор yield реализуется под капотом компилятором, генерирующим класс, который реализует конечный автомат, придерживающийся IEnumerable и IEnumerator.

Учитывая Roslyn MethodDeclarationSyntax, можно создать ClassDeclarationSyntax и сгенерировать метод MoveNext, как это обычно делает компилятор. Это преобразование необходимо, если кто-то пишет кросс-компилятор, который должен поддерживать оператор yield - сначала нужно переписать код C #, чтобы не использовать оператор yield, а затем позволить кросс-компилятору взять его оттуда.

Однако ясно, что, поскольку Roslyn может компилировать код C # от начала до конца, у него должна быть логика для выполнения этого преобразования каким-либо образом, и реализовать этот алгоритм самостоятельно довольно нетривиально.

Мой вопрос: раскрыта ли эта логика таким образом, чтобы ее можно было использовать для преобразования заданного MethodDeclarationSyntax в соответствующее объявление ClassDeclarationSyntax итератора? Или он запекся на этапе Emit и поэтому недоступен при работе с SyntaxNode?


person Kirk Woll    schedule 12.01.2014    source источник
comment
В зависимости от ваших целей, может быть проще перевести IL.   -  person zneak    schedule 13.01.2014
comment
Верно, но мой кросс-компилятор - это исключительно компилятор C # - ›JS.   -  person Kirk Woll    schedule 13.01.2014


Ответы (1)


Текущие биты Roslyn обрабатывают методы итератора как часть фазы генерации кода. К сожалению, эта фаза в основном непрозрачна и использует внутреннее представление, не доступное общедоступному API. Это реализовано во внутреннем классе Roslyn.Compilers.CSharp.IteratorRewriter, если вы хотите углубиться в это.

А пока вам придется реализовать это самостоятельно. Однако команда Roslyn намекнула на ближайшее будущее обновление общедоступной CTP с существенными изменениями API, так что скрестите пальцы, и, возможно, в следующей версии будет эта функция.

person Trillian    schedule 12.01.2014
comment
Ах, спасибо за информацию, особенно за указатель на IteratorRewriter; это в точности такая, как вы говорите, логика, написанная для API без синтаксического дерева. (фактически, BoundXXX набор классов, который, я надеюсь, станет общедоступным в будущем). - person Kirk Woll; 13.01.2014
comment
Я не думаю, что связанные узлы когда-либо станут общедоступным API, поскольку мы захотим их изменять по мере развития компиляторов. Если вам нужен кросс-компилятор, вы, вероятно, захотите написать свою собственную фазу генерации кода компилятора, которая идет после фазы, которая выполняет асинхронное понижение. - person Neal Gafter; 05.04.2014
comment
@NealGafter Поскольку у вас, ребята, есть Roslyn с открытым исходным кодом, все может быть общедоступным API, верно? Кстати, отличная работа! :) - person Trillian; 05.04.2014
comment
Мы обнародовали те части, с которыми мы намеренно поддерживаем определенный уровень совместимости. Что касается остального, вы можете думать об этом как о публичном API, если хотите, но не удивляйтесь, когда он изменится из-под вас. - person Neal Gafter; 06.04.2014