Microsoft Roslyn против CodeDom

111

Из вчерашнего пресс-релиза на InfoWorld о новом Microsoft Roslyn :

Наиболее очевидным преимуществом такого «деконструированного» компилятора является то, что он позволяет вызывать весь процесс компиляции-выполнения из приложений .Net. Хейлсберг продемонстрировал программу на C #, которая передает компилятору C # несколько фрагментов кода в виде строк; компилятор вернул результирующий ассемблерный код IL в виде объекта, который затем был передан в среду CLR для выполнения. Вуаля! Благодаря Roslyn C # получает возможность динамического языка генерировать и вызывать код во время выполнения.

Я смог сделать это с момента выпуска .NET 4, с CSharpCodeProvider.CompileAssemblyFromSourceкоторым я фактически использую в проекте ASP.Net, написанном недавно, который делает именно это - позволяет пользователю вводить код в текстовое поле, выбирать сборки / пространства имен для ссылки, а затем выполнять и отображать выходные данные этого кода на лету для тестирования кода живой среды в Windows Azure.

Является CodeDomчастью / предшественником Roslyn? В чем особенность Roslyn CodeDom?

мелламокб
источник

Ответы:

241

Отказ от ответственности : я работаю в Microsoft в команде Roslyn.

CodeDom является предшественником Roslyn, но имеет лишь незначительное родство. По сути, CodeDom - это простой и (в некоторой степени) не зависящий от языка способ создания кода, который был добавлен в .NET 1.0 для поддержки дизайнеров (а-ля WinForms). Поскольку CodeDom был попыткой предоставить унифицированную модель, которая может генерировать код на C #, VB и других языках, ему не хватает высокой точности с любым из поддерживаемых языков (поэтому вы не можете создать оператор switch с CodeDom). CSharpCodeProvider.CompileAssemblyFromSource - это просто оболочка для выполнения csc.exe.

Рослин - совсем другое животное. Это переписывание компиляторов C # и VB с нуля с использованием управляемого кода - C # в C # и VB в VB (версии csc.exe и vbc.exe, которые поставляются сегодня, написаны в собственном коде). Преимущество их создания в управляемом коде заключается в том, что пользователи могут ссылаться на настоящие компиляторы как на библиотеки из приложений .NET (оболочки не требуются).

При создании каждого компонента конвейера компилятора мы открыли публичные API сверху:

  • Парсер -> API дерева синтаксиса
  • Таблица символов / Импорт метаданных -> API символов
  • Binder -> API привязки и анализа потока
  • IL Emitter -> Emit API

Roslyn можно использовать как сложный генератор исходного кода на C # и VB, но на этом сходство с CodeDom заканчивается. API-интерфейсы Roslyn Compiler можно использовать для синтаксического анализа кода, выполнения семантического анализа, динамической компиляции и оценки кода и т. Д.

Помимо компиляторов, команда Roslyn также перестраивает функции Visual Studio C # и VB IDE поверх общедоступных API-интерфейсов компилятора. Итак, API-интерфейсы компилятора достаточно богаты, чтобы создавать инструменты времени разработки Visual Studio, такие как IntelliSense и рефакторинг Extract Method. Кроме того, на уровнях выше компилятора Roslyn предлагает услуги для анализа или преобразования данных более высокого уровня. Например, существуют службы для форматирования кода с использованием правил форматирования C # и VB или поиска всех ссылок на конкретный символ в решении.

На самом деле, у Roslyn нет одного особого преимущества перед CodeDom. Там, где CodeDom удовлетворяет очень конкретную потребность в генерации кода, Roslyn занимается всем пространством языковых инструментов, предоставляя платформу, позволяющую создавать практически любые языковые инструменты C # или VB, о которых вы можете подумать.

Дастин Кэмпбелл
источник
2
@Dustin: Будет ли Roslyn поддерживать другие языки? Например, JavaScript (.NET)?
Диего Баррос
@Dustin: Это идеально подходит для создания полноценной среды IDE, которая может обеспечить качество кода в моей организации, хотя я не вижу полной замены ручной проверки кода, но я вижу значительное повышение качества. Скоро!
Джеррик Линс Джон
Было бы здорово, если бы кто-то уже создал инструмент на основе Roslyn для преобразования кода, который использует CodeDom, в код, который использует Roslyn SyntaxFactory ... (отчасти потому, что .Net Core имеет Roslyn, но не CodeDom, и я использую библиотеку, построенную на CodeDom )
Emyr
43

