2014-01-12 3 views
4

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

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

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

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

+0

В зависимости от ваших целей, это может быть проще для перевода ИЛ. – zneak

+0

Правда, но мой кросс-компилятор - это чисто компилятор C# -> JS. –

ответ

3

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

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

+0

Ах, спасибо за информацию, особенно указатель на 'IteratorRewriter'; это точно так же, как вы говорите, логика, написанная вокруг API-интерфейса, отличного от syntaxtree. (на самом деле, набор классов «BoundXXX», который я надеюсь, станет публичным в будущем). –

+1

Я не думаю, что связанные узлы, вероятно, станут публичным API, так как мы захотим изменить их по мере развития компиляторов. Если вы хотите использовать кросс-компилятор, вы, вероятно, захотите написать свою собственную фазу генерации кода в компиляторе, которая возникает после фазы, которая выполняет асинхронное понижение. –

+0

@NealGafter С вами, ребята, имеющие открытый Roslyn, все может быть общедоступным API, не так ли? Отличная работа, кстати! :) – Trillian