Microsoft Roslyn กับ CodeDom


111

จากข่าวประชาสัมพันธ์เมื่อวานนี้ใน InfoWorld เกี่ยวกับMicrosoft Roslynใหม่:

ข้อได้เปรียบที่ชัดเจนที่สุดของคอมไพเลอร์ "แยกโครงสร้าง" ประเภทนี้คืออนุญาตให้เรียกกระบวนการคอมไพล์ - รันทั้งหมดจากภายในแอปพลิเคชัน. Net Hejlsberg แสดงให้เห็นถึงโปรแกรม C # ที่ส่งผ่านข้อมูลโค้ดบางส่วนไปยังคอมไพเลอร์ C # เป็นสตริง คอมไพลเลอร์ส่งคืนรหัสแอสเซมบลี IL ที่เป็นผลลัพธ์เป็นอ็อบเจ็กต์ซึ่งจะถูกส่งไปยัง Common Language Runtime (CLR) เพื่อดำเนินการ โวล่า! ด้วย Roslyn C # จะเพิ่มความสามารถของภาษาแบบไดนามิกในการสร้างและเรียกใช้โค้ดในขณะรันไทม์

ฉันสามารถทำได้ตั้งแต่เปิดตัว. NET 4 CSharpCodeProvider.CompileAssemblyFromSourceซึ่งจริงๆแล้วฉันใช้ในโครงการ ASP.Net ที่เขียนเมื่อสักครู่ที่ทำเช่นนั้น - อนุญาตให้ผู้ใช้พิมพ์รหัสลงในกล่องข้อความเลือกแอสเซมบลี / เนมสเปซ เพื่ออ้างอิงจากนั้นดำเนินการและแสดงผลลัพธ์จากโค้ดนั้นได้ทันทีสำหรับการทดสอบโค้ดสภาพแวดล้อมแบบสดบน Windows Azure

เป็นCodeDomส่วนหนึ่งของ / เป็นสารตั้งต้นของ Roslyn หรือไม่? ประโยชน์พิเศษของ Roslyn CodeDomคืออะไร?

คำตอบ:


241

คำเตือน : ฉันทำงานให้กับ Microsoft ในทีม Roslyn

CodeDom เป็นสารตั้งต้นของ Roslyn แต่เกี่ยวข้องเพียงเล็กน้อยเท่านั้น โดยพื้นฐานแล้ว CodeDom เป็นวิธีที่ไม่เชื่อเรื่องพระเจ้าที่ง่ายและ (ค่อนข้าง) ภาษาในการสร้างโค้ดที่เพิ่มใน. NET 1.0 เพื่อสนับสนุนนักออกแบบ (a la WinForms) เนื่องจาก CodeDom เป็นความพยายามในการจัดหาโมเดลแบบรวมที่สามารถสร้างรหัสใน C #, VB และภาษาอื่น ๆ ได้จึงขาดความเที่ยงตรงสูงกับภาษาใด ๆ ที่รองรับ (นั่นคือเหตุผลที่คุณไม่สามารถสร้างคำสั่ง switch ด้วย CodeDom ได้) CSharpCodeProvider.CompileAssemblyFromSource เป็นเพียงเครื่องห่อหุ้มรอบการรัน csc.exe

Roslyn เป็นสัตว์ที่แตกต่างไปจากเดิมอย่างสิ้นเชิง เป็นการเขียนซ้ำของคอมไพเลอร์ C # และ VB ตั้งแต่เริ่มต้นโดยใช้รหัสที่มีการจัดการ - C # ใน C # และ VB ใน VB (เวอร์ชันของ csc.exe และ vbc.exe ที่จัดส่งในวันนี้จะเขียนด้วยรหัสดั้งเดิม) ข้อดีของการสร้างในโค้ดที่มีการจัดการคือผู้ใช้สามารถอ้างอิงคอมไพเลอร์จริงเป็นไลบรารีจากแอปพลิเคชัน. NET (ไม่จำเป็นต้องใช้ตัวห่อ)

ในขณะที่สร้างส่วนประกอบของคอมไพเลอร์ไปป์ไลน์เราได้เปิดเผย API สาธารณะที่ด้านบน:

  • Parser -> Syntax Tree API
  • Symbol Table / Metadata Import -> Symbol API
  • Binder -> Binding และ Flow Analysis APIs
  • IL Emitter -> Emit API

Roslyn สามารถใช้เป็นตัวสร้างซอร์สโค้ด C # และ VB ที่ซับซ้อนได้ แต่นั่นคือจุดสิ้นสุดของความคล้ายคลึงกับ CodeDom Roslyn Compiler API สามารถใช้เพื่อแยกวิเคราะห์โค้ดทำการวิเคราะห์เชิงความหมายรวบรวมและประเมินโค้ดแบบไดนามิก ฯลฯ

