Slide 1

Slide 1 text

Things happening before start coding with Metals ~behind the curtain of daily coding~ 2020/09/25 scala.tokyo Lightning Talk Rikito Taniguchi (tanishiking)

Slide 2

Slide 2 text

こんにちは Rikito Taniguchi (@tanishiking) - Hatena (2017/4 ~ 2020/8) full-time - Hatena (2020/10~) part-time - Grad student at Tokyo Tech (2021/4~) たまに Scala の開発支援ツールの開発を手伝ったりしてます。 This wired diagram looks like the blurred version of metals logo :)

Slide 3

Slide 3 text

Disclaimer 今回の発表はそれぞれ以下のバージョンのコードベース・仕様に基づいています。 - Metals v0.9.4 - Metals VSCode v1.9.4 - metals-languageclient v0.3.2 - Language Server Protocol v3.15

Slide 4

Slide 4 text

Useful References (other than codebase) ● Official page for Language Server Protocol ● Language Server Extension Guide | Visual Studio Code Extension API ● Integrating a new editor · Metals ● Integrating a new build tool · Metals ● A Dive into Configuring Metals · Metals ● A bloop tour for metals users ● Coursier · Pure Scala Artifact Fetching

Slide 5

Slide 5 text

What is Language Server Protocol エディタ(client)とlanguage server との通信プロトコル (ただの JSON-RPC + header) プロトコルを定めることで通信イン ターフェースの実装を各エディタ/言 語のライブラリに任せることができ る。 https://code.visualstudio.com/api/la nguage-extensions/language-server- extension-guide

Slide 6

Slide 6 text

No LSP? ● Intellij-scala / ensime など ○ intellij の backend を vim や emacs から使えないよね ○ ensime、エディタごとのサポート状況にばらつきが大きかった (クライアントの 実装が大変なので) ○ 一方インターフェースを好きに実装できるので柔軟性は高い backend が LSP を実装している場合、クライアント側の実装が小さくなり、いろんなエ ディタに展開しやすくなる。

Slide 7

Slide 7 text

LSPならエディタ側の実装は0じゃないの? ● lsp client さえあれば動くんじゃないの? ● metals-vscode (vscode) や coc-metals (vim) は何をしている? ○ javahome の確認 / java のバージョン確認 ○ エラー時のUI ○ language server の fetch / launch ○ 拡張コマンドの実装など 体験をよりよくするためのラッパー それでも従来のクライアントより実装が少ない!

Slide 8

Slide 8 text

Metals and metals-vscode ● vscode から metals を利用するときは metals-vscode という vscode plugin を使 う。 ● metals-vscode を入れた状態で scala project を開いたときに、コーディングを始 めるまでに何が起きているのか見ていきましょう。

Slide 9

Slide 9 text

metals-vscode の起動 以下の条件で metals-vscode が activate される。 ● metals-vscode の new-scala project コマンドを実行した場合 ● workspace 内に build.sbt や build.sc や src/main/scala/ が存在して、それらの ファイルが開いている場合など scala プロジェクト以外では metals-vscode が起動しない。 https://github.com/scalameta/metals-vscode/blob/master/package.json#L44-L54 https://code.visualstudio.com/api/references/activation-events

Slide 10

Slide 10 text

(metals-vscode) Fetching JAR metals vscode が起動すると (JAVA_HOMEを特定した後で) まずは metals の JAR を fetch する。 coursier fetch --ttl Inf org.scalameta:metals_2.12:0.9.4 <- metals.serverVersion で変更可 -r bintray:scalacenter/releases -r sonatype:public -r sonatype:snapshots https://github.com/scalameta/metals-languageclient/blob/51a4938d9396cef 6c2bb0fa2182b392b0fe5522b/src/fetchMetals.ts#L10-L50

Slide 11

Slide 11 text

(metals-vscode) Launching Server metals.serverProperties や JAVA_OPTS / .jvmopts で起動オプションを編集 できるよ。metals 固有の起動オプションは下のリンクを参照 https://scalameta.org/metals/docs/editors/new-editor.html#metals-serv er-properties java -Xss4m -Xms100m ( <- default ) -classpath ${metalsClasspath} scala.meta.metals.Main fetch が完了したら、取得してきた metals を起動する。

Slide 12

Slide 12 text

(metals-vscode) Initializing Server LSP ではサーバーが起動したら最初に送るのが initialize リクエスト サーバーの設定やクライアント側のcapabilitiesを送る。 ● ClientCapabilities ○ クライアント側がある機能をサポートしているか ○ この値を参考にして使えない機能を別の実装にfallbackしたり色々 ● InitializationOptions ○ metals のサーバー設定いろいろ ○ workspace/didChangeConfiguration でサーバー再起動せず更新可 ○ A Dive into Configuring Metals · Metals

