introduction to roslyn

58
Introduction to Roslyn 2014年5月31日 プログラミング生放送勉強会 第28回@東北大学 @bonprosoft 1

Upload: yuki-igarashi

Post on 19-Aug-2014

447 views

Category:

Engineering


2 download

DESCRIPTION

プログラミング生放送勉強会 第28回@東北大学で発表した資料です。 間違い等も多くあるかと思いますので、その際はご指摘いただければと思います。

TRANSCRIPT

Introduction to Roslyn2014年5月31日 プログラミング生放送勉強会 第28回@東北大学

@bonprosoft

1

自己紹介2

自己紹介• Twitter: @bonprosoft (ぼんぷろ)

• 東北大学工学部の0x13歳

• 自然言語処理系の研究室でアルバイト中

• Microsoft Student Partners Fellow

3

Microsoft Student Partners• Microsoft関連の技術を広めたい学生の集まり

• テクニカル職はもちろんマーケティング職もあります

http://www.microsoft.com/ja-jp/education/msp.aspx

4

Roslynとは5

IS THE COMPILER A BLACK BOX?• 既存のコンパイラはブラックボックス

基本的に出力は成果物(アセンブリ)のみ

途中で生成されたものはアセンブリ出力とともに消去

6

IS THE COMPILER A BLACK BOX?

7

IS THE COMPILER A BLACK BOX?

8

リアルタイムエラー分析

Syntax Highlighting

And more …

IntelliSense(コード補間)

IS THE COMPILER A BLACK BOX?• IDEはコードに関する深い知識が必要

• 知識を得るためには、それぞれがコード解析のためのコードを書く必要がある コンパイラ側と仕様を合わせる必要あり

そもそも解析器は本当に2つ以上必要?

9

コンパイラを1つに• ならコンパイラを1つにまとめよう

• コードに対してコンパイラだけが持つ情報を、APIとして提供できる基盤

Roslyn

10

11

Class

Field

public Foo

private

string

X

CompilerCompilerSource codeSource code

Source

File

Source codeSource code

.NET

Assembly

Meta-programming Read-Eval-Print Loop

Language

Object ModelDSL Embedding

「BUILD 2011 TOOL-816T: Future directions for C# and Visual Basic」より

Roslynの利用例• 以下のサイトにアクセス

http://vsshare.azurewebsites.net/

12

Roslynの利用例• Visual Studioの拡張機能でコードを取得

• Roslynを用いて色付けを行いSignalRで配信

13

Roslynの利用例

14

Server

Presenter PC

(Visual Studio)

SignalR

Visual Studio拡張機能でコード取得

↓Roslynで構文解析&意味解析

↓SignalRで結果を送信

Roslynをcloneして…

15コンパイル時に「プロ生ちゃんマジ天使!」を文字列の最後に挿入

Roslynをcloneして…

16

• FizzBuzz編

Roslynの構成17

.NETの仕様について• コンパイラはネイティブコードではなくILを生成

18

.method public static void Main() cil managed

{

.entrypoint

.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) // コード サイズ 14 (0xe)

.maxstack 8

IL_0000: nop

IL_0001: ldstr "Hello,Pronama!"

IL_0006: call void [mscorlib]System.Console::WriteLine(string)

IL_000b: nop

IL_000c: nop

IL_000d: ret

} // end of method Pronama::Main

.NETの仕様について• 自称 言語処理系「VBCPP」のEmit部分

19

構文木とは

20

Class

Field

public Foo

private

string

X

Roslynで出来ること

• コード生成

• 一部のリファクタリング etcGenerate

• 木の改変

• Code Fixや一部のリファクタリング etcTransform

• 構文/意味解析

• 意味解析 etcAnalyze

21

Roslynの設計理念• Roslynでは普遍性を基本理念としている

「あるツールが影響を与えたせいで、他のツールに危害が加わる」という状態を防ぐため

• データに変更を加える際は、基本的に一部分だけが異なるような新しいデータを作ることになる

22

Compiler APIs(Compiler Layer)

Roslynが提供するAPI

23

Compiler APIs

(Scripting APIs)

Workspaces APIs(Services Layer)

Features APIs(Editor Services Layer)

Compiler APIs(Compiler Layer)

Roslynが提供するAPI

24

Compiler APIs

(Scripting APIs)

Workspaces APIs(Services Layer)