นอกเหนือจากคอมไพเลอร์แล้วทีม Roslyn ยังสร้างคุณลักษณะ Visual Studio C # และ VB IDE ขึ้นใหม่ที่ด้านบนของ API คอมไพเลอร์สาธารณะ ดังนั้น API ของคอมไพเลอร์จึงมีความสมบูรณ์เพียงพอที่จะสร้างเครื่องมือเวลาออกแบบของ Visual Studio เช่น IntelliSense และการปรับโครงสร้างวิธีแยกข้อมูล นอกจากนี้ที่เลเยอร์เหนือคอมไพเลอร์ Roslyn ยังมีบริการสำหรับการวิเคราะห์ระดับสูงขึ้นหรือการแปลงข้อมูล ตัวอย่างเช่นมีบริการสำหรับการจัดรูปแบบโค้ดโดยใช้กฎการจัดรูปแบบ C # และ VB หรือค้นหาการอ้างอิงทั้งหมดไปยังสัญลักษณ์เฉพาะภายในโซลูชัน

จริงๆแล้วRoslyn ไม่ได้มีประโยชน์พิเศษเพียงอย่างเดียวจาก CodeDom ในกรณีที่ CodeDom ตอบสนองความต้องการในการสร้างโค้ดที่เฉพาะเจาะจงมาก Roslyn กำลังจัดการกับพื้นที่เครื่องมือภาษาทั้งหมดโดยจัดเตรียมเฟรมเวิร์กเพื่อให้คุณสร้างเครื่องมือภาษา C # หรือ VB ประเภทใดก็ได้ที่คุณนึกออก


2
@ ดัสติน: Roslyn จะรองรับภาษาอื่นหรือไม่? JavaScript (.NET) เช่น?
Diego Barros

@Dustin: นี่เหมาะสำหรับการสร้างประสบการณ์ IDE ที่สมบูรณ์ซึ่งสามารถบังคับใช้คุณภาพโค้ดในองค์กรของฉันแม้ว่าฉันจะไม่เห็นการแทนที่การตรวจสอบโค้ดด้วยตนเองอย่างสมบูรณ์ แต่ฉันเห็นว่าคุณภาพเพิ่มขึ้นมาก เร็ว ๆ นี้!
Jerric Lyns John

จะดีมากถ้ามีคนสร้างเครื่องมือที่ใช้ Roslyn เพื่อแปลงโค้ดที่ใช้ CodeDom เป็นโค้ดที่ใช้ SyntaxFactory ของ Roslyn ... (ส่วนหนึ่งเป็นเพราะ. Net Core มี Roslyn แต่ไม่มี CodeDom และฉันใช้ lib ที่สร้างขึ้นจาก CodeDom )
Emyr

43

CodeDom ช่วยให้คุณสามารถคอมไพล์ได้ แต่ไม่ได้ให้ความสามารถในการรับข้อมูลเกี่ยวกับโค้ดจริงๆ (นอกเหนือจากข้อผิดพลาดของคอมไพเลอร์) โดยทั่วไปจะเป็นช่องสีดำที่คุณพูดว่า "รวบรวมสิ่งนี้" และมีข้อความว่า "ฉันประสบความสำเร็จ" หรือ "ฉันล้มเหลวนี่คือข้อผิดพลาดบางประการ"

Roslyn ช่วยให้คุณตรวจสอบและสร้างโค้ดได้อย่างสมบูรณ์แบบทันที ซึ่งรวมถึงสิ่งต่างๆเช่นความสามารถในการดู / ตรวจสอบความคิดเห็นภายในส่วนของซอร์สโค้ดข้อมูลโดยละเอียดเกี่ยวกับโครงสร้างทั้งหมด ฯลฯ คุณสามารถดูโครงสร้างไวยากรณ์ทั้งหมดของแหล่งที่มาที่คุณส่งผ่านไปยัง Roslyn และทำการวิเคราะห์โดยละเอียด หรือการเปลี่ยนแปลงของมัน

ด้วยข้อมูลไวยากรณ์ที่ครบถ้วนสมบูรณ์คุณจะมีการควบคุมและความยืดหยุ่นพิเศษจำนวนมาก นี่คือวิธีการทำงานของตัวอย่างที่คัดลอกบล็อกของรหัส C # และวางเป็นรหัส VB.NET ด้วย Roslyn คุณสามารถทำอะไรได้มากกว่าแค่คอมไพล์ - คุณยังสามารถจัดการโค้ดได้อย่างหมดจด สิ่งนี้ควรทำให้การสร้างเครื่องมือง่ายขึ้นมากเนื่องจากสิ่งต่างๆเช่นการปรับโครงสร้างสามารถทำได้อย่างง่ายดายเนื่องจากเครื่องมือเข้าใจไวยากรณ์ทั้งหมดรวมถึงข้อมูลเมตา (เช่นความคิดเห็น) และสามารถทำงานร่วมกับมันได้โดยตรง


12

ความแตกต่างใหญ่อย่างหนึ่งที่ฉันเห็น: ด้วย CodeDom ทุกครั้งที่คุณรวบรวม C # หรือ VB.NET บางอย่างมันเกิดขึ้นจากกระบวนการ CSC.exe หรือ VBC.exe เป็นผู้ปฏิบัติงานจริงที่อยู่เบื้องหลัง

หากคุณต้องการสร้างบริการในแง่ของสถาปัตยกรรมความสามารถในการปรับขนาดการแยกและอื่น ๆ (คุณพูดถึง Azure) สิ่งนี้ไม่ดีมาก

