Slide 1

Slide 1 text

Language Server と喋ろう ぴざきゃっと (@pizzacat83) TSKaigi 2025

Slide 2

Slide 2 text

$whoami pizzacat83 セキュリティ診断をしてくれる AI エージェントをつくっています GMO Flatt Security ソフトウェアエンジニア 趣味: Rust でブラウザ自作

Slide 3

Slide 3 text

hoge Language Server とは

Slide 4

Slide 4 text

Language Server とは エディタの言語サポート、便利ですよね

Slide 5

Slide 5 text

Language Server とは Language Client Language Server この関数はどこで定義されてる? このファイルの n 行目 ※ LSP を使わない言語サポート Extension も存在する 言語サポートの内部

Slide 6

Slide 6 text

Language Server とは Language Client Language Server {“jsonrpc”: “2.0”, “id”: 10, “method”: “textDocument/definition”, ...} {“jsonrpc”: “2.0”, “id”: 10, “result”: ...} このプロトコルが Language Server Protocol (LSP)

Slide 7

Slide 7 text

Language Server とは オレオレプログラム (Language Client) Language Server この変数の使用箇所は? この変数はどんなプロパティある? この関数リネームして! エディタ外で色々な言語サポート機能を programmatic に呼び出すのにも使える

Slide 8

Slide 8 text

Language Server Protocol の生まれた背景 https://code.visualstudio.com/api/language-extensions/language-server-extension-guide

Slide 9

Slide 9 text

LSP の広がり https://microsoft.github.io/language-server-protocol/ implementors/tools/ https://microsoft.github.io/language-server-protocol/ implementors/servers/ 色々な Language Server 色々なエディタ

Slide 10

Slide 10 text

hoge LSP で遊んでみた

Slide 11

Slide 11 text

呼び出し 呼び出し LSP で遊んでみた 「危険なコードに到達しうる関数全列挙くん」 危険なコード Lint とかで見つける LSP 使って洗い出す

Slide 12

Slide 12 text

LSP で遊んでみた 「危険なコードに到達しうる関数全列挙くん」 危険なコード 🤔 この危険なコードは どのエンドポイントで
 使われている? セキュリティエンジニア 脆弱なコードの影響調査を支援

Slide 13

Slide 13 text

LSP で遊んでみた 「危険なコードに到達しうる関数全列挙くん」 LSP を使って作る 1つの実装で多言語をサポート! 様々な言語のアプリケーションの コードを読んでセキュリティ診断をこなす 弊社にとってうれしい性質

Slide 14

Slide 14 text