CodeDom позволяет вам компилировать, но не дает вам возможности действительно получить информацию о самом коде (кроме ошибок компилятора). По сути, это черный ящик, где вы говорите «скомпилируйте это», а там написано «Мне удалось» или «Мне не удалось, вот несколько ошибок».

Roslyn позволяет вам полностью проверять и создавать код на лету. Это включает в себя такие вещи, как возможность видеть / проверять комментарии в части исходного кода, подробную информацию о полной структуре и т. Д. Вы можете просмотреть и получить все синтаксическое дерево источника, который вы передаете в Roslyn, и провести подробный анализ или преобразований на нем.

Имея полную и богатую информацию о синтаксисе, вы получаете огромный дополнительный контроль и гибкость. Так, например, работает образец, который копирует блок кода C # и вставляет его как код VB.NET. С Roslyn вы можете делать больше, чем просто компилировать - вы также можете аккуратно манипулировать самим кодом. Это должно значительно упростить создание большого количества инструментов, поскольку такие вещи, как рефакторинг, можно сделать очень просто, поскольку инструменты понимают полный синтаксис, включая метаинформацию (например, комментарии), и могут просто работать с ним напрямую.

Рид Копси
источник
12

Я вижу одно большое отличие: с CodeDom каждый раз, когда вы компилируете какой-нибудь C # или VB.NET, это происходит вне процесса. CSC.exe или VBC.exe - настоящие работники за сценой.

Если вы хотите создать службу с точки зрения архитектуры, масштабируемости, изоляции и т. Д. (Вы упомянули Azure), это не очень хорошо.

С Roslyn это в процессе.

Полагаю, это одна из причин, по которой его называют «Компилятор как услуга».

Кроме того, CodeDom - это относительно плохой API, в нем отсутствует множество функций и он не совсем актуален, поскольку был разработан в основном для поддержки автоматического создания кода дизайнерами пользовательского интерфейса Visual Studio. Я думаю, что Roslyn будет намного лучше, так как его написали ребята, которые пишут компиляторы. Я надеюсь, что это изменит ситуацию.

PS: Одно заметное отличие от CSC.exe и VBC.exe: Roslyn кажется чистым .NET (и использует CCI ).

Саймон Мурье
источник
8

Roslyn позволяет гораздо точнее контролировать весь процесс - например, вы можете проанализировать строку и даже сгенерировать дополнительный код (на лету в процессе компиляции на основе анализа) и т. Д.

CodeDom «просто использует компилятор», в то время как Roslyn - «компилятор как услуга с полным доступом к (под) частям» ... с Roslyn вы находитесь «внутри компилятора» и можете видеть, как выглядит код с точки зрения компилятора. позволяя вам изменить вещи способами, которые в настоящее время невозможны.

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

Для обзора текущего состояния Roslyn и различных уровней доступа и управления, которые он предоставляет, см. Http://msdn.microsoft.com/en-us/hh500769

ОБНОВИТЬ

Microsoft только что выпустила новый CTP с дополнительными функциями и множеством изменений / дополнений API. Подробности смотрите здесь .

Яхья
источник
1
На самом деле неправда, что вы можете использовать Roslyn для расширения C # с помощью дополнительных ключевых слов.
Дастин Кэмпбелл,
спасибо ... исправлено ... хотя и не в первом выпуске, я доволен, что это будет возможно ...
Яхия
2
@DustinCampbell, Что, если бы вы обработали любую ошибку компилятора, вызванную псевдо-ключевым словом при генерации кода?
Родрик Чепмен,
3
Вам нужно будет переписать, прежде чем передавать его компилятору. Сначала проанализируйте код с помощью ваших специальных ключевых слов. Код будет проанализирован, и, если синтаксический анализатор не сможет разобраться в нем, недопустимые ключевые слова будут отображаться как SkippedTokenTrivia в результирующем дереве. Затем определите пропущенные ключевые слова и перепишите дерево с допустимым кодом (например, переплетение АОП). Наконец, передайте новое дерево компилятору. Это определенно взлом, и его работа с будущими версиями Roslyn не гарантируется. Например, синтаксический анализатор может выдать другое дерево для поврежденного кода в будущих выпусках.
Дастин Кэмпбелл,
@DustinCampbell: а будет ли что-то, позволяющее использовать АОП в финале Roslyn? Мое переплетение Mono.Cecil INPC работает отлично, но если бы я мог написать, public notifying string Name {get;set;}это было бы еще более
круто