CodeVetter · Repo Unpack · Extension points
microsoft/TypeScript
Extension happens at well-defined registries. New LSP methods plug into the handlers() map via registerRequestHandler/registerNotificationHandler/registerLanguageService*RequestHandler helpers, with protocol types generated from the LSP meta-model. New API methods add a Method constant plus an unmarshallerFor entry in proto.go and a handler on the session. The compiler is host-driven: vfs.FS, CompilerHost, CheckerPool, and contentmapper.Spawner are all injectable. Diagnostics, enums, AST kinds and localized strings are codegen'd from JSON/Go sources via hereby generate:* tasks. On the product side, tsconfig `contentMappers` is a user-facing plugin model, and the VS Code extension exposes registerContentMappers to other extensions.
- Adding an LSP method: implement a handleX on *Server (or a *ls.LanguageService method) and register it in handlers() inside server.go; the register* wrappers handle params unmarshalling, initialization gating, result sending, and async work.
- LSP protocol types are generated from the upstream meta-model: lsproto/_generate/fetchModel.mts downloads metaModel.json and generateLSP produces lsp_generated.go; custom methods are declared in lsproto/lsp.go (e.g. CustomSetLogVerbosityInfo, CustomTextDocumentSourceDefinitionInfo).
- Adding an API method: declare a Method constant in proto.go, add its params unmarshaller to the method table (unmarshallerFor[T]), and implement the handler on the API session; clients call it through the sync/async Node clients.
- File-system behavior is pluggable via the vfs.FS interface with existing implementations osvfs (real FS), wrapvfs, cachedvfs, iovfs, trackingvfs, vfsmock (moq-generated), and vfstest for tests.
- Compilation is host-injected: compiler.ProgramOptions takes a CompilerHost (NewCachedFSCompilerHost for CLI, compilerhost.go/projectreferencedtsfakinghost.go variants in the compiler and build packages), an optional CreateCheckerPool factory, TypingsLocation, and Tracing.
- New diagnostics are added by editing diagnosticMessages.json/extraDiagnosticMessages.json and running `npx hereby generate:diagnostics`, which regenerates diagnostics_generated.go, loc stubs (loc_generated.go) and localized lcl payloads.
- Enum/stringer codegen is declarative: //go:generate npx hereby generate:* directives in source files map to Herebyfile stringerGenerator/moqGenerator specs (e.g. generate:ast-stringer, generate:vfs, generate:projecttestutil).
- Emit transforms plug in through the transformer chain (internal/transformers/chain.go): per-feature transformers live in tstransforms (type erasure, legacy decorators, metadata), estransforms (downlevel ES), moduletransforms (cjs/esm), and declarations for .d.ts emit.
- Content mappers are the user-facing plugin point: tsconfig 'contentMappers' entries name npm packages whose package.json carries mapper metadata (Exec argv, declared compilerOptions, DynamicConfig); resolution lives in tsoptions/contentmappers.go.
- The VS Code extension exposes an ExtensionAPI to other extensions: onLanguageServerInitialized, initializeAPIConnection(pipe) and registerContentMappers(contributorId, contributions) which flow to the server's custom setContentMapperContributions method.
- project.Session is client-abstracted: project.Client and ata.NpmExecutor interfaces let the same session machinery serve the LSP server and the API server; test mocks are generated via moq into testutil/projecttestutil.
- The execute package is test-hooked through the tsc.CommandLineTesting interface (GetTrace, OnProgram, OnEmittedFiles, watch-status callbacks), letting tsctests intercept compilation internals without changing product code.
- Repo lint rules are extensible: adding an analyzer to BuildAnalyzers() in tools/customlint/plugin.go wires a new golangci-lint check for both Go modules.