Features APIs(Editor Services Layer)

Compiler APIs• 主にコンパイラに関するAPIを提供

• 主に3層に分かれている コア部分

言語別部分

(フロント部分)

25

Compiler APIs• コア部分

Microsoft.CodeAnalysis.dll

言語特有でない、すべての編集・解析プロセスを含む

Emit APIや、Syntax Tree APIの基本的・抽象的な構造、及び(拡張)メソッドを持つ

26

Compiler APIs• 言語別部分

Microsoft.CodeAnalysis.VisualBasic.dll

Microsoft.CodeAnalysis.CSharp.dll

コア部分を継承し、言語毎のパーサーや解析ロジックを持つ

実際にコードをコンパイルするときに呼び出される

27

Compiler APIs• フロント部分

rcsc.exeやrvbc.exe (Roslyn版コンパイラ) 、そしてVBCSCompiler.exeを含む

ここではコマンドラインをパースして先ほどまでのレイヤーを呼ぶだけ

28

Compiler APIs• デモ

コンパイラAPIを用いて何か作ってみましょう

29

Compiler APIs Demo1 (追記)

• 単純な構文のみを検証するプログラム

30

Dim tree = VisualBasicSyntaxTree.ParseText(code)

Dim errors As New List(Of ErrorItem)

For Each item In tree.GetDiagnostics

errors.Add(New ErrorItem With {.Message = item.GetMessage,

.Location = item.Location.SourceSpan.ToString,

.Id = item.Id,

.Severity = item.Severity.ToString})

Next

Compiler APIs Demo1 (追記)

• 実行結果

31

Compiler APIs Demo1 (追記)

• 実行結果に関して 単純に構文のエラーは解析できる

変数名の重複や存在しない名前(型やメソッド等)を入力しても通ってしまう

32

Compiler APIs Demo2 (追記)

• Semantic Analysisを用いて、意味も検証する

33

Dim tree = VisualBasicSyntaxTree.ParseText(code)

Dim compilation = VisualBasicCompilation.Create("pronama",

{tree},

{New MetadataFileReference(GetType(Object).Assembly.Location)})

Dim errors As New List(Of ErrorItem)

For Each item In compilation.GetDiagnostics

errors.Add(New ErrorItem With {.Message = item.GetMessage,

.Location = item.Location.SourceSpan.ToString,

.Id = item.Id,

.Severity = item.Severity.ToString})

Next

Compiler APIs Demo2 (追記)

• 実行結果

34

Compiler APIs Demo2 (追記)

• 実行結果に関して 構文エラーはもちろん解析可能

変数名の重複や存在しない名前(型やメソッド等)を入力したらエラーを出力してくれる

「変数が使われていない」等の警告も出力

データフロー解析(どこで変数を参照しているか等)も行える

35

Compiler APIs• Scripting APIsに関して

