Slide 1

Slide 1 text

TypeScript LSP ͷ ࠓ·Ͱͱ͜Ε͔Β @Quramy 2025.6.6

Slide 2

Slide 2 text

About me

Slide 3

Slide 3 text

Today's theme - Corsa ( TypeScript 7.0, Go ݴޠϕʔε) ͰΤσΟλαϙʔτ͕Ͳ͏ͳͬͯ ͍͘ͷ͔ɺࢥ͍Λ஘͍ͤͯ͘

Slide 4

Slide 4 text

TypeScript ͷΤσΟλαϙʔτ - Strada(TypeScript < 7) ʹ͸ tsserver ͱ͍͏ϓϩάϥϜ͕ಉࠝ͞Ε͍ͯΔ - ΤσΟλ (e.g. VSC, Vim, etc, ) ͸ tsserver ͱ௨৴͢Δ͜ͱͰϢʔβʔʹίʔ σΟϯάͷศརػೳΛఏڙ͍ͯ͠Δ - ίʔυิ׬, ΤϥʔνΣοΫ, Quick fi x, Organize Import, etc,,,

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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 ੡ͷΞμϓλΛט·ͤΔ౳ ͷख͕ؒඞཁͳঢ়گ͕ଓ͍͍ͯΔ 😇

Slide 7

Slide 7 text

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 ͷૅͱݴͬͯ ΋աݴͰ͸ͳ͍

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

10೥ӽ͠ͷ෱Ի͕ʂ - tsserver ͷLSPԽ͸஗ʑͱͯ͠ਐ·ͳ͔͕ͬͨɺ2025.3.11 ʹিܸ͕૸Δ IUUQTHJUIVCDPNNJDSPTPGU5ZQF4DSJQUJTTVFTJTTVFDPNNFOU

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

͜͏ͯ͠ TS ΤσΟλ քʹฏ࿨͕๚Εͨ

Slide 12

Slide 12 text

͜͏ͯ͠ TS ΤσΟλք ʹฏ࿨͕๚Εͨ ͱ͸ݴ͍੾Εͳ͍

Slide 13

Slide 13 text

΋͏ͻͱͭͷ "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,

Slide 14

Slide 14 text

LS Plugin ͷجຊ - LS Plugin ͸ tscon fi g.json ͷ plugins ʹهࡌ͢Δ͜ͱͰ༗ޮԽ͞ΕΔ (ҎԼ͸ ts-graphql-plugin ͷREADME ΑΓൈਮ) -

Slide 15

Slide 15 text

Corsa ͱ LS Plugin - typescript-go ͷ discussion ʹΑΔͱ: https://github.com/microsoft/typescript-go/discussions/455#discussioncomment-12467973 - ۩ମత͸ະఆ͕ͩɺLS ͷ Plugin ػߏͷߏ૝͸͋Δͱͷ͜ͱ - LSP ͷ JSON RPC Payload Λ Intercept ͢ΔܗͰߟ͑Ε͹͍͍ͷͰ͸ɺͱͷ͜ͱ - ԼਤͷΑ͏ͳײͩ͡Ζ͏͔ʁ (஫: ͜Ε͸ Quramy ͷໝ૝Λਤʹ͚ͨͩ͠)

Slide 16

Slide 16 text

ίʔυϨϕϧͰߟ͑Δ - 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; }, }; };

Slide 17

Slide 17 text

ίʔυϨϕϧͰߟ͑Δ - 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ͷϓϩηε͕ىಈ ͞ΕΔͱ૝ఆ

Slide 18

Slide 18 text

(ิ଍) 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 ͱಉ͘͡ಉظతͳݺͼग़͕͠Մೳ

Slide 19

Slide 19 text

ݸਓతͳؾʹͳΓ - 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 Ͱ͸ͦΕ͸ແཧͦ͏

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Thank you !