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

TypeScript LSP の今までとこれから

TypeScript LSP の今までとこれから

Avatar for Yosuke Kurami

Yosuke Kurami

June 06, 2025
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. TypeScript ͷΤσΟλαϙʔτ - Strada(TypeScript < 7) ʹ͸ tsserver ͱ͍͏ϓϩάϥϜ͕ಉࠝ͞Ε͍ͯΔ -

    ΤσΟλ (e.g. VSC, Vim, etc, ) ͸ tsserver ͱ௨৴͢Δ͜ͱͰϢʔβʔʹίʔ σΟϯάͷศརػೳΛఏڙ͍ͯ͠Δ - ίʔυิ׬, ΤϥʔνΣοΫ, Quick fi x, Organize Import, etc,,,
  2. Language Server Protocol - LSP (Language Server Protocol) : -

    MicroSoft ͕ࡦఆͨ͠ ΤσΟλ - ݴޠαʔϏεؒͷ౷ҰతͳΠϯλʔϑΣΠε - LSP ʹΑΓɺΤσΟλଆ͸ Plugin ͷ࣮૷ίετ͕֨ஈʹԼ͕Δ -41ͷͳ͍ੈք -41ͷ͋Δੈք
  3. Language Server Protocol ? - tsserver ͸ LSP Λ࣮૷͍ͯ͠ͳ͍ tsserver

    should implement the Language Server Protocol #11274 - tsserver ͸ LSP ͸࣮૷͍ͯ͠ͳ͍ (େࣄͳ͜ͱͳͷͰry tsserver should implement the Language Server Protocol #39459 - TypeScript Λ LSP Ͱѻ͏ͨΊʹ͸ɺ3rd party ੡ͷΞμϓλΛט·ͤΔ౳ ͷख͕ؒඞཁͳঢ়گ͕ଓ͍͍ͯΔ 😇
  4. LSP ͷྺ࢙ - 2015.4 ݄ʹ TypeScript 1.5-alpha Ͱ tsserver ͕ެ։͞Εͨ

    (߹Θͤͯ MS ͸ Sublime Text ޲͚ͷϓϥάΠϯ΋ϦϦʔε͍ͯ͠Δ) - ಉ࣌ظʹ C# (.NET) ͷίϛϡχςΟͰ OmniSharp ͱ͍͏ݴޠαϙʔτ͕։ൃ͞Εͨ - 2015.4 ݄ͷ Build Ͱ VSC ൃදɻ VSC Ͱ OmniSharp, tsserver ͷ૒ํʹରԠͤ͞Δ Plugin Λ։ൃ͢ΔաఔͰ LSP ͷߏ૝ ͕࢝·Δ ( https://github.com/microsoft/language-server-protocol/wiki/Protocol-History ) - 2016೥ʹ Microsoft ͕ LSP Λެ։ LSP ͷ JSON RPC ௨৴࢓༷͸ tsserver, OmniSharp ͷӨڹΛڧ͘ड͚͍ͯΔɻ ಛʹ tsserver ͸ stdio Λτϥϯεϙʔτʹ࠾༻͍ͯ͠ΔͨΊɺࠓ೔ͷ LSP ͷૅͱݴͬͯ ΋աݴͰ͸ͳ͍
  5. tsserver v.s. LSP - TypeScript ͷ LSP αϙʔτ͕ਐ·ͳ͔ͬͨཧ༝͸ҎԼ͕ߟ͑ΒΕΔ: - LSP

    ͕ tsserver / VSC ͕αϙʔτ͍ͯ͠ΔػೳΑΓ΋ශऑͩͬͨ ྫ: Diagnostic pull model ( LSP 3.17 Ͱඪ४Խ͞Εͨ) https://github.com/microsoft/TypeScript/issues/39459#issuecomment-774538570 - TypeScript ͷϝϯςφ͸ LSP ൛ͱ tsserver ͱ͍͏2ͭͷ࣮૷Λμϒϧ ϝϯς͢Δखؒ͸ආ͚͍ͨ https://github.com/microsoft/TypeScript/issues/39459#issuecomment-696179304
  6. Corsa ͱ tsserver - Corsa Ͱ͸ LSP ϕʔεͷݴޠαʔόʔΛఏڙ༧ఆ https://devblogs.microsoft.com/typescript/announcing-typescript-native-previews/#editor- support-&-lsp-progress

    - Preview ൛Ͱ΋ (ݶఆతͰ͸͋Δ͕) ར༻Մೳɻ tsc -> tsgo ͱҧ͍ɺ୯७ ͳ porting Ͱࡁ·ͣɺҠ২࡞ۀʹ͕͔͔࣌ؒΔɻStrada ͕࣋ͭେྔͷ Integration Test (௨শ Fourslash ) ΛͲ͏΍ͬͯҠߦͤ͞ΔͷʁͳͲͷ՝ ୊͸͋Δ͕ɺண࣮ʹਐΈͦ͏ https://github.com/microsoft/TypeScript/issues/61742
  7. ΋͏ͻͱͭͷ "LSP" - TypeScript ʹ͸ Language Service Plugin ͱ͍͏ػߏ͕ଘࡏ͢Δ ϢʔβʔϥϯυଆͰ

    TypeScript ͷ Language Service ͕࣋ͭϝιουͷ ॻ͖׵͕͑Մೳ - ৄ͘͠͸ @mizdra ͞Μͷ TSKaigi 2025 ൃදࢿྉΛಡΉͱΑ͍ TypeScript Language Service Plugin Ͱ CSS Module ͷ։ൃମݧΛվળ͢Δ - ࣗ෼΋ز͔ͭͷ LS Plugin Λ OSS ͱͯ͠ఏڙ͍ͯ͠ΔͨΊɺ Corsa Ͱ LS Plugin ͕Ͳ͏ͳΔ͔͸ଞਓࣄͰ͸ͳ͍ e.g. ts-graphql-plugin, eslint-typescript-language-service,
  8. LS Plugin ͷجຊ - LS Plugin ͸ tscon fi g.json

    ͷ plugins ʹهࡌ͢Δ͜ͱͰ༗ޮԽ͞ΕΔ (ҎԼ͸ ts-graphql-plugin ͷREADME ΑΓൈਮ) -
  9. Corsa ͱ LS Plugin - typescript-go ͷ discussion ʹΑΔͱ: https://github.com/microsoft/typescript-go/discussions/455#discussioncomment-12467973

    - ۩ମత͸ະఆ͕ͩɺLS ͷ Plugin ػߏͷߏ૝͸͋Δͱͷ͜ͱ - LSP ͷ JSON RPC Payload Λ Intercept ͢ΔܗͰߟ͑Ε͹͍͍ͷͰ͸ɺͱͷ͜ͱ - ԼਤͷΑ͏ͳײͩ͡Ζ͏͔ʁ (஫: ͜Ε͸ Quramy ͷໝ૝Λਤʹ͚ͨͩ͠)
  10. ίʔυϨϕϧͰߟ͑Δ - Strada (TypeScript < 7) ʹ͓͚Δ LS Plugin ͷίʔυ͸ҎԼͷΑ͏ͳܗ

    export = () => { return { create(info: ts.server.PluginCreateInfo) { const originalLs = info.languageService; return { ...originalLs, getQuickInfoAtPosition(fileName: string, pos: number) { // ݩͷ Language Service ϝιουΛ࣮ߦ const originalResult = originalLs.getQuickInfoAtPosition( fileName, pos ); // ϑΝΠϧͷ AST Λऔಘ const sourceFile = info.project.getSourceFile(fileName as ts.Path); // AST ղੳ const result = analyzeAST(sourceFile, pos); return mergeResult(originalResult, result); }, } satisfies ts.LanguageService; }, }; };
  11. ίʔυϨϕϧͰߟ͑Δ - Corsa ͷੈքͰ͸...? export = () => { return

    { create(info: ts.server.PluginCreateInfo) { const originalLs = info.languageService; return { ...originalLs, getQuickInfoAtPosition(fileName: string, pos: number) { // ݩͷ Language Service ϝιουΛ࣮ߦ const originalResult = originalLs.getQuickInfoAtPosition( fileName, pos ); // ϑΝΠϧͷ AST Λऔಘ const sourceFile = info.project.getSourceFile(fileName as ts.Path); // AST ղੳ const result = analyzeAST(sourceFile, pos); return mergeResult(originalResult, result); }, } satisfies ts.LanguageService; }, }; }; ϥοϓݩͷݴޠαʔϏεػೳͷݺͼग़͠ ຊ࣭తʹ-41ͷϨεϙϯεͱ౳Ձɻ ΠϯλʔηϓλͰஔ׵Ͱ͖ͦ͏ +4ଆͰ"45ղੳͰ͖Δ࢓૊Έ͕ඞཁ ͢ͳΘͪɺ$PSTBʹ͓͚Δ$PNQJMFS"1*Ͱ ಉ౳ͷ͜ͱ͕Ͱ͖Δͷ͔͕ϙΠϯτ 1MVHJOͷΤϯτϦํࣜ͸Θ͔Βͳ͍͕ɺ Ұ୴Ͳ͔͜Β͔/PEFKTͷϓϩηε͕ىಈ ͞ΕΔͱ૝ఆ
  12. (ิ଍) Corsa ͱ Compiler API - Compiler API ʹ͍ͭͯ͸ɺtypescript-go ʹ࠷খݶͷج൫෦෼͸

    commit ͞Ε͍ͯΔ https://github.com/microsoft/typescript-go/pull/711 - ઌ΄Ͳͷ project.getSourceFile() Ͱ AST Λऔಘ͢ΔՕॴ΋࣮૷͞Ε͍ͯΔͨΊɺ Corsa Ҡߦޙ΋ JS ͔Βࠓͱಉ༷ͷײ֮Ͱ AST ղੳΛ࣮૷Ͱ͖ͦ͏ - getSourceFile ͷ࣮ଶ͸ IPC Ͱ͋Δ͕ɺlibsyncrpc ͕ར༻͞Ε͓ͯΓ JS ଆ͔Β͸ैདྷͷ Compiler API ͱಉ͘͡ಉظతͳݺͼग़͕͠Մೳ
  13. ݸਓతͳؾʹͳΓ - LSP Λ௨Δ JSON RPC Request ͷස౓Ͱ Plugin-Native ؒͰ

    AST సૹ͕ൃੜ͠ ͯ໰୊ͳ͍ͷ͔ʁ - ྫ: Completion ܥͷίϚϯυ͸ίʔυ͕Ϣʔβʔ͕λΠϐϯά͢ΔͨͼʹϦ ΫΤετ͞ΕಘΔ - Plugin ͕ Interceptor ͔Β sourceFile Λཁٻ͢ΔͱɺLSP ͷ RPC ϦΫΤε τຖͰ AST సૹ͕ൃੜ͢Δ (୯७ͳ JSON Ͱ͸ͳ͘ Flatten ͳ Uint8Array) Strada Ͱ͸ plugin ίʔυ͕ ಉҰϓϩηεͷ sourceFile ʹ௚઀ΞΫηεͰ͖ ΔͨΊɺߴස౓ͷ document มߋԼͰ΋ TypeScript ͕͍࣋ͬͯΔ Incremental Parse ͷԸܙΛڗडͰ͖͕ͨɺݱঢ় Corsa ͷ IPC ϕʔεͷ API Ͱ͸ͦΕ͸ແཧͦ͏
  14. recap - TypeScript ͱ Language Server Protocol - Corsa ͰΑ͏΍͘

    TypeScript ͸ LSP Λਖ਼ࣜʹ໊৐ΕΔΑ͏ʹͳΔΑ - TypeScript Language Service Plugin - Plugin ػߏͷߏ૝ࣗମ͸͋Δ΋ͷͷɺPlugin ͷϩʔυํࣜ΍ AST స ૹΦʔόʔϔουͳͲɺෆ໌ྎͳ෦෼͸ґવͱͯ͠ଟ͍ - ൺֱత੔උ͕ਐΜͰ͍Δ Compiler API पΓ͔Β௥͏ͱΑͦ͞͏