Add Cask::Config RBI compiler

This is a naive attempt at creating an RBI compiler for the
`Cask::Config` class. `Config` contains methods like `appdir` that
are defined dynamically using the class's default values and Sorbet
doesn't understand that these methods exist or what their return
types are. This compiler works as expected and gets the job done but
I know basically nothing about Tapioca, so there may be a better way
of doing this.

For what it's worth, this isn't an issue right now but Sorbet will
surface an error once `Cask::DSL` is updated to `typed: strict` (i.e.,
`Method appdir does not exist on Cask::Config`). That's something
I've been working on and this compiler is intended as a way of
preemptively resolving that Sorbet error, so I can move forward with
the `Cask::DSL` type signature work.
This commit is contained in:
Sam Ford 2025-06-16 23:20:19 -04:00
parent 95f0e76154
commit 9c69859f99
No known key found for this signature in database
GPG Key ID: 7AF5CBEE1DD6F76D
2 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,58 @@
# typed: true
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Cask::Config`.
# Please instead update this file by running `bin/tapioca dsl Cask::Config`.
module Cask
class Config
sig { returns(String) }
def appdir; end
sig { returns(String) }
def audio_unit_plugindir; end
sig { returns(String) }
def colorpickerdir; end
sig { returns(String) }
def dictionarydir; end
sig { returns(String) }
def fontdir; end
sig { returns(String) }
def input_methoddir; end
sig { returns(String) }
def internet_plugindir; end
sig { returns(String) }
def keyboard_layoutdir; end
sig { returns(T::Array[String]) }
def languages; end
sig { returns(String) }
def mdimporterdir; end
sig { returns(String) }
def prefpanedir; end
sig { returns(String) }
def qlplugindir; end
sig { returns(String) }
def screen_saverdir; end
sig { returns(String) }
def servicedir; end
sig { returns(String) }
def vst3_plugindir; end
sig { returns(String) }
def vst_plugindir; end
end
end

View File

@ -0,0 +1,37 @@
# typed: strict
# frozen_string_literal: true
require_relative "../../../../global"
require "cask/config"
module Tapioca
module Compilers
class CaskConfig < Tapioca::Dsl::Compiler
ConstantType = type_member { { fixed: Module } }
sig { override.returns(T::Enumerable[Module]) }
def self.gather_constants = [Cask::Config]
sig { override.void }
def decorate
root.create_module("Cask") do |mod|
mod.create_class("Config") do |klass|
Cask::Config.defaults.each do |key, value|
return_type = if key == :languages
# :languages is a `LazyObject`, so it lazily evaluates to an
# array of strings when a method is called on it.
"T::Array[String]"
elsif key.end_with?("?")
"T::Boolean"
else
value.class.to_s
end
klass.create_method(key.to_s, return_type:, class_method: false)
end
end
end
end
end
end
end