Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Language Server と喋ろう – TSKaigi 2025

Language Server と喋ろう – TSKaigi 2025

TSKaigi 2025 での登壇資料です。

Avatar for pizzacat83

pizzacat83

May 22, 2025
Tweet

More Decks by pizzacat83

Other Decks in Programming

Transcript

  1. Language Server とは Language Client Language Server この関数はどこで定義されてる? このファイルの n

    行目 ※ LSP を使わない言語サポート Extension も存在する 言語サポートの内部
  2. Language Server とは Language Client Language Server {“jsonrpc”: “2.0”, “id”:

    10, “method”: “textDocument/definition”, ...} {“jsonrpc”: “2.0”, “id”: 10, “result”: ...} このプロトコルが Language Server Protocol (LSP)
  3. Language Server とは オレオレプログラム (Language Client) Language Server この変数の使用箇所は? この変数はどんなプロパティある?

    この関数リネームして! エディタ外で色々な言語サポート機能を programmatic に呼び出すのにも使える
  4. Language Server の面白そうなメソッド u コードジャンプP u 定義に移動 (textDocument/definitionw u 全ての参照を検索

    (textDocument/referencesw u 呼び出し階層の表示 (callHierarchy/incomingCallsw u 名前変更 (textDocument/renamew u コード補完 (textDocument/completion)
  5. Language Server と喋ろう Language Client Language Server {“jsonrpc”: “2.0”, “id”:

    10, “method”: “textDocument/definition”, ...} {“jsonrpc”: “2.0”, “id”: 10, “result”: ...}
  6. メッセージの種類 Language Client Language Client Language Client Language Server Language

    Server Language Server Request Notification Response Notification
  7. 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
  8. 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
  9. Language Server と喋ってみよう $ echo 'Content-Length: 63 {"jsonrpc": "2.0","id": 1,"method":

    "initialize","params": {}}' | ./typescript-anguage-server --stdio サーバーが反応しない… CRLF とか気をつけても動かない… そもそも Content-Length 手打ちつらい…… Language Server stdio
  10. プログラムから Language Server と喋ってみよう Language Client を JS/TS で書くためのライブラリを VSCode

    が提4  vscode-jsonrpc: 通信まわB  vscode-languageserver-protocol: リクエスト・レスポンス型定義など (vscode-languageclient は VSCode 拡張内でのみ使えるものと思われる)
  11. プログラムから 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(); 子プロセスとして起動 接続開始 標準入出力に繋ぐ
  12. プログラムから Language Server と喋ってみよう (2) 初期化 await connection.sendRequest(“initialize”, { processId:

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

    textDocument: { languageId: ”typescript”, version: 1, text: fs.readFileSync(filePath, "utf-8"), uri: `file://${filePath}`, }, }); 「filePath を開いたよ。コンテンツはこれ」 これをしないと動かない…
  14. プログラムから 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', ...
  15. 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 }, })
  16. TypeScript と LSP Compiler API は JS/TS の
 詳細な解析にアクセスできる Compiler

    API は TS 公式だが LSP は third-party LSP は言語汎用 JS/TS 特有の概念は扱えない TS 公式は tsserver という
 別プロトコルのサーバーを提供 (third-party LSP はその wrapper)
  17. 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 を採用するらしい
  18. AI と LSP LSP を叩く Coding AI Agent は知る限りない (知ってたら教えてください)

    弊社 “Takumi” も LSP 入れてない それでも、けっこう賢くコードを読み書きしてくれる 現状:
  19. AI と LSP AI Agent × LSP の懸念材料 i grep

    より重い、遅™ i 言語の枠組みを超える処理の流れを追うには使えない場合‚ i frontend-backend r i マイクロサービスr i LSP のリクエストを成功させるのはむずかし™ i textDocument/definitionを呼ぶ前にtextDocument/didOpen通知が必要とA i リクエスト失敗ばかりでかえって AI が混乱するかも…?
  20. Language Server Protocol を喋ろう p Language Server は様々な言語サポート機能を提A p HTTP+JSON

    のようなものを stdio でやりとC p エディタ外から programmatic に呼び出すことも可€ p 多様な言語を扱う設計の工夫がみられる Thank you for listening!