Roslyn อยู่ระหว่างดำเนินการ

ฉันคิดว่านี่เป็นเหตุผลหนึ่งที่พวกเขาเรียกมันว่า "Compiler as a service"

นอกจากนี้ CodeDom ยังเป็น API ที่ค่อนข้างแย่ขาดคุณสมบัติมากมายและยังไม่เป็นปัจจุบันเนื่องจากออกแบบมาเพื่อรองรับการสร้างโค้ดอัตโนมัติของนักออกแบบ Visual Studio UI เป็นส่วนใหญ่ ฉันคิดว่า Roslyn จะทำได้ดีกว่ามากเพราะเขียนโดยคนที่เขียนคอมไพเลอร์ ฉันหวังว่าจะสร้างความแตกต่าง

PS: ความแตกต่างที่น่าสังเกตอย่างหนึ่งจาก CSC.exe และ VBC.exe: Roslyn ดูเหมือนจะเป็น. NET ที่บริสุทธิ์ (และใช้CCI )


8

Roslyn ช่วยให้สามารถควบคุมกระบวนการทั้งหมดได้ละเอียดขึ้นมากตัวอย่างเช่นคุณสามารถวิเคราะห์สตริงและสร้างโค้ดเพิ่มเติมได้ (แบบทันทีภายในกระบวนการคอมไพล์ตามการวิเคราะห์) เป็นต้น

CodeDom คือ "เพียงแค่ใช้คอมไพเลอร์" ในขณะที่ Roslyn เป็น "คอมไพเลอร์เป็นบริการที่สามารถเข้าถึงส่วนย่อย (ย่อย)" ได้อย่างสมบูรณ์ ... ด้วย Roslyn คุณเป็น "ภายในคอมไพเลอร์" และสามารถดูว่าโค้ดมีลักษณะอย่างไรจากมุมมองของคอมไพเลอร์ ทำให้คุณสามารถเปลี่ยนแปลงสิ่งต่างๆในรูปแบบที่ไม่สามารถทำได้ในปัจจุบัน

ตัวอย่างเช่นคุณสามารถใช้ Roslyn เพื่อขยาย C # ซึ่งเป็นสิ่งที่มีประโยชน์มากและดีกว่าสถานะปัจจุบันของการใช้งาน AOP

สำหรับภาพรวมของสถานะ Roslyn ปัจจุบันและระดับการเข้าถึงและการควบคุมที่แตกต่างกันโปรดดูที่http://msdn.microsoft.com/en-us/hh500769

อัปเดต

Microsoft เพิ่งเปิดตัว CTP ใหม่พร้อมคุณสมบัติเพิ่มเติมและการเปลี่ยนแปลง / เพิ่มเติม API มากมาย สำหรับรายละเอียดดูที่นี่


1
จริงๆแล้วไม่เป็นความจริงที่คุณสามารถใช้ Roslyn เพื่อขยาย C # ด้วยคำหลักเพิ่มเติม
Dustin Campbell

ขอบคุณ ... แก้ไข ... แม้ว่าจะไม่ได้อยู่ในรุ่นแรก แต่ก็น่าจะเป็นไปได้ ...
Yahia

2
@DustinCampbell ถ้าคุณจัดการข้อผิดพลาดของคอมไพเลอร์ที่คีย์เวิร์ดหลอกเกิดจากการสร้างโค้ดล่ะ?
Rodrick Chapman

3
คุณต้องทำการเขียนใหม่ก่อนที่จะส่งไปยังคอมไพเลอร์ ขั้นแรกให้แยกวิเคราะห์รหัสด้วยคำหลักพิเศษของคุณ รหัสจะแยกวิเคราะห์และเว้นแต่ตัวแยกวิเคราะห์จะไม่สามารถสร้างหัวหรือก้อยได้คำหลักที่ไม่ถูกต้องจะแสดงเป็น SkippedTokenTrivia ในโครงสร้างผลลัพธ์ จากนั้นตรวจหาคีย์เวิร์ดที่ข้ามและเขียนต้นไม้ใหม่ด้วยรหัสที่ถูกต้อง (เช่นการทอผ้า AOP) สุดท้ายส่งต้นไม้ใหม่ไปยังคอมไพเลอร์ นี่เป็นการแฮ็กอย่างแน่นอนและไม่รับประกันว่าจะใช้งานกับ Roslyn เวอร์ชันอนาคตได้ เช่นโปรแกรมแยกวิเคราะห์อาจสร้างโครงสร้างเดียวกันสำหรับโค้ดที่ใช้งานไม่ได้ในรุ่นต่อ ๆ ไป
Dustin Campbell

@DustinCampbell: แต่จะมีบางสิ่งที่อนุญาตให้ทอ AOP ใน Roslyn รอบชิงชนะเลิศหรือไม่? การทอผ้า Mono.Cecil INPC ของฉันทำงานได้ดีเหมือนเดิม แต่ถ้าฉันเขียนได้public notifying string Name {get;set;}มันจะเจ๋งกว่านี้
TDaver
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.