Microsoft Roslyn vs. CodeDom


110

З вчорашнього прес-релізу в InfoWorld щодо нового Microsoft Roslyn :

Найбільш очевидною перевагою такого типу "деконструйованого" компілятора є те, що він дозволяє викликати весь процес компіляції та виконання зсередини .Net-додатків. Хейльсберг продемонстрував програму C #, яка передала кілька фрагментів коду компілятору C # у вигляді рядків; компілятор повернув отриманий код збірки IL як об'єкт, який потім був переданий для виконання загальної мови виконання (CLR). Вуаля! З Росліном C # отримує динамічну здатність мови генерувати та викликати код під час виконання.

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

Є CodeDomчастиною / попередником Росліна? У чому особлива перевага Рослін CodeDom?

Відповіді:


240

Відмова : Я працюю в Microsoft над командою Roslyn.

CodeDom є попередником Росліна, але пов'язаний лише незначно. По суті, CodeDom - це простий і (дещо) агностічний спосіб генерування коду, який був доданий в .NET 1.0 для підтримки дизайнерів (a la WinForms). Оскільки CodeDom була спробою створення уніфікованої моделі, яка може генерувати код у C #, VB та інших мовах, йому не вистачає надійності з будь-яким з мов, які він підтримує (саме тому ви не можете створити оператор переключення за допомогою CodeDom). CSharpCodeProvider.CompileAssemblyFromSource - це просто обгортка навколо виконання csc.exe.

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

Під час створення кожного компонента конвеєра компілятора ми відкрили відкриті API-вершини:

  • Парсер -> API синтаксичного дерева
  • Таблиця символів / Імпорт метаданих -> API Symbol
  • Біндер -> API прив'язки та аналізу потоків
  • IL Emitter -> Emit API

Рослін можна використовувати як складний генератор вихідних кодів C # і VB, але на цьому схожість з CodeDom закінчується. API Roslyn Compiler можна використовувати для розбору коду, виконання семантичного аналізу, динамічної компіляції та оцінки коду тощо.

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

Дійсно, не існує лише однієї особливої ​​переваги Рослін над CodeDom. Там, де CodeDom заповнив дуже конкретну потребу в генеруванні коду, Рослін вирішує весь простір мовних інструментів, надаючи рамки, що дозволяють будувати майже будь-який тип мовного інструменту C # або VB, про який ви можете придумати.


2
@Dustin: Чи підтримуватиме Рослін інші мови? JavaScript (.NET), наприклад?
Дієго Баррос

@Dustin: Це ідеально підходить для створення повного досвіду IDE, який може забезпечити якість коду в моїй організації, хоча я не бачу повної заміни огляду коду вручну, але я бачу значне підвищення якості. Скоро!
Jerric Lyns Джон

Було б чудово, якби хтось уже створив інструмент на основі Roslyn для перетворення коду, який використовує CodeDom, у код, який використовує SyntaxFactory Roslyn ... (Частково тому, що .Net Core має Roslyn, але немає CodeDom, і я використовую lib, побудований навколо CodeDom )
Емір

43

CodeDom дозволяє компілювати - але це не дає вам можливості реально отримувати інформацію про сам код (крім помилок компілятора). В основному, це чорна скринька, де ви говорите «скласти це», і на ній написано «я досяг успіху» або «я не зміг, ось деякі помилки».

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

Враховуючи повну насичену інформацію про синтаксис, ви маєте величезну кількість додаткового контролю та гнучкості. Так, наприклад, працює зразок, який копіює блок коду C # і вставляє його як код VB.NET. З Росліном ви можете зробити більше, ніж просто компілювати - ви також можете чисто маніпулювати самим кодом. Це повинно зробити багато інструментів набагато простішим у створенні, оскільки такі речі, як рефакторинг, можна зробити дуже просто, оскільки інструмент розуміє повний синтаксис, включаючи метаінформацію (як коментарі), і може просто працювати з ним безпосередньо.


12

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

Якщо ви хочете побудувати службу з точки зору архітектури, масштабованості, ізоляції тощо (ви згадуєте Azure), це не дуже добре.

З Рослін це вже в процесі роботи.

Я думаю, це одна з причин, коли вони називають це "Компілятор як послуга".

Також CodeDom є відносно бідним API, пропускає безліч функцій і насправді не є сучасним, оскільки він був розроблений здебільшого для підтримки автоматичного генерування коду дизайнерів Visual Studio UI. Я думаю, що Рослін зробить набагато краще, як це написали хлопці, які пишуть компілятори. Я сподіваюся, що це змінить значення.

PS: Одна помітна відмінність від CSC.exe і VBC.exe: Рослін, здається, чистий .NET (і використовує CCI ).


8

Рослін дозволяє набагато тонше контролювати весь процес - наприклад, ви можете проаналізувати рядок і навіть генерувати додатковий код (на ходу в процесі компіляції на основі аналізу) тощо.

CodeDom - це "просто використання компілятора", а Рослін - "компілятор як служба з повним доступом до (під) частин" ... з Росліном ви "всередині компілятора" і можете побачити, як виглядає код з точки зору компілятора що дозволяє змінити речі способами, які наразі неможливо.

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

Огляд поточного стану Рослін та різних рівнів доступу та контролю, які він забезпечує, див. На веб-сторінці http://msdn.microsoft.com/en-us/hh500769

ОНОВЛЕННЯ

Microsoft тільки що представила новий CTP з додатковими функціями та безліччю змін / доповнень API. Детальніше дивіться тут .


1
Насправді, це неправда, що ви можете використовувати Roslyn для розширення C # за допомогою додаткових ключових слів.
Дастін Кемпбелл

спасибі ... виправлено ... хоча не в першому випуску, я гадаю, що це стане можливим ...
Yahia

2
@DustinCampbell, Що робити, якщо ви обробляли будь-яку помилку компілятора, яку ключове слово псевдо викликало генерування коду?
Родрік Чапман

3
Вам потрібно буде переписати, перш ніж передавати його компілятору. Спочатку проаналізуйте код за допомогою спеціальних ключових слів. Код буде розбиратися, і, якщо аналізатор не зможе зробити з нього голови чи хвости, недійсні ключові слова відображатимуться у вигляді дерева SkippedTokenTrivia. Потім виявіть пропущені ключові слова та перепишіть дерево з дійсним кодом (наприклад, AOP ткання). Нарешті, передайте нове дерево компілятору. Це, безумовно, хак, і працювати з майбутніми версіями Roslyn не гарантовано. Наприклад, аналізатор може не створювати те саме дерево для зламаного коду в майбутніх випусках.
Дастін Кемпбелл

@DustinCampbell: але чи буде щось, що дозволить плетінню AOP у фіналі Росліна? Моє плетіння Mono.Cecil INPC працює чудово, як є, але якби я міг написати, public notifying string Name {get;set;}це було б навіть приголомшливіше
TDaver
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.