Skip to content

Commit

Permalink
Add docs for compiler options
Browse files Browse the repository at this point in the history
  • Loading branch information
paracycle committed Jun 18, 2024
1 parent d3c6028 commit 4c458b6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 2 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Tapioca makes it easy to work with [Sorbet](https://sorbet.org) in your codebase
* [Changing the typed strictness of annotations files](#changing-the-typed-strictness-of-annotations-files)
* [Generating RBI files for Rails and other DSLs](#generating-rbi-files-for-rails-and-other-dsls)
* [Keeping RBI files for DSLs up-to-date](#keeping-rbi-files-for-dsls-up-to-date)
* [Using DSL compiler options](#using-dsl-compiler-options)
* [Writing custom DSL compilers](#writing-custom-dsl-compilers)
* [Writing custom DSL extensions](#writing-custom-dsl-extensions)
* [RBI files for missing constants and methods](#rbi-files-for-missing-constants-and-methods)
Expand Down Expand Up @@ -546,6 +547,25 @@ if Rails.env.development?
end
```
#### Using DSL compiler options
Some DSL compilers are able to change their behaviour based on the options passed to them. For example, the
`ActiveRecordColumns` compiler can be configured to change how it generates types for method related to Active Record
column attributes. To pass options during DSL RBI generation, use the `--compiler-options` flag:
```shell
$ bin/tapioca dsl --compiler-options=ActiveRecordColumnTypes:untyped
```
which will make the `ActiveRecordColumns` compiler generate untyped signatures for column attribute methods.
Compiler options can be passed through the configuration file, as like any other option, and we expect most users to
configure them this way. For example, to configure the `ActiveRecordColumns` compiler to generate untyped signatures,
you need to add the following to your `sorbet/tapioca/config.yml` file:
```yaml
dsl:
compiler_options:
ActiveRecordColumnTypes: untyped
```
#### Writing custom DSL compilers
It is possible to create your own compilers for DSLs not supported by Tapioca out of the box.
Expand Down
28 changes: 27 additions & 1 deletion lib/tapioca/dsl/compilers/active_record_columns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ module Compilers
# created for columns and virtual attributes that are defined in the Active Record
# model.
#
# This compiler accepts a `ActiveRecordColumnTypes` option that can be used to specify
# how the types of the column related methods should be generated. The option can be one of the following:
# - `persisted` (_default_): The methods will be generated with the type that matches the actual database
# column type as the return type. This means that if the column is a string, the method return type
# will be `String`, but if the column is also nullable, then the return type will be `T.nilable(String)`. This
# mode basically treats each model as if it was a valid and persisted model. Note that this makes typing
# Active Record models easier, but does not match the behaviour of non-persisted or invalid models, which can
# have all kinds of non-sensical values in their column attributes.
# - `nilable`: All column methods will be generated with `T.nilable` return types. This is strictly the most
# correct way to type the methods, but it can make working with the models more cumbersome, as you will have to
# handle the `nil` cases explicitly using `T.must` or the safe navigation operator `&.`, even for valid
# persisted models.
# - `untyped`: The methods will be generated with `T.untyped` return types. This mode is practical if you are not
# ready to start typing your models strictly yet, but still want to generate RBI files for them.
#
# For example, with the following model class:
# ~~~rb
# class Post < ActiveRecord::Base
Expand All @@ -33,7 +48,7 @@ module Compilers
# end
# ~~~
#
# this compiler will produce the following methods in the RBI file
# this compiler will, by default, produce the following methods in the RBI file
# `post.rbi`:
#
# ~~~rbi
Expand Down Expand Up @@ -94,6 +109,17 @@ module Compilers
# end
# end
# ~~~
#
# However, if `ActiveRecordColumnTypes` is set to `nilable`, the `title` method will be generated as:
# ~~~rbi
# sig { returns(T.nilable(::String)) }
# def title; end
# ~~~
# and if the option is set to `untyped`, the `title` method will be generated as:
# ~~~rbi
# sig { returns(T.untyped) }
# def title; end
# ~~~
class ActiveRecordColumns < Compiler
extend T::Sig
include Helpers::ActiveRecordConstantsHelper
Expand Down
28 changes: 27 additions & 1 deletion manual/compiler_activerecordcolumns.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ This compiler is only responsible for defining the attribute methods that would
created for columns and virtual attributes that are defined in the Active Record
model.

This compiler accepts a `ActiveRecordColumnTypes` option that can be used to specify
how the types of the column related methods should be generated. The option can be one of the following:
- `persisted` (_default_): The methods will be generated with the type that matches the actual database
column type as the return type. This means that if the column is a string, the method return type
will be `String`, but if the column is also nullable, then the return type will be `T.nilable(String)`. This
mode basically treats each model as if it was a valid and persisted model. Note that this makes typing
Active Record models easier, but does not match the behaviour of non-persisted or invalid models, which can
have all kinds of non-sensical values in their column attributes.
- `nilable`: All column methods will be generated with `T.nilable` return types. This is strictly the most
correct way to type the methods, but it can make working with the models more cumbersome, as you will have to
handle the `nil` cases explicitly using `T.must` or the safe navigation operator `&.`, even for valid
persisted models.
- `untyped`: The methods will be generated with `T.untyped` return types. This mode is practical if you are not
ready to start typing your models strictly yet, but still want to generate RBI files for them.

For example, with the following model class:
~~~rb
class Post < ActiveRecord::Base
Expand All @@ -24,7 +39,7 @@ create_table :posts do |t|
end
~~~

this compiler will produce the following methods in the RBI file
this compiler will, by default, produce the following methods in the RBI file
`post.rbi`:

~~~rbi
Expand Down Expand Up @@ -85,3 +100,14 @@ class Post
end
end
~~~

However, if `ActiveRecordColumnTypes` is set to `nilable`, the `title` method will be generated as:
~~~rbi
sig { returns(T.nilable(::String)) }
def title; end
~~~
and if the option is set to `untyped`, the `title` method will be generated as:
~~~rbi
sig { returns(T.untyped) }
def title; end
~~~

0 comments on commit 4c458b6

Please sign in to comment.