Language Server の面白そうなメソッド u コードジャンプP u 定義に移動 (textDocument/definitionw u 全ての参照を検索 (textDocument/referencesw u 呼び出し階層の表示 (callHierarchy/incomingCallsw u 名前変更 (textDocument/renamew u コード補完 (textDocument/completion)

Slide 15

Slide 15 text

hoge Language Server と喋ろう

Slide 16

Slide 16 text

Language Server と喋ろう Language Client Language Server {“jsonrpc”: “2.0”, “id”: 10, “method”: “textDocument/definition”, ...} {“jsonrpc”: “2.0”, “id”: 10, “result”: ...}

Slide 17

Slide 17 text

メッセージの種類 Language Client Language Client Language Client Language Server Language Server Language Server Request Notification Response Notification

Slide 18

Slide 18 text

LSP メッセージ例 Content-Length: 234

 { "jsonrpc": "2.0", "id" : 1, "method": "textDocument/definition", "params": { "textDocument": { "uri": "file:///path/to/code.ts" }, "position": { "line": 1, "character": 2 } } } Language Client Language Server ←HTTP っぽいヘッダ ←JSON-RPC

Slide 19

Slide 19 text

LSP メッセージ例 Content-Length: 231

 { "jsonrpc": "2.0", "id": 1, "result": { "uri": "file:///path/to/lib.ts", "range": { "start": { "line": 1, "character": 2 }, "end": { "line": 3, "character": 4 } } } } Language Client Language Server ←HTTP っぽいヘッダ ←JSON-RPC

Slide 20

Slide 20 text

Language Server の起動と通信 Language Client Language Server ./server.exe stdio cp.spawn("server.exe”, ...)

Slide 21

Slide 21 text

Language Server と喋ってみよう $ echo 'Content-Length: 63 {"jsonrpc": "2.0","id": 1,"method": "initialize","params": {}}' | ./typescript-anguage-server --stdio サーバーが反応しない… CRLF とか気をつけても動かない… そもそも Content-Length 手打ちつらい…… Language Server stdio

Slide 22

Slide 22 text

プログラムから Language Server と喋ってみよう Language Client を JS/TS で書くためのライブラリを VSCode が提4  vscode-jsonrpc: 通信まわB  vscode-languageserver-protocol: リクエスト・レスポンス型定義など (vscode-languageclient は VSCode 拡張内でのみ使えるものと思われる)

Slide 23

Slide 23 text

プログラムから Language Server と喋ってみよう (1) Language Server を起動・接続 const cp = childProcess.spawn("typescript-language- server", ["--stdio"], { stdio: ['pipe', 'pipe', 'inherit'] }); const connection = rpc.createMessageConnection( new rpc.StreamMessageReader(childProcess.stdout), new rpc.StreamMessageWriter(childProcess.stdin)); connection.listen(); 子プロセスとして起動 接続開始 標準入出力に繋ぐ

Slide 24

Slide 24 text

プログラムから Language Server と喋ってみよう (2) 初期化 await connection.sendRequest(“initialize”, { processId: process.pid, workspaceFolders: [{ uri: `file://${args.workspace}`, name: path.basename(args.workspace), }], } await connection.sendNotification(“initialized”, {}); 初期化リクエストをサーバーへ クライアントの初期化をサーバーに通知

Slide 25

Slide 25 text

プログラムから Language Server と喋ってみよう (3) ファイルを開く (フリをする) await connection.sendNotification(“textDocument/didOpen”, { textDocument: { languageId: ”typescript”, version: 1, text: fs.readFileSync(filePath, "utf-8"), uri: `file://${filePath}`, }, }); 「filePath を開いたよ。コンテンツはこれ」 これをしないと動かない…

Slide 26

Slide 26 text

プログラムから Language Server と喋ってみよう (3) Go to Definition を呼ぶ! await connection.sendRequest(“textDocument/definition”, { textDocument: { uri: `file://${filePath}` }, position: { line: 1, character: 2 }, }) Response: [{ targetRange: { start: { line: 3, character: 0 }, end: { line: 10, character: 1 } }, targetUri: 'file:///path/to/lib.ts', ...

Slide 27

Slide 27 text

Response: [{ targetRange: { start: { line: 3, character: 0 }, end: { line: 10, character: 1 } }, targetUri: 'file:///path/to/lib.ts', ... プログラムから Language Server と喋ってみよう (3) Go to Definition を呼ぶ! await connection.sendRequest(“textDocument/definition”, { textDocument: { uri: `file://${filePath}` }, position: { line: 1, character: 2 }, })

Slide 28

Slide 28 text

プログラムから Language Server と喋ってみよう L2C1にあるやつの定義は? lib.ts の L4C1〜L9C2にあるよ 言語に特化しない、「位置」でコード片を表現

Slide 29

Slide 29 text

hoge TypeScript と LSP

Slide 30

Slide 30 text

TypeScript と LSP Q. Compiler API 使えば良くない?

Slide 31

Slide 31 text

TypeScript と LSP Q. Compiler API 使えば良くない? A. JS/TS しか解析しないなら、そう思う

Slide 32

Slide 32 text

TypeScript と LSP Compiler API は JS/TS の
 詳細な解析にアクセスできる Compiler API は TS 公式だが LSP は third-party LSP は言語汎用 JS/TS 特有の概念は扱えない TS 公式は tsserver という
 別プロトコルのサーバーを提供 (third-party LSP はその wrapper)

Slide 33

Slide 33 text

TypeScript と LSP JS/TS だけ解析したい → Compiler API いろんな言語を解析したい → LSP など

Slide 34

Slide 34 text

TypeScript と LSP We’ll also be moving to the Language Server Protocol (LSP), a longstanding infrastructural work item to better align our implementation with other languages. https://devblogs.microsoft.com/typescript/typescript-native-port/ Native tsc (TypeScript 7) は LSP を採用するらしい

Slide 35

Slide 35 text

hoge AI と LSP

Slide 36

Slide 36 text

AI と LSP エンジニア AI エージェント エディタを駆使して
 ソースコードを読み書き LSP を駆使させれば
 人間のように読み書きできるかも……?? と思ったけど

Slide 37

Slide 37 text

AI と LSP LSP を叩く Coding AI Agent は知る限りない (知ってたら教えてください) 弊社 “Takumi” も LSP 入れてない それでも、けっこう賢くコードを読み書きしてくれる 現状:

Slide 38

Slide 38 text

AI と LSP AI Agent × LSP の懸念材料 i grep より重い、遅™ i 言語の枠組みを超える処理の流れを追うには使えない場合‚ i frontend-backend r i マイクロサービスr i LSP のリクエストを成功させるのはむずかし™ i textDocument/definitionを呼ぶ前にtextDocument/didOpen通知が必要とA i リクエスト失敗ばかりでかえって AI が混乱するかも…?

Slide 39

Slide 39 text

hoge まとめ

Slide 40

Slide 40 text

Language Server Protocol を喋ろう p Language Server は様々な言語サポート機能を提A p HTTP+JSON のようなものを stdio でやりとC p エディタ外から programmatic に呼び出すことも可€ p 多様な言語を扱う設計の工夫がみられる Thank you for listening!