Slide 13

Slide 13 text

Launching Bloop サーバーの initialize が完了したら、Metalsが以下のような機能を実現するために Build Server (e.g. Bloop) との接続を行う。 ● build / test の実行 (metalsがコンパイルを実行したりするわけじゃない!) ● diagnostics の取得 ● 外部ライブラリへの Go to Definition 実行時に、ライブラリのコード表示 Wait, what is Bloop?

Slide 14

Slide 14 text

What is Bloop (quickly) 便利な機能をたくさん備えたサーバー型のビルドツールだよ ● ビルドの並列制御 ○ compile deduplication ○ compile isolation ● bloop-cli ○ コマンドラインからビルド実行する場合はCLIを利用可 ● Build Server Protocol What is Bloop · Bloop / A bloop tour for metals users

Slide 15

Slide 15 text

Build Server Protocol language server などが、compile や test の実行などをリクエストするためのプロトコ ル。 LSP と同様に JSON-RPC で通信を行う。 Build Server Protocol · Protocol for IDEs and build tools to communicate about compile, run, test, debug and more. request compile compile errors

Slide 16

Slide 16 text

Where Bloop comes from??? metals が bloop を利用することは分かった。しかしbloopをローカルマシンにインストー ルした覚えがある人は少ないはず。 initialized 完了後、metals が bloop launcher を使って自動的に background でインス トール & 起動してくれる。 ● Launcher Reference · Bloop ● BloopServers.scala launch

Slide 17

Slide 17 text

Build Server Discovery Q. metals は常に新しい bloop server をインストールして使うの?起動済みのbloopに 接続できないの? A. 起動済みの bloop server がいたら、 bloop launcher が検知してそれを再利用してく れる。 (metals project を close しても bloop server は terminate しない) ● Build Server Discovery · Build Server Protocol ● Launcher Reference · Bloop ● https://github.com/scalameta/metals-feature-requests/issues/129

Slide 18

Slide 18 text

Importing Build Q. bloop は build や test を実行できる。build 設定はどこから取得してる? A. metals 起動時に sbt (など) から設定を export している。 from https://scalameta.org/metals/docs/editors/vscode.html

Slide 19

Slide 19 text

Importing Build ● sbt-bloop という sbt 設定を bloop の設定ファイルに書き出すプラグイン ● sbt-bloop が project/metals.sbt に追加される。 ● sbt bloopInstall が実行される。(build.sbt 等が編集されるたびにプロンプト) ● .bloop ディレクトリ以下に json の設定ファイルが生成される。 1: add sbt-bloop 2: run sbt bloopInstall 3: Dump config to .bloop

Slide 20

Slide 20 text

つまりどういうこと...? ● sbt はビルド設定を bloop 設定に変換して .bloop にダンプ ● bloop は .bloop 以下のビルド設定を利用して build / test を実行できる ● metals はその bloop を利用して diagnostics の取得などを行う ● editor は metals を使ってリッチな開発体験を得る。 sbt bloopInstall BSP LSP

Slide 21

Slide 21 text

SemanticDB の生成 ● SemanticDB は Symbol や 型情報などの semantic information を保持するデー タ構造。SemanticDB Specification · Scalameta ● metals は semanticdb を利用して go to definition などの機能を実現。 (これがないと go to definition とかが動かない) ● 通常はコンパイラプラグインを導入する必要があるが、bloop が生成してくれるの でエンドユーザーは気にする必要なし Semantic DB

Slide 22

Slide 22 text

Finally, finally, finally... ● metals-vscode が scala project を検知して ● metals server が起動して ● initialize request を server に投げ ● build server に接続し ● ビルド設定を sbt から import し ● semanticdb が生成されたら ようやくコーディング開始!!!! (本当は他にも indexing, presentation compiler thread 管理 scalafmt や mdoc のインストールなど色々起きてるけど!)

Slide 23

Slide 23 text

Takeaway from this talk ● metals でコーディングする際、裏側ではいろんなことが起きているのを metals や metals-vscode がうまく隠蔽しているよ ● metalsは 裏側で bloop を使っているよ、やりとりには BSP を使っている。 ● bloop のビルド設定は .bloop 以下にあるよ(なのでなんかおかしくなったときは .bloop を消して metals を再起動して build import するとなんか直ることが...)