( https://roslyn.codeplex.com/wikipage?title=FAQ#What happened to the REPL and hosting scripting APIs より)

36

Compiler APIs(Compiler Layer)

Roslynが提供するAPI

37

Compiler APIs

(Scripting APIs)

Workspaces APIs(Services Layer)

Features APIs(Editor Services Layer)

Workspace APIs• 主にワークスペースに関するAPIを提供する

Microsoft.CodeAnalysis.Workspaces.dll

Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll

Microsoft.CodeAnalysis.CSharp.Workspaces.dll

38

Workspace APIs• プロジェクトファイルの構造や基本的なリファクタリング機能を含む プロジェクトファイル全体を把握しないとできない機能

(ex. 参照関係やすべての検索機能等)を提供

ソースコードと参照関係を含むProjectとSolutionの管理

39

Workspace APIs

40

Dim workspace = MSBuild.MSBuildWorkspace.Create()

Dim solution = Await workspace.OpenSolutionAsync(dlg.FileName)

For Each projectId In solution.ProjectIds

Dim project = solution.GetProject(projectId)

Console.WriteLine("+ Project" + vbCrLf + " FileName: {0}, Lang: {1}, Id: {2}",

project.Name, project.Language, project.Id.ToString)

For Each docId In project.DocumentIds

Dim document = project.GetDocument(docId)

Console.WriteLine("- File" + vbCrLf + " Name: {0}, Path: {1}, ID: {2}",

document.Name, document.FilePath, document.Id)

Next

Next

• ソリューションに含まれるファイルの一覧を出力

Workspace APIs

41

Dim document = project.GetDocument(project.DocumentIds(0))

Dim version = Await document.GetTextVersionAsync()

Dim text = Await document.GetTextAsync()

Console.WriteLine("Version: {0}" + vbCrLf + “Text: {1}" version.ToString , text.ToString)

old = document

Dim newDocument = Await Formatter.FormatAsync(document)

Dim diff = Await newDocument.GetTextChangesAsync(old)

version = Await newDocument.GetTextVersionAsync()

text = Await newDocument.GetTextAsync()

Console.WriteLine("Version: {0}" + vbCrLf + “Text: {1}" version.ToString , text.ToString)

For Each change In diff

Console.WriteLine("*Change* + vbCrLf + "Place: {0}" + vbCrLf +"NewText: " ,

change.Span.ToString , change.NewText)

Next

• とあるファイルの整形を行い、その整形箇所を表示

Compiler APIs(Compiler Layer)

Roslynが提供するAPI

42

Compiler APIs

(Scripting APIs)

Workspaces APIs(Services Layer)

Features APIs(Editor Services Layer)

Feature APIs• 各種リファクタリングやQuick FixなどのAPIを提供

Microsoft.CodeAnalysis.Features.dll

NuGetでは Microsoft.CodeAnalysis.CodeActions という名前

• 言語別で詳細なツールを作成することが可能

43

Code Fix

44

• VBでメソッドを呼び出す際、()をつけないと警告を出すようにするCode Fix

Feature APIs• デモ

Code Fixを作ってみます

45

Roslyn Q&A

46

DLR vs. Roslyn• Dynamic Language Runtime(動的言語ランタイム)

IronPythonやIronRubyをサポート

• DLRとRoslynは目的に違う RoslynはVisual Studio他との関わり合いを重視

DLRは動的に動的言語に言語機能を提供するための技術

47

DLR vs. Roslyn• ILの生成

DLRはSystem.Linq.Expressions 以下の式ツリーを使用

RoslynはEmit APIにより直接ILを生成している

=> パフォーマンスの向上につながる

48

DSL with Roslyn• 既存のパーサーの構文の拡張も、オープンソースに伴ってできるようになった(未確認)

• パーサーをすべて自前で用意してもよい その場合自分のパーサーでRoslynのASTを生成すればよい

49

Roslynのこれまでとこれから50

Roslynのこれまで

51

CTP

• 2011年10月

• Workspace APIとScripting API、また基本的なCompiler APIを提供

CTP2

• 2012年6月

• 匿名型やクエリ、イベント、lockステートメント他多数の言語サポート

CTP3

• 2012年9月

• LINQのサポート、遅延バインディング等

Preview

• 2014年4月

• async/awaitのサポート、次期バージョン機能の搭載

Roslynのロードマップ• Review and refine the design of the REPL window(scripting API).

• Discuss proposed language features.

• Remove the core compiler's dependency on the full .NET framework allowing the use of the Compilation data type on platforms like WinRT.

( http://roslyn.codeplex.com/wikipage?title=Roadmap&referringTitle=Documentation より抜粋)

52

Roslynを使用する際の注意点• プロジェクトファイルの構造が変わる

• IntelliSenseが遅くなる (マシンによる?)

53

Roslynが開く未来• C#/VBへの新機能実装コストが減る

すでにRoslyn End User Previewではいくつかの新機能が実装済み

どのような新機能が実装済み(予定)であるか、リストアップされている

https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation

54

Roslynが開く未来• Monoで開発が止まっていたVB.NETの歴史が再び動き出す!(かもしれない)

現在MonoはNRefactoryとMono.Csharpを使用

すでにMonoはこんなレポジトリを持っている

Roslyn Compiler - Tracks Mono Patches

https://github.com/mono/roslyn

55

Roslynが開く未来• ASP.NET vNextでのRoslyn

Roslynによるリアルタイムコンパイル

マルチプラットフォームで動く模様

56

リンク集• RoslynのダウンロードURL

http://aka.ms/roslyn

• Roslyn Source Browser

http://source.roslyn.codeplex.com/

• .NET コンパイラ プラットフォーム ("Roslyn")

http://msdn.microsoft.com/ja-JP/roslyn

57

Copyright © 2014 bonprosoft All Rights Reserved.

58