Sorbet

Sorbet

  • Get started
  • Docs
  • Try
  • Community
  • GitHub
  • Blog

›Editor Features

Getting Started

  • Overview
  • Adopting Sorbet
  • Tracking Adoption
  • Quick Reference
  • Visual Studio Code
  • TypeScript ↔ Sorbet

Static & Runtime

  • Gradual Type Checking
  • Enabling Static Checks
  • Enabling Runtime Checks
  • RBI Files
  • CLI Quickstart
  • CLI Reference
  • Runtime Configuration

Troubleshooting

  • Troubleshooting
  • Why type annotations?
  • FAQ
  • Error Reference
  • Unsupported Ruby Features

Type System

  • sig
  • Type Annotations (non-sig)
  • T.let, T.cast, T.must, T.bind
  • Class Types (Integer, String)
  • Arrays & Hashes
  • Nilable Types (T.nilable)
  • Union Types (T.any)
  • Flow-Sensitivity (is_a?, nil?)
  • T.type_alias
  • Exhaustiveness (T.absurd)
  • T::Struct
  • T::Enum
  • T.untyped
  • Blocks, Procs, & Lambdas
  • Abstract Classes & Interfaces
  • Final Methods & Classes
  • Override Checking
  • Sealed Classes
  • T.class_of
  • T.self_type
  • T.noreturn
  • T.anything
  • T.attached_class
  • Intersection Types (T.all)
  • Generics
  • T::NonForcingConstants
  • Banning untyped

Editor Features

  • Language Server (LSP)
  • Server Status
  • LSP & Typed Level
  • Go to Definition
  • Hover
  • Autocompletion
  • Find All References
  • Code Actions
  • Outline & Document Symbols
  • Documentation Comments
  • Suggesting sigs
  • Highlighting untyped
  • sorbet: URIs

Experimental Features

  • Tuples
  • Shapes
  • Overloads
  • Requiring Ancestors
  • RBS Comments
Edit

Working with Synthetic or Missing Files

Note: The Sorbet VS Code extension supports this out-of-the-box. This doc serves as a reference for users of alternative LSP clients to recreate the VS Code extension behavior in their preferred language client.

When typechecking a project, certain files in the project are synthetic. For example: every RBI file which defines the Ruby standard library is not a file on disk, but actually a blob of memory baked into the Sorbet binary executable. Also, some files may be visible to the language server, but missing from the language client.

Sorbet supports a handful of extensions to the language server protocol to enable Go to Definition to work with these files:


The video above shows that Go to Definition on the File.read method (defined in an RBI file contained inside Sorbet itself) opens like a normal, non-modifiable file inside VS Code.

The extensions powering this are:

  • The supportsSorbetURIs property of the initialize request.
  • A custom sorbet/readFile LSP request.
  • In the Sorbet VS Code extension: a TextDocumentContentProvider to present a Virtual Document.
  • The --lsp-directories-missing-from-client command line flag, specifying which extra files the language server knows about, but are not known to the client, which need to be served as virtual sorbet: URI files. (Uncommon, but available)

As seen above, Sorbet’s VS Code extension supports this out of the box.

To configure other language clients to support Go to Definition for these files, follow these steps:

1. Pass supportsSorbetURIs at initialization

By default, Sorbet produces https:// URIs for synthetic files in its payload, and normal file:// URIs for all other files (even those which are missing from the client).

The first step is to request that Sorbet send sorbet: URIs for these files instead.

In the initialize request that starts the Sorbet language server, be sure to pass the supportsSorbetURIs property:

"initializationOptions": {
  // ...
  "supportsSorbetURIs": true,
  // ...
}

Different language clients will have different ways to specify initializationOptions when starting a language server. Consult the documentation of your editor or language client for how to pass this option on startup in the initialize request.

Setting supportsSorbetURIs to true informs Sorbet that it can use sorbet: URIs. Whenever a Go to Definition request would attempt to jump into a synthetic or missing file, instead of sending an https:// URI or a file:// URI, it will send a sorbet: URI.

2. Use the sorbet/readFile request to read the virtual file

By default, the language client will not know how to open files with a sorbet: URI, so the next step is to teach it.

Sorbet implements a custom LSP request method called sorbet/readFile which language clients can use to get the text content of a synthetic or missing file:

Request:

  • method: sorbet/readFile
  • params: TextDocumentIdentifier

Response:

  • result: TextDocumentItem

Different language clients have their own way to customize the way files with a certain URI are opened. For example:

  • VS Code provides an API called TextDocumentContentProvider.
  • Vim and Neovim provide BufReadCmd and FileReadCmd to customize how files with certain protocols are read. For more information, see :help Cmd-event

The best reference for how to use the sorbet/readFile command is the official Sorbet VS Code extension’s TextDocumentContentProvider implementation:

→ vscode_extension/src/sorbetContentProvider.ts

If you have implemented something which uses the sorbet/readFile request, please contribute an edit to this doc which shares a link to your code, so others can reference it!

← Highlighting untypedTuples →
  • 1. Pass supportsSorbetURIs at initialization
  • 2. Use the sorbet/readFile request to read the virtual file

Get started · Docs · Try · Community · Blog · Twitter