mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
brew vendor-gems: commit updates.
This commit is contained in:
parent
d4325c0137
commit
f3db247045
@ -167,6 +167,7 @@ GEM
|
|||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
aarch64-linux
|
aarch64-linux
|
||||||
|
arm-linux
|
||||||
arm64-darwin
|
arm64-darwin
|
||||||
x86_64-darwin
|
x86_64-darwin
|
||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
61
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
61
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
@ -37,21 +37,21 @@ end
|
|||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/public_suffix-6.0.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/public_suffix-6.0.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/addressable-2.8.7/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/addressable-2.8.7/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ast-2.4.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ast-2.4.3/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/base64-0.2.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/base64-0.3.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/benchmark-0.4.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/benchmark-0.4.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/bigdecimal-3.1.9")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/bigdecimal-3.2.2")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bigdecimal-3.1.9/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bigdecimal-3.2.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bindata-2.5.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/bindata-2.5.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/coderay-1.1.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/coderay-1.1.3/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/csv-3.3.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/csv-3.3.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/diff-lcs-1.6.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/diff-lcs-1.6.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/docile-1.4.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/docile-1.4.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/elftools-1.3.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/elftools-1.3.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/erubi-1.13.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/erubi-1.13.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/hana-1.3.7/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/hana-1.3.7/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/json-2.12.0")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/json-2.12.2")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/json-2.12.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/json-2.12.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/regexp_parser-2.10.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/regexp_parser-2.10.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simpleidn-0.2.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simpleidn-0.2.3/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/json_schemer-2.4.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/json_schemer-2.4.0/lib")
|
||||||
@ -64,7 +64,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
|
|||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/minitest-5.25.5/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/minitest-5.25.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/netrc-0.11.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/netrc-0.11.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parallel-1.27.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parallel-1.27.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parallel_tests-5.2.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parallel_tests-5.3.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/racc-1.8.1")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/racc-1.8.1")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/racc-1.8.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/racc-1.8.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parser-3.3.8.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/parser-3.3.8.0/lib")
|
||||||
@ -76,48 +76,49 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
|
|||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/pycall-1.5.2")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/pycall-1.5.2")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/pycall-1.5.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/pycall-1.5.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rainbow-3.1.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rainbow-3.1.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/rbs-3.9.4")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/rbs-4.0.0.dev.4")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rbs-3.9.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rbs-4.0.0.dev.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-runtime-0.5.12117/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rbi-0.3.6/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rbi-0.3.3/lib")
|
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/redcarpet-3.6.1")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/redcarpet-3.6.1")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/redcarpet-3.6.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/redcarpet-3.6.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-support-3.13.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/require-hooks-0.2.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-core-3.13.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-support-3.13.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-expectations-3.13.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-core-3.13.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-mocks-3.13.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-expectations-3.13.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-3.13.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-mocks-3.13.5/lib")
|
||||||
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-3.13.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-github-3.0.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-github-3.0.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-retry-0.6.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-retry-0.6.2/lib")
|
||||||
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-runtime-0.5.12222/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-sorbet-1.9.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec-sorbet-1.9.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec_junit_formatter-0.6.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rspec_junit_formatter-0.6.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-ast-1.44.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-ast-1.45.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-progressbar-1.13.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-progressbar-1.13.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/unicode-emoji-4.0.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/unicode-emoji-4.0.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/unicode-display_width-3.1.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/unicode-display_width-3.1.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-1.75.6/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-1.77.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-md-2.0.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-md-2.0.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-performance-1.25.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-performance-1.25.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-3.6.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-3.6.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.10.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.10.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-lsp-0.23.21/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-lsp-0.24.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-macho-4.1.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-macho-4.1.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/ruby-prof-1.7.1")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/ruby-prof-1.7.2")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-prof-1.7.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-prof-1.7.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-html-0.13.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-html-0.13.1/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov_json_formatter-0.1.4/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov_json_formatter-0.1.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-0.22.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-0.22.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-cobertura-2.1.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-cobertura-2.1.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-0.5.12117-universal-darwin/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-0.5.12222-universal-darwin/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-0.5.12117/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-0.5.12222/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-and-runtime-0.5.12117/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/sorbet-static-and-runtime-0.5.12222/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/thor-1.3.2/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/thor-1.3.2/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/spoom-1.6.3/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/spoom-1.7.4/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/stackprof-0.2.27")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/stackprof-0.2.27")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/stackprof-0.2.27/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/stackprof-0.2.27/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/yard-0.9.37/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/yard-0.9.37/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/yard-sorbet-0.9.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/yard-sorbet-0.9.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/tapioca-0.16.11/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/tapioca-0.17.5/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/vernier-1.7.1")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/vernier-1.8.0")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/vernier-1.7.1/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/vernier-1.8.0/lib")
|
||||||
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/warning-1.5.0/lib")
|
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/warning-1.5.0/lib")
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGE.
|
|
@ -2,7 +2,7 @@
|
|||||||
#
|
#
|
||||||
# \Module \Base64 provides methods for:
|
# \Module \Base64 provides methods for:
|
||||||
#
|
#
|
||||||
# - Encoding a binary string (containing non-ASCII characters)
|
# - \Encoding a binary string (containing non-ASCII characters)
|
||||||
# as a string of printable ASCII characters.
|
# as a string of printable ASCII characters.
|
||||||
# - Decoding such an encoded string.
|
# - Decoding such an encoded string.
|
||||||
#
|
#
|
||||||
@ -27,7 +27,7 @@
|
|||||||
#
|
#
|
||||||
# require 'base64'
|
# require 'base64'
|
||||||
#
|
#
|
||||||
# == Encoding Character Sets
|
# == \Encoding Character Sets
|
||||||
#
|
#
|
||||||
# A \Base64-encoded string consists only of characters from a 64-character set:
|
# A \Base64-encoded string consists only of characters from a 64-character set:
|
||||||
#
|
#
|
||||||
@ -140,7 +140,7 @@
|
|||||||
# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
|
# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
|
||||||
# Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
|
# Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
|
||||||
#
|
#
|
||||||
# \Method Base64.urlsafe_decode64 allows padding in +str+,
|
# \Method Base64.urlsafe_decode64 allows padding in the encoded string,
|
||||||
# which if present, must be correct:
|
# which if present, must be correct:
|
||||||
# see {Padding}[Base64.html#module-Base64-label-Padding], above:
|
# see {Padding}[Base64.html#module-Base64-label-Padding], above:
|
||||||
#
|
#
|
||||||
@ -183,11 +183,14 @@
|
|||||||
#
|
#
|
||||||
module Base64
|
module Base64
|
||||||
|
|
||||||
VERSION = "0.2.0"
|
VERSION = "0.3.0"
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
# Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
|
# :call-seq:
|
||||||
|
# Base64.encode64(string) -> encoded_string
|
||||||
|
#
|
||||||
|
# Returns a string containing the RFC-2045-compliant \Base64-encoding of +string+.
|
||||||
#
|
#
|
||||||
# Per RFC 2045, the returned string may contain the URL-unsafe characters
|
# Per RFC 2045, the returned string may contain the URL-unsafe characters
|
||||||
# <tt>+</tt> or <tt>/</tt>;
|
# <tt>+</tt> or <tt>/</tt>;
|
||||||
@ -220,19 +223,22 @@ module Base64
|
|||||||
[bin].pack("m")
|
[bin].pack("m")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :call-seq:
|
||||||
|
# Base64.decode(encoded_string) -> decoded_string
|
||||||
|
#
|
||||||
# Returns a string containing the decoding of an RFC-2045-compliant
|
# Returns a string containing the decoding of an RFC-2045-compliant
|
||||||
# \Base64-encoded string +str+:
|
# \Base64-encoded string +encoded_string+:
|
||||||
#
|
#
|
||||||
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
|
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
|
||||||
# Base64.decode64(s) # => "This is line 1\nThis is line 2\n"
|
# Base64.decode64(s) # => "This is line 1\nThis is line 2\n"
|
||||||
#
|
#
|
||||||
# Non-\Base64 characters in +str+ are ignored;
|
# Non-\Base64 characters in +encoded_string+ are ignored;
|
||||||
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
||||||
# these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
|
# these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
|
||||||
#
|
#
|
||||||
# Base64.decode64("\x00\n-_") # => ""
|
# Base64.decode64("\x00\n-_") # => ""
|
||||||
#
|
#
|
||||||
# Padding in +str+ (even if incorrect) is ignored:
|
# Padding in +encoded_string+ (even if incorrect) is ignored:
|
||||||
#
|
#
|
||||||
# Base64.decode64("MDEyMzQ1Njc") # => "01234567"
|
# Base64.decode64("MDEyMzQ1Njc") # => "01234567"
|
||||||
# Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
|
# Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
|
||||||
@ -242,7 +248,10 @@ module Base64
|
|||||||
str.unpack1("m")
|
str.unpack1("m")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a string containing the RFC-2045-compliant \Base64-encoding of +bin+.
|
# :call-seq:
|
||||||
|
# Base64.strict_encode64(string) -> encoded_string
|
||||||
|
#
|
||||||
|
# Returns a string containing the RFC-2045-compliant \Base64-encoding of +string+.
|
||||||
#
|
#
|
||||||
# Per RFC 2045, the returned string may contain the URL-unsafe characters
|
# Per RFC 2045, the returned string may contain the URL-unsafe characters
|
||||||
# <tt>+</tt> or <tt>/</tt>;
|
# <tt>+</tt> or <tt>/</tt>;
|
||||||
@ -274,13 +283,16 @@ module Base64
|
|||||||
[bin].pack("m0")
|
[bin].pack("m0")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# :call-seq:
|
||||||
|
# Base64.strict_decode64(encoded_string) -> decoded_string
|
||||||
|
#
|
||||||
# Returns a string containing the decoding of an RFC-2045-compliant
|
# Returns a string containing the decoding of an RFC-2045-compliant
|
||||||
# \Base64-encoded string +str+:
|
# \Base64-encoded string +encoded_string+:
|
||||||
#
|
#
|
||||||
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
|
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
|
||||||
# Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n"
|
# Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n"
|
||||||
#
|
#
|
||||||
# Non-\Base64 characters in +str+ not allowed;
|
# Non-\Base64 characters in +encoded_string+ are not allowed;
|
||||||
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
||||||
# these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
|
# these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
|
||||||
#
|
#
|
||||||
@ -288,7 +300,7 @@ module Base64
|
|||||||
# Base64.strict_decode64('-') # Raises ArgumentError
|
# Base64.strict_decode64('-') # Raises ArgumentError
|
||||||
# Base64.strict_decode64('_') # Raises ArgumentError
|
# Base64.strict_decode64('_') # Raises ArgumentError
|
||||||
#
|
#
|
||||||
# Padding in +str+, if present, must be correct:
|
# Padding in +encoded_string+, if present, must be correct:
|
||||||
#
|
#
|
||||||
# Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
|
# Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError
|
||||||
# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
|
# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567"
|
||||||
@ -298,7 +310,10 @@ module Base64
|
|||||||
str.unpack1("m0")
|
str.unpack1("m0")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the RFC-4648-compliant \Base64-encoding of +bin+.
|
# :call-seq:
|
||||||
|
# Base64.urlsafe_encode64(string) -> encoded_string
|
||||||
|
#
|
||||||
|
# Returns the RFC-4648-compliant \Base64-encoding of +string+.
|
||||||
#
|
#
|
||||||
# Per RFC 4648, the returned string will not contain the URL-unsafe characters
|
# Per RFC 4648, the returned string will not contain the URL-unsafe characters
|
||||||
# <tt>+</tt> or <tt>/</tt>,
|
# <tt>+</tt> or <tt>/</tt>,
|
||||||
@ -332,16 +347,19 @@ module Base64
|
|||||||
str
|
str
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the decoding of an RFC-4648-compliant \Base64-encoded string +str+:
|
# :call-seq:
|
||||||
|
# Base64.urlsafe_decode64(encoded_string) -> decoded_string
|
||||||
#
|
#
|
||||||
# +str+ may not contain non-Base64 characters;
|
# Returns the decoding of an RFC-4648-compliant \Base64-encoded string +encoded_string+:
|
||||||
|
#
|
||||||
|
# +encoded_string+ may not contain non-Base64 characters;
|
||||||
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
# see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above:
|
||||||
#
|
#
|
||||||
# Base64.urlsafe_decode64('+') # Raises ArgumentError.
|
# Base64.urlsafe_decode64('+') # Raises ArgumentError.
|
||||||
# Base64.urlsafe_decode64('/') # Raises ArgumentError.
|
# Base64.urlsafe_decode64('/') # Raises ArgumentError.
|
||||||
# Base64.urlsafe_decode64("\n") # Raises ArgumentError.
|
# Base64.urlsafe_decode64("\n") # Raises ArgumentError.
|
||||||
#
|
#
|
||||||
# Padding in +str+, if present, must be correct:
|
# Padding in +encoded_string+, if present, must be correct:
|
||||||
# see {Padding}[Base64.html#module-Base64-label-Padding], above:
|
# see {Padding}[Base64.html#module-Base64-label-Padding], above:
|
||||||
#
|
#
|
||||||
# Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
|
# Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
|
23
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/LICENSE.txt
vendored
Normal file
23
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/LICENSE.txt
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Copyright (c) 2023 Vladimir Dementyev
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
3
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks.rb
vendored
Normal file
3
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks.rb
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "require-hooks/version"
|
132
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks/api.rb
vendored
Normal file
132
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks/api.rb
vendored
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RequireHooks
|
||||||
|
@@around_load = []
|
||||||
|
@@source_transform = []
|
||||||
|
@@hijack_load = []
|
||||||
|
|
||||||
|
class Context
|
||||||
|
def initialize(around_load, source_transform, hijack_load)
|
||||||
|
@around_load = around_load
|
||||||
|
@source_transform = source_transform
|
||||||
|
@hijack_load = hijack_load
|
||||||
|
end
|
||||||
|
|
||||||
|
def empty?
|
||||||
|
@around_load.empty? && @source_transform.empty? && @hijack_load.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_transform?
|
||||||
|
@source_transform.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def hijack?
|
||||||
|
@hijack_load.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_around_load_callbacks(path)
|
||||||
|
return yield if @around_load.empty?
|
||||||
|
|
||||||
|
chain = @around_load.reverse.inject do |acc_proc, next_proc|
|
||||||
|
proc { |path, &block| acc_proc.call(path) { next_proc.call(path, &block) } }
|
||||||
|
end
|
||||||
|
|
||||||
|
chain.call(path) { yield }
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform_source_transform(path)
|
||||||
|
return unless @source_transform.any?
|
||||||
|
|
||||||
|
source = nil
|
||||||
|
|
||||||
|
@source_transform.each do |transform|
|
||||||
|
source = transform.call(path, source) || source
|
||||||
|
end
|
||||||
|
|
||||||
|
source
|
||||||
|
end
|
||||||
|
|
||||||
|
def try_hijack_load(path, source)
|
||||||
|
return unless @hijack_load.any?
|
||||||
|
|
||||||
|
@hijack_load.each do |hijack|
|
||||||
|
result = hijack.call(path, source)
|
||||||
|
return result if result
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr_accessor :print_warnings
|
||||||
|
|
||||||
|
# Define a block to wrap the code loading.
|
||||||
|
# The return value MUST be a result of calling the passed block.
|
||||||
|
# For example, you can use such hooks for instrumentation, debugging purposes.
|
||||||
|
#
|
||||||
|
# RequireHooks.around_load do |path, &block|
|
||||||
|
# puts "Loading #{path}"
|
||||||
|
# block.call.tap { puts "Loaded #{path}" }
|
||||||
|
# end
|
||||||
|
def around_load(patterns: nil, exclude_patterns: nil, &block)
|
||||||
|
@@around_load << [patterns, exclude_patterns, block]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Define hooks to perform source-to-source transformations.
|
||||||
|
# The return value MUST be either String (new source code) or nil (indicating that no transformations were performed).
|
||||||
|
#
|
||||||
|
# NOTE: The second argument (`source`) MAY be nil, indicating that no transformer tried to transform the source code.
|
||||||
|
#
|
||||||
|
# For example, you can prepend each file with `# frozen_string_literal: true` pragma:
|
||||||
|
#
|
||||||
|
# RequireHooks.source_transform do |path, source|
|
||||||
|
# "# frozen_string_literal: true\n#{source}"
|
||||||
|
# end
|
||||||
|
def source_transform(patterns: nil, exclude_patterns: nil, &block)
|
||||||
|
@@source_transform << [patterns, exclude_patterns, block]
|
||||||
|
end
|
||||||
|
|
||||||
|
# This hook should be used to manually compile byte code to be loaded by the VM.
|
||||||
|
# The arguments are (path, source = nil), where source is only defined if transformations took place.
|
||||||
|
# Otherwise, you MUST read the source code from the file yourself.
|
||||||
|
#
|
||||||
|
# The return value MUST be either nil (continue to the next hook or default behavior) or a platform-specific bytecode object (e.g., RubyVM::InstructionSequence).
|
||||||
|
#
|
||||||
|
# RequireHooks.hijack_load do |path, source|
|
||||||
|
# source ||= File.read(path)
|
||||||
|
# if defined?(RubyVM::InstructionSequence)
|
||||||
|
# RubyVM::InstructionSequence.compile(source)
|
||||||
|
# elsif defined?(JRUBY_VERSION)
|
||||||
|
# JRuby.compile(source)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
def hijack_load(patterns: nil, exclude_patterns: nil, &block)
|
||||||
|
@@hijack_load << [patterns, exclude_patterns, block]
|
||||||
|
end
|
||||||
|
|
||||||
|
def context_for(path)
|
||||||
|
around_load = @@around_load.select do |patterns, exclude_patterns, _block|
|
||||||
|
next unless !patterns || patterns.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
next if exclude_patterns&.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
|
||||||
|
true
|
||||||
|
end.map { |_patterns, _exclude_patterns, block| block }
|
||||||
|
|
||||||
|
source_transform = @@source_transform.select do |patterns, exclude_patterns, _block|
|
||||||
|
next unless !patterns || patterns.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
next if exclude_patterns&.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
|
||||||
|
true
|
||||||
|
end.map { |_patterns, _exclude_patterns, block| block }
|
||||||
|
|
||||||
|
hijack_load = @@hijack_load.select do |patterns, exclude_patterns, _block|
|
||||||
|
next unless !patterns || patterns.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
next if exclude_patterns&.any? { |pattern| File.fnmatch?(pattern, path) }
|
||||||
|
|
||||||
|
true
|
||||||
|
end.map { |_patterns, _exclude_patterns, block| block }
|
||||||
|
|
||||||
|
Context.new(around_load, source_transform, hijack_load)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,36 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RequireHooks
|
||||||
|
module Bootsnap
|
||||||
|
module CompileCacheExt
|
||||||
|
def input_to_storage(source, path, *)
|
||||||
|
ctx = RequireHooks.context_for(path)
|
||||||
|
|
||||||
|
new_contents = ctx.perform_source_transform(path)
|
||||||
|
hijacked = ctx.try_hijack_load(path, new_contents)
|
||||||
|
|
||||||
|
if hijacked
|
||||||
|
raise TypeError, "Unsupported bytecode format for #{path}: #{hijack.class}" unless hijacked.is_a?(::RubyVM::InstructionSequence)
|
||||||
|
return hijacked.to_binary
|
||||||
|
elsif new_contents
|
||||||
|
return RubyVM::InstructionSequence.compile(new_contents, path, path, 1).to_binary
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
rescue SyntaxError, TypeError
|
||||||
|
::Bootsnap::CompileCache::UNCOMPILABLE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module LoadIseqExt
|
||||||
|
# Around hooks must be performed every time we trigger a file load, even if
|
||||||
|
# the file is already cached.
|
||||||
|
def load_iseq(path)
|
||||||
|
RequireHooks.context_for(path).run_around_load_callbacks(path) { super }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Bootsnap::CompileCache::ISeq.singleton_class.prepend(RequireHooks::Bootsnap::CompileCacheExt)
|
||||||
|
RubyVM::InstructionSequence.singleton_class.prepend(RequireHooks::Bootsnap::LoadIseqExt)
|
@ -0,0 +1,326 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "mutex_m"
|
||||||
|
require "pathname"
|
||||||
|
|
||||||
|
module RequireHooks
|
||||||
|
module KernelPatch
|
||||||
|
class << self
|
||||||
|
def load(path)
|
||||||
|
ctx = RequireHooks.context_for(path)
|
||||||
|
|
||||||
|
ctx.run_around_load_callbacks(path) do
|
||||||
|
next load_without_require_hooks(path) unless ctx.source_transform? || ctx.hijack?
|
||||||
|
|
||||||
|
new_contents = ctx.perform_source_transform(path)
|
||||||
|
hijacked = ctx.try_hijack_load(path, new_contents)
|
||||||
|
|
||||||
|
return try_evaluate(path, hijacked) if hijacked
|
||||||
|
|
||||||
|
if new_contents
|
||||||
|
evaluate(new_contents, path)
|
||||||
|
true
|
||||||
|
else
|
||||||
|
load_without_require_hooks(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def try_evaluate(path, bytecode)
|
||||||
|
if defined?(::RubyVM::InstructionSequence) && bytecode.is_a?(::RubyVM::InstructionSequence)
|
||||||
|
bytecode.eval
|
||||||
|
else
|
||||||
|
raise TypeError, "Unknown bytecode format for #{path}: #{bytecode.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
if defined?(JRUBY_VERSION) || defined?(TruffleRuby)
|
||||||
|
def evaluate(code, filepath)
|
||||||
|
new_toplevel.eval(code, filepath)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_toplevel
|
||||||
|
# Create new "toplevel" binding to avoid lexical scope re-use
|
||||||
|
# (aka "leaking refinements")
|
||||||
|
eval "proc{binding}.call", TOPLEVEL_BINDING, __FILE__, __LINE__
|
||||||
|
end
|
||||||
|
else
|
||||||
|
def evaluate(code, filepath)
|
||||||
|
# This is workaround to solve the "leaking refinements" problem in MRI
|
||||||
|
RubyVM::InstructionSequence.compile(code, filepath).tap do |iseq|
|
||||||
|
iseq.eval
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Features
|
||||||
|
class Locker
|
||||||
|
class PathLock
|
||||||
|
def initialize
|
||||||
|
@mu = Mutex.new
|
||||||
|
@resolved = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def owned?
|
||||||
|
@mu.owned?
|
||||||
|
end
|
||||||
|
|
||||||
|
def locked?
|
||||||
|
@mu.locked?
|
||||||
|
end
|
||||||
|
|
||||||
|
def lock!
|
||||||
|
@mu.lock
|
||||||
|
end
|
||||||
|
|
||||||
|
def unlock!
|
||||||
|
@mu.unlock
|
||||||
|
end
|
||||||
|
|
||||||
|
def resolve!
|
||||||
|
@resolved = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def resolved?
|
||||||
|
@resolved
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :features, :mu
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@mu = Mutex.new
|
||||||
|
@features = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def lock_feature(fname)
|
||||||
|
lock = mu.synchronize do
|
||||||
|
features[fname] ||= PathLock.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# Can this even happen?
|
||||||
|
return yield(true) if lock.resolved?
|
||||||
|
|
||||||
|
# Recursive require
|
||||||
|
if lock.owned? && lock.locked?
|
||||||
|
warn "loading in progress, circular require considered harmful: #{fname}" if RequireHooks.print_warnings
|
||||||
|
return yield(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
lock.lock!
|
||||||
|
begin
|
||||||
|
yield(lock.resolved?).tap do
|
||||||
|
lock.resolve!
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
lock.unlock!
|
||||||
|
|
||||||
|
mu.synchronize do
|
||||||
|
features.delete(fname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def locked_feature?(fname)
|
||||||
|
mu.synchronize { features.key?(fname) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LOCK = Locker.new
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def feature_path(path, implitic_ext: true)
|
||||||
|
path = resolve_feature_path(path, implitic_ext: implitic_ext)
|
||||||
|
return if path.nil?
|
||||||
|
return if File.extname(path) != ".rb" && implitic_ext
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Based on https://github.com/ruby/ruby/blob/b588fd552390c55809719100d803c36bc7430f2f/load.c#L403-L415
|
||||||
|
def feature_loaded?(feature)
|
||||||
|
return true if $LOADED_FEATURES.include?(feature) && !LOCK.locked_feature?(feature)
|
||||||
|
|
||||||
|
feature = Pathname.new(feature).cleanpath.to_s
|
||||||
|
efeature = File.expand_path(feature)
|
||||||
|
|
||||||
|
# Check absoulute and relative paths
|
||||||
|
return true if $LOADED_FEATURES.include?(efeature) && !LOCK.locked_feature?(efeature)
|
||||||
|
|
||||||
|
candidates = []
|
||||||
|
|
||||||
|
$LOADED_FEATURES.each do |lf|
|
||||||
|
candidates << lf if lf.end_with?("/#{feature}")
|
||||||
|
end
|
||||||
|
|
||||||
|
return false if candidates.empty?
|
||||||
|
|
||||||
|
$LOAD_PATH.each do |lp|
|
||||||
|
lp_feature = File.join(lp, feature)
|
||||||
|
return true if candidates.include?(lp_feature) && !LOCK.locked_feature?(lp_feature)
|
||||||
|
end
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def lookup_feature_path(path, implitic_ext: true)
|
||||||
|
path = "#{path}.rb" if File.extname(path).empty? && implitic_ext
|
||||||
|
|
||||||
|
# Resolve relative paths only against current directory
|
||||||
|
if path.match?(/^\.\.?\//)
|
||||||
|
path = File.expand_path(path)
|
||||||
|
return path if File.file?(path)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if Pathname.new(path).absolute?
|
||||||
|
path = File.expand_path(path)
|
||||||
|
return File.file?(path) ? path : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# not a relative, not an absolute path — bare path; try looking relative to current dir,
|
||||||
|
# if it's in the $LOAD_PATH
|
||||||
|
if $LOAD_PATH.include?(Dir.pwd) && File.file?(path)
|
||||||
|
return File.expand_path(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
$LOAD_PATH.find do |lp|
|
||||||
|
lpath = File.join(lp, path)
|
||||||
|
return File.expand_path(lpath) if File.file?(lpath)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if $LOAD_PATH.respond_to?(:resolve_feature_path)
|
||||||
|
def resolve_feature_path(feature, implitic_ext: true)
|
||||||
|
if implitic_ext
|
||||||
|
path = $LOAD_PATH.resolve_feature_path(feature)
|
||||||
|
path.last if path # rubocop:disable Style/SafeNavigation
|
||||||
|
else
|
||||||
|
lookup_feature_path(feature, implitic_ext: implitic_ext)
|
||||||
|
end
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
else
|
||||||
|
def resolve_feature_path(feature, implitic_ext: true)
|
||||||
|
lookup_feature_path(feature, implitic_ext: implitic_ext)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Patch Kernel to hijack require/require_relative/load
|
||||||
|
module Kernel
|
||||||
|
module_function
|
||||||
|
|
||||||
|
alias_method :require_without_require_hooks, :require
|
||||||
|
# See https://github.com/ruby/ruby/blob/d814722fb8299c4baace3e76447a55a3d5478e3a/load.c#L1181
|
||||||
|
def require(path)
|
||||||
|
path = path.to_path if path.respond_to?(:to_path)
|
||||||
|
raise TypeError unless path.respond_to?(:to_str)
|
||||||
|
|
||||||
|
path = path.to_str
|
||||||
|
|
||||||
|
raise TypeError unless path.is_a?(::String)
|
||||||
|
|
||||||
|
realpath = nil
|
||||||
|
feature = path
|
||||||
|
|
||||||
|
# if extname == ".rb" => lookup feature -> resolve feature -> load
|
||||||
|
# if extname != ".rb" => append ".rb" - lookup feature -> resolve feature -> lookup orig (no ext) -> resolve orig (no ext) -> load
|
||||||
|
if File.extname(path) != ".rb"
|
||||||
|
realpath = RequireHooks::KernelPatch::Features.feature_path(path + ".rb")
|
||||||
|
|
||||||
|
if realpath
|
||||||
|
feature = path + ".rb"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
realpath ||= RequireHooks::KernelPatch::Features.feature_path(path)
|
||||||
|
|
||||||
|
return require_without_require_hooks(path) unless realpath
|
||||||
|
|
||||||
|
ctx = RequireHooks.context_for(realpath)
|
||||||
|
|
||||||
|
return require_without_require_hooks(path) if ctx.empty?
|
||||||
|
|
||||||
|
return false if RequireHooks::KernelPatch::Features.feature_loaded?(feature)
|
||||||
|
|
||||||
|
RequireHooks::KernelPatch::Features::LOCK.lock_feature(feature) do |loaded|
|
||||||
|
return false if loaded
|
||||||
|
|
||||||
|
$LOADED_FEATURES << realpath
|
||||||
|
RequireHooks::KernelPatch.load(realpath)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
rescue LoadError => e
|
||||||
|
$LOADED_FEATURES.delete(realpath) if realpath
|
||||||
|
warn "RequireHooks failed to require '#{path}': #{e.message}" if RequireHooks.print_warnings
|
||||||
|
require_without_require_hooks(path)
|
||||||
|
rescue Errno::ENOENT, Errno::EACCES
|
||||||
|
raise LoadError, "cannot load such file -- #{path}"
|
||||||
|
rescue
|
||||||
|
$LOADED_FEATURES.delete(realpath) if realpath
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :require_relative_without_require_hooks, :require_relative
|
||||||
|
def require_relative(path)
|
||||||
|
path = path.to_path if path.respond_to?(:to_path)
|
||||||
|
raise TypeError unless path.respond_to?(:to_str)
|
||||||
|
path = path.to_str
|
||||||
|
|
||||||
|
raise TypeError unless path.is_a?(::String)
|
||||||
|
|
||||||
|
return require(path) if Pathname.new(path).absolute?
|
||||||
|
|
||||||
|
loc = caller_locations(1..1).first
|
||||||
|
from = loc.absolute_path || loc.path || File.join(Dir.pwd, "main")
|
||||||
|
realpath = File.absolute_path(
|
||||||
|
File.join(
|
||||||
|
File.dirname(File.absolute_path(from)),
|
||||||
|
path
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
require(realpath)
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :load_without_require_hooks, :load
|
||||||
|
def load(path, wrap = false)
|
||||||
|
if wrap
|
||||||
|
warn "RequireHooks does not support `load(smth, wrap: ...)`. Falling back to original `Kernel#load`" if RequireHooks.print_warnings
|
||||||
|
return load_without_require_hooks(path, wrap)
|
||||||
|
end
|
||||||
|
|
||||||
|
path = path.to_path if path.respond_to?(:to_path)
|
||||||
|
raise TypeError unless path.respond_to?(:to_str)
|
||||||
|
|
||||||
|
path = path.to_str
|
||||||
|
|
||||||
|
raise TypeError unless path.is_a?(::String)
|
||||||
|
|
||||||
|
realpath =
|
||||||
|
if path =~ /^\.\.?\//
|
||||||
|
path
|
||||||
|
else
|
||||||
|
RequireHooks::KernelPatch::Features.feature_path(path, implitic_ext: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
return load_without_require_hooks(path, wrap) unless realpath
|
||||||
|
|
||||||
|
RequireHooks::KernelPatch.load(realpath)
|
||||||
|
rescue Errno::ENOENT, Errno::EACCES
|
||||||
|
raise LoadError, "cannot load such file -- #{path}"
|
||||||
|
rescue LoadError => e
|
||||||
|
warn "RuquireHooks failed to load '#{path}': #{e.message}" if RequireHooks.print_warnings
|
||||||
|
load_without_require_hooks(path)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,31 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RequireHooks
|
||||||
|
module LoadIseq
|
||||||
|
def load_iseq(path)
|
||||||
|
ctx = RequireHooks.context_for(path)
|
||||||
|
|
||||||
|
ctx.run_around_load_callbacks(path) do
|
||||||
|
if ctx.source_transform? || ctx.hijack?
|
||||||
|
new_contents = ctx.perform_source_transform(path)
|
||||||
|
hijacked = ctx.try_hijack_load(path, new_contents)
|
||||||
|
|
||||||
|
if hijacked
|
||||||
|
raise TypeError, "Unsupported bytecode format for #{path}: #{hijack.class}" unless hijacked.is_a?(::RubyVM::InstructionSequence)
|
||||||
|
return hijacked
|
||||||
|
elsif new_contents
|
||||||
|
return RubyVM::InstructionSequence.compile(new_contents, path, path, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defined?(super) ? super : RubyVM::InstructionSequence.compile_file(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if RubyVM::InstructionSequence.respond_to?(:load_iseq)
|
||||||
|
warn "require-hooks: RubyVM::InstructionSequence.load_iseq is already defined. It won't be used by files processed by require-hooks."
|
||||||
|
end
|
||||||
|
|
||||||
|
RubyVM::InstructionSequence.singleton_class.prepend(RequireHooks::LoadIseq)
|
28
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks/setup.rb
vendored
Normal file
28
Library/Homebrew/vendor/bundle/ruby/3.4.0/gems/require-hooks-0.2.2/lib/require-hooks/setup.rb
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "require-hooks/api"
|
||||||
|
|
||||||
|
mode = ENV["REQUIRE_HOOKS_MODE"]
|
||||||
|
|
||||||
|
case mode
|
||||||
|
when "patch"
|
||||||
|
require "require-hooks/mode/kernel_patch"
|
||||||
|
when "load_iseq"
|
||||||
|
require "require-hooks/mode/load_iseq"
|
||||||
|
when "bootsnap"
|
||||||
|
require "require-hooks/mode/bootsnap"
|
||||||
|
else
|
||||||
|
if defined?(::RubyVM::InstructionSequence)
|
||||||
|
# Check if Bootsnap has been loaded.
|
||||||
|
# Based on https://github.com/kddeisz/preval/blob/master/lib/preval.rb
|
||||||
|
if RubyVM::InstructionSequence.respond_to?(:load_iseq) &&
|
||||||
|
(load_iseq = RubyVM::InstructionSequence.method(:load_iseq)) &&
|
||||||
|
load_iseq.source_location[0].include?("/bootsnap/")
|
||||||
|
require "require-hooks/mode/bootsnap"
|
||||||
|
else
|
||||||
|
require "require-hooks/mode/load_iseq"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
require "require-hooks/mode/kernel_patch"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RequireHooks
|
||||||
|
VERSION = "0.2.2"
|
||||||
|
end
|
@ -27,7 +27,7 @@ module T
|
|||||||
def self.any(type_a, type_b, *types)
|
def self.any(type_a, type_b, *types)
|
||||||
type_a = T::Utils.coerce(type_a)
|
type_a = T::Utils.coerce(type_a)
|
||||||
type_b = T::Utils.coerce(type_b)
|
type_b = T::Utils.coerce(type_b)
|
||||||
types = types.map {|t| T::Utils.coerce(t)} if !types.empty?
|
types = types.map { |t| T::Utils.coerce(t) } if !types.empty?
|
||||||
T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types)
|
T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types)
|
||||||
end
|
end
|
||||||
|
|
@ -4,5 +4,5 @@
|
|||||||
module T
|
module T
|
||||||
# T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`.
|
# T::Boolean is a type alias helper for the common `T.any(TrueClass, FalseClass)`.
|
||||||
# Defined separately from _types.rb because it has a dependency on T::Types::Union.
|
# Defined separately from _types.rb because it has a dependency on T::Types::Union.
|
||||||
Boolean = T.type_alias {T.any(TrueClass, FalseClass)}
|
Boolean = T.type_alias { T.any(TrueClass, FalseClass) }
|
||||||
end
|
end
|
@ -419,12 +419,12 @@ module T::Configuration
|
|||||||
if values.nil?
|
if values.nil?
|
||||||
@scalar_types = values
|
@scalar_types = values
|
||||||
else
|
else
|
||||||
bad_values = values.reject {|v| v.class == String}
|
bad_values = values.reject { |v| v.class == String }
|
||||||
unless bad_values.empty?
|
unless bad_values.empty?
|
||||||
raise ArgumentError.new("Provided values must all be class name strings.")
|
raise ArgumentError.new("Provided values must all be class name strings.")
|
||||||
end
|
end
|
||||||
|
|
||||||
@scalar_types = values.each_with_object({}) {|x, acc| acc[x] = true}.freeze
|
@scalar_types = values.each_with_object({}) { |x, acc| acc[x] = true }.freeze
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -449,9 +449,9 @@ module T::Configuration
|
|||||||
private_constant :MODULE_NAME
|
private_constant :MODULE_NAME
|
||||||
|
|
||||||
@default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7
|
@default_module_name_mangler = if T::Configuration::AT_LEAST_RUBY_2_7
|
||||||
->(type) {MODULE_NAME.bind_call(type)}
|
->(type) { MODULE_NAME.bind_call(type) }
|
||||||
else
|
else
|
||||||
->(type) {MODULE_NAME.bind(type).call} # rubocop:disable Performance/BindCall
|
->(type) { MODULE_NAME.bind(type).call } # rubocop:disable Performance/BindCall
|
||||||
end
|
end
|
||||||
|
|
||||||
@module_name_mangler = nil
|
@module_name_mangler = nil
|
@ -44,11 +44,11 @@ class T::Enum
|
|||||||
extend T::Props::CustomType
|
extend T::Props::CustomType
|
||||||
|
|
||||||
# TODO(jez) Might want to restrict this, or make subclasses provide this type
|
# TODO(jez) Might want to restrict this, or make subclasses provide this type
|
||||||
SerializedVal = T.type_alias {T.untyped}
|
SerializedVal = T.type_alias { T.untyped }
|
||||||
private_constant :SerializedVal
|
private_constant :SerializedVal
|
||||||
|
|
||||||
### Enum class methods ###
|
### Enum class methods ###
|
||||||
sig {returns(T::Array[T.attached_class])}
|
sig { returns(T::Array[T.attached_class]) }
|
||||||
def self.values
|
def self.values
|
||||||
if @values.nil?
|
if @values.nil?
|
||||||
raise "Attempting to access values of #{self.class} before it has been initialized." \
|
raise "Attempting to access values of #{self.class} before it has been initialized." \
|
||||||
@ -59,7 +59,7 @@ class T::Enum
|
|||||||
|
|
||||||
# This exists for compatibility with the interface of `Hash` & mostly to support
|
# This exists for compatibility with the interface of `Hash` & mostly to support
|
||||||
# the HashEachMethods Rubocop.
|
# the HashEachMethods Rubocop.
|
||||||
sig {params(blk: T.nilable(T.proc.params(arg0: T.attached_class).void)).returns(T.any(T::Enumerator[T.attached_class], T::Array[T.attached_class]))}
|
sig { params(blk: T.nilable(T.proc.params(arg0: T.attached_class).void)).returns(T.any(T::Enumerator[T.attached_class], T::Array[T.attached_class])) }
|
||||||
def self.each_value(&blk)
|
def self.each_value(&blk)
|
||||||
if blk
|
if blk
|
||||||
values.each(&blk)
|
values.each(&blk)
|
||||||
@ -72,7 +72,7 @@ class T::Enum
|
|||||||
#
|
#
|
||||||
# Note: It would have been nice to make this method final before people started overriding it.
|
# Note: It would have been nice to make this method final before people started overriding it.
|
||||||
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
||||||
sig {params(serialized_val: SerializedVal).returns(T.nilable(T.attached_class)).checked(:never)}
|
sig { params(serialized_val: SerializedVal).returns(T.nilable(T.attached_class)).checked(:never) }
|
||||||
def self.try_deserialize(serialized_val)
|
def self.try_deserialize(serialized_val)
|
||||||
if @mapping.nil?
|
if @mapping.nil?
|
||||||
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
||||||
@ -88,7 +88,7 @@ class T::Enum
|
|||||||
#
|
#
|
||||||
# @return [self]
|
# @return [self]
|
||||||
# @raise [KeyError] if serialized value does not match any instance.
|
# @raise [KeyError] if serialized value does not match any instance.
|
||||||
sig {overridable.params(serialized_val: SerializedVal).returns(T.attached_class).checked(:never)}
|
sig { overridable.params(serialized_val: SerializedVal).returns(T.attached_class).checked(:never) }
|
||||||
def self.from_serialized(serialized_val)
|
def self.from_serialized(serialized_val)
|
||||||
res = try_deserialize(serialized_val)
|
res = try_deserialize(serialized_val)
|
||||||
if res.nil?
|
if res.nil?
|
||||||
@ -99,7 +99,7 @@ class T::Enum
|
|||||||
|
|
||||||
# Note: It would have been nice to make this method final before people started overriding it.
|
# Note: It would have been nice to make this method final before people started overriding it.
|
||||||
# @return [Boolean] Does the given serialized value correspond with any of this enum's values.
|
# @return [Boolean] Does the given serialized value correspond with any of this enum's values.
|
||||||
sig {overridable.params(serialized_val: SerializedVal).returns(T::Boolean).checked(:never)}
|
sig { overridable.params(serialized_val: SerializedVal).returns(T::Boolean).checked(:never) }
|
||||||
def self.has_serialized?(serialized_val)
|
def self.has_serialized?(serialized_val)
|
||||||
if @mapping.nil?
|
if @mapping.nil?
|
||||||
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
||||||
@ -109,7 +109,7 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
||||||
sig {override.params(instance: T.nilable(T::Enum)).returns(SerializedVal).checked(:never)}
|
sig { override.params(instance: T.nilable(T::Enum)).returns(SerializedVal).checked(:never) }
|
||||||
def self.serialize(instance)
|
def self.serialize(instance)
|
||||||
# This is needed otherwise if a Chalk::ODM::Document with a property of the shape
|
# This is needed otherwise if a Chalk::ODM::Document with a property of the shape
|
||||||
# T::Hash[T.nilable(MyEnum), Integer] and a value that looks like {nil => 0} is
|
# T::Hash[T.nilable(MyEnum), Integer] and a value that looks like {nil => 0} is
|
||||||
@ -126,7 +126,7 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
||||||
sig {override.params(mongo_value: SerializedVal).returns(T.attached_class).checked(:never)}
|
sig { override.params(mongo_value: SerializedVal).returns(T.attached_class).checked(:never) }
|
||||||
def self.deserialize(mongo_value)
|
def self.deserialize(mongo_value)
|
||||||
if self == T::Enum
|
if self == T::Enum
|
||||||
raise "Cannot call T::Enum.deserialize directly. You must call on a specific child class."
|
raise "Cannot call T::Enum.deserialize directly. You must call on a specific child class."
|
||||||
@ -136,46 +136,46 @@ class T::Enum
|
|||||||
|
|
||||||
### Enum instance methods ###
|
### Enum instance methods ###
|
||||||
|
|
||||||
sig {returns(T.self_type)}
|
sig { returns(T.self_type) }
|
||||||
def dup
|
def dup
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(T.self_type).checked(:tests)}
|
sig { returns(T.self_type).checked(:tests) }
|
||||||
def clone
|
def clone
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
||||||
sig {returns(SerializedVal).checked(:never)}
|
sig { returns(SerializedVal).checked(:never) }
|
||||||
def serialize
|
def serialize
|
||||||
assert_bound!
|
assert_bound!
|
||||||
@serialized_val
|
@serialized_val
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(args: T.untyped).returns(T.untyped)}
|
sig { params(args: T.untyped).returns(T.untyped) }
|
||||||
def to_json(*args)
|
def to_json(*args)
|
||||||
serialize.to_json(*args)
|
serialize.to_json(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(args: T.untyped).returns(T.untyped)}
|
sig { params(args: T.untyped).returns(T.untyped) }
|
||||||
def as_json(*args)
|
def as_json(*args)
|
||||||
serialized_val = serialize
|
serialized_val = serialize
|
||||||
return serialized_val unless serialized_val.respond_to?(:as_json)
|
return serialized_val unless serialized_val.respond_to?(:as_json)
|
||||||
serialized_val.as_json(*args)
|
serialized_val.as_json(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(String)}
|
sig { returns(String) }
|
||||||
def to_s
|
def to_s
|
||||||
inspect
|
inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(String)}
|
sig { returns(String) }
|
||||||
def inspect
|
def inspect
|
||||||
"#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>"
|
"#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(other: BasicObject).returns(T.nilable(Integer))}
|
sig { params(other: BasicObject).returns(T.nilable(Integer)) }
|
||||||
def <=>(other)
|
def <=>(other)
|
||||||
case other
|
case other
|
||||||
when self.class
|
when self.class
|
||||||
@ -192,7 +192,7 @@ class T::Enum
|
|||||||
# responds to the `to_str` method. It does not actually call `to_str` however.
|
# responds to the `to_str` method. It does not actually call `to_str` however.
|
||||||
#
|
#
|
||||||
# See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D
|
# See https://ruby-doc.org/core-2.4.0/String.html#method-i-3D-3D
|
||||||
T::Sig::WithoutRuntime.sig {returns(String)}
|
T::Sig::WithoutRuntime.sig { returns(String) }
|
||||||
def to_str
|
def to_str
|
||||||
msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.'
|
msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.'
|
||||||
if T::Configuration.legacy_t_enum_migration_mode?
|
if T::Configuration.legacy_t_enum_migration_mode?
|
||||||
@ -200,7 +200,7 @@ class T::Enum
|
|||||||
msg,
|
msg,
|
||||||
storytime: {
|
storytime: {
|
||||||
class: self.class.name,
|
class: self.class.name,
|
||||||
caller_location: Kernel.caller_locations(1..1)&.[](0)&.then {"#{_1.path}:#{_1.lineno}"},
|
caller_location: Kernel.caller_locations(1..1)&.[](0)&.then { "#{_1.path}:#{_1.lineno}" },
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
serialize.to_s
|
serialize.to_s
|
||||||
@ -217,12 +217,12 @@ class T::Enum
|
|||||||
if T.unsafe(false)
|
if T.unsafe(false)
|
||||||
# Declare to the type system that the `serialize` method for sure exists
|
# Declare to the type system that the `serialize` method for sure exists
|
||||||
# on whatever we mix this into.
|
# on whatever we mix this into.
|
||||||
T::Sig::WithoutRuntime.sig {abstract.returns(T.untyped)}
|
T::Sig::WithoutRuntime.sig { abstract.returns(T.untyped) }
|
||||||
def serialize; end
|
def serialize; end
|
||||||
end
|
end
|
||||||
|
|
||||||
# WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
|
# WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
|
||||||
T::Sig::WithoutRuntime.sig {params(other: BasicObject).returns(T::Boolean)}
|
T::Sig::WithoutRuntime.sig { params(other: BasicObject).returns(T::Boolean) }
|
||||||
def ==(other)
|
def ==(other)
|
||||||
case other
|
case other
|
||||||
when String
|
when String
|
||||||
@ -238,7 +238,7 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
|
|
||||||
# WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
|
# WithoutRuntime so that comparison_assertion_failed can assume a constant stack depth
|
||||||
T::Sig::WithoutRuntime.sig {params(other: BasicObject).returns(T::Boolean)}
|
T::Sig::WithoutRuntime.sig { params(other: BasicObject).returns(T::Boolean) }
|
||||||
def ===(other)
|
def ===(other)
|
||||||
case other
|
case other
|
||||||
when String
|
when String
|
||||||
@ -255,7 +255,7 @@ class T::Enum
|
|||||||
|
|
||||||
# WithoutRuntime so that caller_locations can assume a constant stack depth
|
# WithoutRuntime so that caller_locations can assume a constant stack depth
|
||||||
# (Otherwise, the first call would be the method with the wrapping, which would have a different stack depth.)
|
# (Otherwise, the first call would be the method with the wrapping, which would have a different stack depth.)
|
||||||
T::Sig::WithoutRuntime.sig {params(method: Symbol, other: T.untyped).void}
|
T::Sig::WithoutRuntime.sig { params(method: Symbol, other: T.untyped).void }
|
||||||
private def comparison_assertion_failed(method, other)
|
private def comparison_assertion_failed(method, other)
|
||||||
T::Configuration.soft_assert_handler(
|
T::Configuration.soft_assert_handler(
|
||||||
'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration',
|
'Enum to string comparison not allowed. Compare to the Enum instance directly instead. See go/enum-migration',
|
||||||
@ -265,7 +265,7 @@ class T::Enum
|
|||||||
other: other,
|
other: other,
|
||||||
other_class: other.class.name,
|
other_class: other.class.name,
|
||||||
method: method,
|
method: method,
|
||||||
caller_location: Kernel.caller_locations(2..2)&.[](0)&.then {"#{_1.path}:#{_1.lineno}"},
|
caller_location: Kernel.caller_locations(2..2)&.[](0)&.then { "#{_1.path}:#{_1.lineno}" },
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -276,7 +276,7 @@ class T::Enum
|
|||||||
UNSET = T.let(Module.new.freeze, Module)
|
UNSET = T.let(Module.new.freeze, Module)
|
||||||
private_constant :UNSET
|
private_constant :UNSET
|
||||||
|
|
||||||
sig {params(serialized_val: SerializedVal).void}
|
sig { params(serialized_val: SerializedVal).void }
|
||||||
def initialize(serialized_val=UNSET)
|
def initialize(serialized_val=UNSET)
|
||||||
raise 'T::Enum is abstract' if self.class == T::Enum
|
raise 'T::Enum is abstract' if self.class == T::Enum
|
||||||
if !self.class.started_initializing?
|
if !self.class.started_initializing?
|
||||||
@ -292,7 +292,7 @@ class T::Enum
|
|||||||
self.class._register_instance(self)
|
self.class._register_instance(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(NilClass).checked(:never)}
|
sig { returns(NilClass).checked(:never) }
|
||||||
private def assert_bound!
|
private def assert_bound!
|
||||||
if @const_name.nil?
|
if @const_name.nil?
|
||||||
raise "Attempting to access Enum value on #{self.class} before it has been initialized." \
|
raise "Attempting to access Enum value on #{self.class} before it has been initialized." \
|
||||||
@ -300,14 +300,14 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(const_name: Symbol).void}
|
sig { params(const_name: Symbol).void }
|
||||||
def _bind_name(const_name)
|
def _bind_name(const_name)
|
||||||
@const_name = const_name
|
@const_name = const_name
|
||||||
@serialized_val = const_to_serialized_val(const_name) if @serialized_val.equal?(UNSET)
|
@serialized_val = const_to_serialized_val(const_name) if @serialized_val.equal?(UNSET)
|
||||||
freeze
|
freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(const_name: Symbol).returns(String)}
|
sig { params(const_name: Symbol).returns(String) }
|
||||||
private def const_to_serialized_val(const_name)
|
private def const_to_serialized_val(const_name)
|
||||||
# Historical note: We convert to lowercase names because the majority of existing calls to
|
# Historical note: We convert to lowercase names because the majority of existing calls to
|
||||||
# `make_accessible` were arrays of lowercase strings. Doing this conversion allowed for the
|
# `make_accessible` were arrays of lowercase strings. Doing this conversion allowed for the
|
||||||
@ -315,7 +315,7 @@ class T::Enum
|
|||||||
-const_name.to_s.downcase.freeze
|
-const_name.to_s.downcase.freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(T::Boolean)}
|
sig { returns(T::Boolean) }
|
||||||
def self.started_initializing?
|
def self.started_initializing?
|
||||||
unless defined?(@started_initializing)
|
unless defined?(@started_initializing)
|
||||||
@started_initializing = T.let(false, T.nilable(T::Boolean))
|
@started_initializing = T.let(false, T.nilable(T::Boolean))
|
||||||
@ -323,7 +323,7 @@ class T::Enum
|
|||||||
T.must(@started_initializing)
|
T.must(@started_initializing)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(T::Boolean)}
|
sig { returns(T::Boolean) }
|
||||||
def self.fully_initialized?
|
def self.fully_initialized?
|
||||||
unless defined?(@fully_initialized)
|
unless defined?(@fully_initialized)
|
||||||
@fully_initialized = T.let(false, T.nilable(T::Boolean))
|
@fully_initialized = T.let(false, T.nilable(T::Boolean))
|
||||||
@ -332,7 +332,7 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Maintains the order in which values are defined
|
# Maintains the order in which values are defined
|
||||||
sig {params(instance: T.untyped).void}
|
sig { params(instance: T.untyped).void }
|
||||||
def self._register_instance(instance)
|
def self._register_instance(instance)
|
||||||
@values ||= []
|
@values ||= []
|
||||||
@values << T.cast(instance, T.attached_class)
|
@values << T.cast(instance, T.attached_class)
|
||||||
@ -340,7 +340,7 @@ class T::Enum
|
|||||||
|
|
||||||
# Entrypoint for allowing people to register new enum values.
|
# Entrypoint for allowing people to register new enum values.
|
||||||
# All enum values must be defined within this block.
|
# All enum values must be defined within this block.
|
||||||
sig {params(blk: T.proc.void).void}
|
sig { params(blk: T.proc.void).void }
|
||||||
def self.enums(&blk)
|
def self.enums(&blk)
|
||||||
raise "enums cannot be defined for T::Enum" if self == T::Enum
|
raise "enums cannot be defined for T::Enum" if self == T::Enum
|
||||||
raise "Enum #{self} was already initialized" if fully_initialized?
|
raise "Enum #{self} was already initialized" if fully_initialized?
|
||||||
@ -375,13 +375,13 @@ class T::Enum
|
|||||||
|
|
||||||
orphaned_instances = T.must(@values) - @mapping.values
|
orphaned_instances = T.must(@values) - @mapping.values
|
||||||
if !orphaned_instances.empty?
|
if !orphaned_instances.empty?
|
||||||
raise "Enum values must be assigned to constants: #{orphaned_instances.map {|v| v.instance_variable_get('@serialized_val')}}"
|
raise "Enum values must be assigned to constants: #{orphaned_instances.map { |v| v.instance_variable_get('@serialized_val') }}"
|
||||||
end
|
end
|
||||||
|
|
||||||
@fully_initialized = true
|
@fully_initialized = true
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(child_class: T::Class[T.anything]).void}
|
sig { params(child_class: T::Class[T.anything]).void }
|
||||||
def self.inherited(child_class)
|
def self.inherited(child_class)
|
||||||
super
|
super
|
||||||
|
|
||||||
@ -394,12 +394,12 @@ class T::Enum
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Marshal support
|
# Marshal support
|
||||||
sig {params(_level: Integer).returns(String)}
|
sig { params(_level: Integer).returns(String) }
|
||||||
def _dump(_level)
|
def _dump(_level)
|
||||||
Marshal.dump(serialize)
|
Marshal.dump(serialize)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(args: String).returns(T.attached_class)}
|
sig { params(args: String).returns(T.attached_class) }
|
||||||
def self._load(args)
|
def self._load(args)
|
||||||
deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad
|
deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad
|
||||||
end
|
end
|
@ -4,7 +4,7 @@
|
|||||||
module T::NonForcingConstants
|
module T::NonForcingConstants
|
||||||
# NOTE: This method is documented on the RBI in Sorbet's payload, so that it
|
# NOTE: This method is documented on the RBI in Sorbet's payload, so that it
|
||||||
# shows up in the hover/completion documentation via LSP.
|
# shows up in the hover/completion documentation via LSP.
|
||||||
T::Sig::WithoutRuntime.sig {params(val: BasicObject, klass: String).returns(T::Boolean)}
|
T::Sig::WithoutRuntime.sig { params(val: BasicObject, klass: String).returns(T::Boolean) }
|
||||||
def self.non_forcing_is_a?(val, klass)
|
def self.non_forcing_is_a?(val, klass)
|
||||||
method_name = "T::NonForcingConstants.non_forcing_is_a?"
|
method_name = "T::NonForcingConstants.non_forcing_is_a?"
|
||||||
if klass.empty?
|
if klass.empty?
|
@ -25,7 +25,7 @@ module T::Private::Methods
|
|||||||
# twice is permitted). we could do this with two tables, but it seems slightly
|
# twice is permitted). we could do this with two tables, but it seems slightly
|
||||||
# cleaner with a single table.
|
# cleaner with a single table.
|
||||||
# Effectively T::Hash[Module, T.nilable(Set))]
|
# Effectively T::Hash[Module, T.nilable(Set))]
|
||||||
@modules_with_final = Hash.new {|hash, key| hash[key] = nil}.compare_by_identity
|
@modules_with_final = Hash.new { |hash, key| hash[key] = nil }.compare_by_identity
|
||||||
# this stores the old [included, extended] hooks for Module and inherited hook for Class that we override when
|
# this stores the old [included, extended] hooks for Module and inherited hook for Class that we override when
|
||||||
# enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the 'hooks'
|
# enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the 'hooks'
|
||||||
# in installed_hooks.
|
# in installed_hooks.
|
||||||
@ -168,7 +168,7 @@ module T::Private::Methods
|
|||||||
|
|
||||||
definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location
|
definition_file, definition_line = T::Private::Methods.signature_for_method(ancestor.instance_method(method_name)).method.source_location
|
||||||
is_redefined = target == ancestor
|
is_redefined = target == ancestor
|
||||||
caller_loc = T::Private::CallerUtils.find_caller {|loc| !loc.path.to_s.start_with?(SORBET_RUNTIME_LIB_PATH)}
|
caller_loc = T::Private::CallerUtils.find_caller { |loc| !loc.path.to_s.start_with?(SORBET_RUNTIME_LIB_PATH) }
|
||||||
extra_info = "\n"
|
extra_info = "\n"
|
||||||
if caller_loc
|
if caller_loc
|
||||||
extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
||||||
@ -471,7 +471,7 @@ module T::Private::Methods
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.all_checked_tests_sigs
|
def self.all_checked_tests_sigs
|
||||||
@signatures_by_method.values.select {|sig| sig.check_level == :tests}
|
@signatures_by_method.values.select { |sig| sig.check_level == :tests }
|
||||||
end
|
end
|
||||||
|
|
||||||
# the module target is adding the methods from the module source to itself. we need to check that for all instance
|
# the module target is adding the methods from the module source to itself. we need to check that for all instance
|
||||||
@ -589,6 +589,22 @@ module T::Private::Methods
|
|||||||
mod.extend(SingletonMethodHooks)
|
mod.extend(SingletonMethodHooks)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# `name` must be an instance method (for class methods, pass in mod.singleton_class)
|
||||||
|
def self.visibility_method_name(mod, name)
|
||||||
|
if mod.public_method_defined?(name)
|
||||||
|
:public
|
||||||
|
elsif mod.protected_method_defined?(name)
|
||||||
|
:protected
|
||||||
|
elsif mod.private_method_defined?(name)
|
||||||
|
:private
|
||||||
|
else
|
||||||
|
# Raises a NameError formatted like the Ruby VM would (the exact text formatting
|
||||||
|
# of these errors changed across Ruby VM versions, in ways that would sometimes
|
||||||
|
# cause tests to fail if they were dependent on hard coding errors).
|
||||||
|
mod.method(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# use this directly if you don't want/need to box up the method into an object to pass to method_to_key.
|
# use this directly if you don't want/need to box up the method into an object to pass to method_to_key.
|
||||||
private_class_method def self.method_owner_and_name_to_key(owner, name)
|
private_class_method def self.method_owner_and_name_to_key(owner, name)
|
||||||
"#{owner.object_id}##{name}"
|
"#{owner.object_id}##{name}"
|
@ -12,7 +12,7 @@ module T::Private::Methods::CallValidation
|
|||||||
# @param method_sig [T::Private::Methods::Signature]
|
# @param method_sig [T::Private::Methods::Signature]
|
||||||
# @return [UnboundMethod] the new wrapper method (or the original one if we didn't wrap it)
|
# @return [UnboundMethod] the new wrapper method (or the original one if we didn't wrap it)
|
||||||
def self.wrap_method_if_needed(mod, method_sig, original_method)
|
def self.wrap_method_if_needed(mod, method_sig, original_method)
|
||||||
original_visibility = visibility_method_name(mod, method_sig.method_name)
|
original_visibility = T::Private::Methods.visibility_method_name(mod, method_sig.method_name)
|
||||||
if method_sig.mode == T::Private::Methods::Modes.abstract
|
if method_sig.mode == T::Private::Methods::Modes.abstract
|
||||||
create_abstract_wrapper(mod, method_sig, original_method, original_visibility)
|
create_abstract_wrapper(mod, method_sig, original_method, original_visibility)
|
||||||
# Do nothing in this case; this method was not wrapped in _on_method_added.
|
# Do nothing in this case; this method was not wrapped in _on_method_added.
|
||||||
@ -69,11 +69,11 @@ module T::Private::Methods::CallValidation
|
|||||||
|
|
||||||
def self.create_validator_method(mod, original_method, method_sig, original_visibility)
|
def self.create_validator_method(mod, original_method, method_sig, original_visibility)
|
||||||
has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest &&
|
has_fixed_arity = method_sig.kwarg_types.empty? && !method_sig.has_rest && !method_sig.has_keyrest &&
|
||||||
original_method.parameters.all? {|(kind, _name)| kind == :req || kind == :block}
|
original_method.parameters.all? { |(kind, _name)| kind == :req || kind == :block }
|
||||||
can_skip_block_type = method_sig.block_type.nil? || method_sig.block_type.valid?(nil)
|
can_skip_block_type = method_sig.block_type.nil? || method_sig.block_type.valid?(nil)
|
||||||
ok_for_fast_path = has_fixed_arity && can_skip_block_type && !method_sig.bind && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
|
ok_for_fast_path = has_fixed_arity && can_skip_block_type && !method_sig.bind && method_sig.arg_types.length < 5 && is_allowed_to_have_fast_path
|
||||||
|
|
||||||
all_args_are_simple = ok_for_fast_path && method_sig.arg_types.all? {|_name, type| type.is_a?(T::Types::Simple)}
|
all_args_are_simple = ok_for_fast_path && method_sig.arg_types.all? { |_name, type| type.is_a?(T::Types::Simple) }
|
||||||
simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple)
|
simple_method = all_args_are_simple && method_sig.return_type.is_a?(T::Types::Simple)
|
||||||
simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void)
|
simple_procedure = all_args_are_simple && method_sig.return_type.is_a?(T::Private::Types::Void)
|
||||||
|
|
||||||
@ -330,19 +330,6 @@ module T::Private::Methods::CallValidation
|
|||||||
location: caller_loc
|
location: caller_loc
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# `name` must be an instance method (for class methods, pass in mod.singleton_class)
|
|
||||||
private_class_method def self.visibility_method_name(mod, name)
|
|
||||||
if mod.public_method_defined?(name)
|
|
||||||
:public
|
|
||||||
elsif mod.protected_method_defined?(name)
|
|
||||||
:protected
|
|
||||||
elsif mod.private_method_defined?(name)
|
|
||||||
:private
|
|
||||||
else
|
|
||||||
mod.method(name) # Raises
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if T::Configuration::AT_LEAST_RUBY_2_7
|
if T::Configuration::AT_LEAST_RUBY_2_7
|
@ -154,7 +154,12 @@ module T::Private::Methods
|
|||||||
case decl.mode
|
case decl.mode
|
||||||
when Modes.standard
|
when Modes.standard
|
||||||
decl.mode = Modes.override
|
decl.mode = Modes.override
|
||||||
decl.override_allow_incompatible = allow_incompatible
|
case allow_incompatible
|
||||||
|
when true, false, :visibility
|
||||||
|
decl.override_allow_incompatible = allow_incompatible
|
||||||
|
else
|
||||||
|
raise BuilderError.new(".override(allow_incompatible: ...) only accepts `true`, `false`, or `:visibility`, got: #{allow_incompatible.inspect}")
|
||||||
|
end
|
||||||
when Modes.override, Modes.overridable_override
|
when Modes.override, Modes.overridable_override
|
||||||
raise BuilderError.new(".override cannot be repeated in a single signature")
|
raise BuilderError.new(".override cannot be repeated in a single signature")
|
||||||
when Modes.overridable
|
when Modes.overridable
|
@ -68,14 +68,14 @@ class T::Private::Methods::Signature
|
|||||||
writer_method = !(raw_arg_types.size == 1 && raw_arg_types.key?(nil)) && parameters == UNNAMED_REQUIRED_PARAMETERS && method_name[-1] == "="
|
writer_method = !(raw_arg_types.size == 1 && raw_arg_types.key?(nil)) && parameters == UNNAMED_REQUIRED_PARAMETERS && method_name[-1] == "="
|
||||||
# For writer methods, map the single parameter to the method name without the "=" at the end
|
# For writer methods, map the single parameter to the method name without the "=" at the end
|
||||||
parameters = [[:req, method_name[0...-1].to_sym]] if writer_method
|
parameters = [[:req, method_name[0...-1].to_sym]] if writer_method
|
||||||
is_name_missing = parameters.any? {|_, name| !raw_arg_types.key?(name)}
|
is_name_missing = parameters.any? { |_, name| !raw_arg_types.key?(name) }
|
||||||
if is_name_missing
|
if is_name_missing
|
||||||
param_names = parameters.map {|_, name| name}
|
param_names = parameters.map { |_, name| name }
|
||||||
missing_names = param_names - raw_arg_types.keys
|
missing_names = param_names - raw_arg_types.keys
|
||||||
raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}"
|
raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}"
|
||||||
elsif parameters.length != raw_arg_types.size
|
elsif parameters.length != raw_arg_types.size
|
||||||
param_names = parameters.map {|_, name| name}
|
param_names = parameters.map { |_, name| name }
|
||||||
has_extra_names = parameters.count {|_, name| raw_arg_types.key?(name)} < raw_arg_types.size
|
has_extra_names = parameters.count { |_, name| raw_arg_types.key?(name) } < raw_arg_types.size
|
||||||
if has_extra_names
|
if has_extra_names
|
||||||
extra_names = raw_arg_types.keys - param_names
|
extra_names = raw_arg_types.keys - param_names
|
||||||
raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}"
|
raise "The declaration for `#{method.name}` has extra parameter(s): #{extra_names.join(', ')}"
|
||||||
@ -95,7 +95,7 @@ class T::Private::Methods::Signature
|
|||||||
# always precede optional keyword arguments. We can't tell
|
# always precede optional keyword arguments. We can't tell
|
||||||
# whether the culprit is the Ruby reordering or user error, so
|
# whether the culprit is the Ruby reordering or user error, so
|
||||||
# we error but include a note
|
# we error but include a note
|
||||||
if param_kind == :keyreq && parameters.any? {|k, _| k == :key}
|
if param_kind == :keyreq && parameters.any? { |k, _| k == :key }
|
||||||
hint = "\n\nNote: Any required keyword arguments must precede any optional keyword " \
|
hint = "\n\nNote: Any required keyword arguments must precede any optional keyword " \
|
||||||
"arguments. If your method declaration matches your `def`, try reordering any " \
|
"arguments. If your method declaration matches your `def`, try reordering any " \
|
||||||
"optional keyword parameters to the end of the method list."
|
"optional keyword parameters to the end of the method list."
|
||||||
@ -103,7 +103,7 @@ class T::Private::Methods::Signature
|
|||||||
|
|
||||||
raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \
|
raise "Parameter `#{type_name}` is declared out of order (declared as arg number " \
|
||||||
"#{i + 1}, defined in the method as arg number " \
|
"#{i + 1}, defined in the method as arg number " \
|
||||||
"#{parameters.index {|_, name| name == type_name} + 1}).#{hint}\nMethod: #{method_desc}"
|
"#{parameters.index { |_, name| name == type_name } + 1}).#{hint}\nMethod: #{method_desc}"
|
||||||
end
|
end
|
||||||
|
|
||||||
type = T::Utils.coerce(raw_type)
|
type = T::Utils.coerce(raw_type)
|
||||||
@ -245,8 +245,8 @@ class T::Private::Methods::Signature
|
|||||||
end
|
end
|
||||||
|
|
||||||
def force_type_init
|
def force_type_init
|
||||||
@arg_types.each {|_, type| type.build_type}
|
@arg_types.each { |_, type| type.build_type }
|
||||||
@kwarg_types.each {|_, type| type.build_type}
|
@kwarg_types.each { |_, type| type.build_type }
|
||||||
@block_type&.build_type
|
@block_type&.build_type
|
||||||
@rest_type&.build_type
|
@rest_type&.build_type
|
||||||
@keyrest_type&.build_type
|
@keyrest_type&.build_type
|
@ -72,7 +72,7 @@ module T::Private::Methods::SignatureValidation
|
|||||||
|
|
||||||
# If the super_method has any kwargs we can't build a
|
# If the super_method has any kwargs we can't build a
|
||||||
# Signature for it, so we'll just skip validation in that case.
|
# Signature for it, so we'll just skip validation in that case.
|
||||||
if !super_signature && !super_method.parameters.select {|kind, _| kind == :rest || kind == :kwrest}.empty?
|
if !super_signature && !super_method.parameters.select { |kind, _| kind == :rest || kind == :kwrest }.empty?
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
# super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use
|
# super_signature can be nil when we're overriding a method (perhaps a builtin) that didn't use
|
||||||
@ -89,6 +89,7 @@ module T::Private::Methods::SignatureValidation
|
|||||||
validate_override_mode(signature, super_signature)
|
validate_override_mode(signature, super_signature)
|
||||||
validate_override_shape(signature, super_signature)
|
validate_override_shape(signature, super_signature)
|
||||||
validate_override_types(signature, super_signature)
|
validate_override_types(signature, super_signature)
|
||||||
|
validate_override_visibility(signature, super_signature)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
validate_non_override_mode(signature)
|
validate_non_override_mode(signature)
|
||||||
@ -175,7 +176,7 @@ module T::Private::Methods::SignatureValidation
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.validate_override_shape(signature, super_signature)
|
def self.validate_override_shape(signature, super_signature)
|
||||||
return if signature.override_allow_incompatible
|
return if signature.override_allow_incompatible == true
|
||||||
return if super_signature.mode == Modes.untyped
|
return if super_signature.mode == Modes.untyped
|
||||||
|
|
||||||
method_name = signature.method_name
|
method_name = signature.method_name
|
||||||
@ -231,7 +232,7 @@ module T::Private::Methods::SignatureValidation
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.validate_override_types(signature, super_signature)
|
def self.validate_override_types(signature, super_signature)
|
||||||
return if signature.override_allow_incompatible
|
return if signature.override_allow_incompatible == true
|
||||||
return if super_signature.mode == Modes.untyped
|
return if super_signature.mode == Modes.untyped
|
||||||
return unless [signature, super_signature].all? do |sig|
|
return unless [signature, super_signature].all? do |sig|
|
||||||
sig.check_level == :always || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
|
sig.check_level == :always || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
|
||||||
@ -276,6 +277,38 @@ module T::Private::Methods::SignatureValidation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.validate_override_visibility(signature, super_signature)
|
||||||
|
return if super_signature.mode == Modes.untyped
|
||||||
|
# This departs from the behavior of other `validate_override_whatever` functions in that it
|
||||||
|
# only comes into effect when the child signature explicitly says the word `override`. This was
|
||||||
|
# done because the primary method for silencing these errors (`allow_incompatible: :visibility`)
|
||||||
|
# requires an `override` node to attach to. Once we have static override checking for implicitly
|
||||||
|
# overridden methods, we can remove this.
|
||||||
|
return unless [Modes.override, Modes.overridable_override].include?(signature.mode)
|
||||||
|
return if [:visibility, true].include?(signature.override_allow_incompatible)
|
||||||
|
method = signature.method
|
||||||
|
super_method = super_signature.method
|
||||||
|
mode_noun = super_signature.mode == Modes.abstract ? 'implementation' : 'override'
|
||||||
|
vis = method_visibility(method)
|
||||||
|
super_vis = method_visibility(super_method)
|
||||||
|
|
||||||
|
if visibility_strength(vis) > visibility_strength(super_vis)
|
||||||
|
raise "Incompatible visibility for #{mode_noun} of method #{method.name}\n" \
|
||||||
|
"* Base: #{super_vis} (in #{method_loc_str(super_method)})\n" \
|
||||||
|
"* #{mode_noun.capitalize}: #{vis} (in #{method_loc_str(method)})\n" \
|
||||||
|
"(The override must be at least as permissive as the supermethod)" \
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private_class_method def self.method_visibility(method)
|
||||||
|
T::Private::Methods.visibility_method_name(method.owner, method.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Higher = more restrictive.
|
||||||
|
private_class_method def self.visibility_strength(vis)
|
||||||
|
%i[public protected private].find_index(vis)
|
||||||
|
end
|
||||||
|
|
||||||
private_class_method def self.base_override_loc_str(signature, super_signature)
|
private_class_method def self.base_override_loc_str(signature, super_signature)
|
||||||
mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override'
|
mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override'
|
||||||
"\n * Base definition: in #{method_loc_str(super_signature.method)}" \
|
"\n * Base definition: in #{method_loc_str(super_signature.method)}" \
|
@ -5,7 +5,7 @@ module T::Private
|
|||||||
module MixesInClassMethods
|
module MixesInClassMethods
|
||||||
def included(other)
|
def included(other)
|
||||||
mods = Abstract::Data.get(self, :class_methods_mixins)
|
mods = Abstract::Data.get(self, :class_methods_mixins)
|
||||||
mods.each {|mod| other.extend(mod)}
|
mods.each { |mod| other.extend(mod) }
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -32,7 +32,7 @@ module T::Private::RuntimeLevels
|
|||||||
def self.enable_checking_in_tests
|
def self.enable_checking_in_tests
|
||||||
if !@check_tests && @wrapped_tests_with_validation
|
if !@check_tests && @wrapped_tests_with_validation
|
||||||
all_checked_tests_sigs = T::Private::Methods.all_checked_tests_sigs
|
all_checked_tests_sigs = T::Private::Methods.all_checked_tests_sigs
|
||||||
locations = all_checked_tests_sigs.map {|sig| sig.method.source_location.join(':')}.join("\n- ")
|
locations = all_checked_tests_sigs.map { |sig| sig.method.source_location.join(':') }.join("\n- ")
|
||||||
raise "Toggle `:tests`-level runtime type checking earlier. " \
|
raise "Toggle `:tests`-level runtime type checking earlier. " \
|
||||||
"There are already some methods wrapped with `sig.checked(:tests)`:\n" \
|
"There are already some methods wrapped with `sig.checked(:tests)`:\n" \
|
||||||
"- #{locations}"
|
"- #{locations}"
|
@ -5,7 +5,7 @@ module T::Private::Sealed
|
|||||||
module NoInherit
|
module NoInherit
|
||||||
def inherited(child)
|
def inherited(child)
|
||||||
super
|
super
|
||||||
caller_loc = T::Private::CallerUtils.find_caller {|loc| loc.base_label != 'inherited'}
|
caller_loc = T::Private::CallerUtils.find_caller { |loc| loc.base_label != 'inherited' }
|
||||||
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'inherited')
|
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'inherited')
|
||||||
@sorbet_sealed_module_all_subclasses << child
|
@sorbet_sealed_module_all_subclasses << child
|
||||||
end
|
end
|
||||||
@ -22,14 +22,14 @@ module T::Private::Sealed
|
|||||||
module NoIncludeExtend
|
module NoIncludeExtend
|
||||||
def included(child)
|
def included(child)
|
||||||
super
|
super
|
||||||
caller_loc = T::Private::CallerUtils.find_caller {|loc| loc.base_label != 'included'}
|
caller_loc = T::Private::CallerUtils.find_caller { |loc| loc.base_label != 'included' }
|
||||||
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'included')
|
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'included')
|
||||||
@sorbet_sealed_module_all_subclasses << child
|
@sorbet_sealed_module_all_subclasses << child
|
||||||
end
|
end
|
||||||
|
|
||||||
def extended(child)
|
def extended(child)
|
||||||
super
|
super
|
||||||
caller_loc = T::Private::CallerUtils.find_caller {|loc| loc.base_label != 'extended'}
|
caller_loc = T::Private::CallerUtils.find_caller { |loc| loc.base_label != 'extended' }
|
||||||
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'extended')
|
T::Private::Sealed.validate_inheritance(caller_loc, self, child, 'extended')
|
||||||
@sorbet_sealed_module_all_subclasses << child
|
@sorbet_sealed_module_all_subclasses << child
|
||||||
end
|
end
|
||||||
@ -81,7 +81,7 @@ module T::Private::Sealed
|
|||||||
|
|
||||||
if !this_file.start_with?(decl_file)
|
if !this_file.start_with?(decl_file)
|
||||||
whitelist = T::Configuration.sealed_violation_whitelist
|
whitelist = T::Configuration.sealed_violation_whitelist
|
||||||
if !whitelist.nil? && whitelist.any? {|pattern| this_file =~ pattern}
|
if !whitelist.nil? && whitelist.any? { |pattern| this_file =~ pattern }
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -109,7 +109,7 @@ module T::Props
|
|||||||
# form.
|
# form.
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
sig {params(name: Symbol, cls: T.untyped, rules: T.untyped).void}
|
sig { params(name: Symbol, cls: T.untyped, rules: T.untyped).void }
|
||||||
def prop(name, cls, **rules)
|
def prop(name, cls, **rules)
|
||||||
cls = T::Utils.coerce(cls) if !cls.is_a?(Module)
|
cls = T::Utils.coerce(cls) if !cls.is_a?(Module)
|
||||||
decorator.prop_defined(name, cls, rules)
|
decorator.prop_defined(name, cls, rules)
|
||||||
@ -132,7 +132,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Shorthand helper to define a `prop` with `immutable => true`
|
# Shorthand helper to define a `prop` with `immutable => true`
|
||||||
sig {params(name: Symbol, cls_or_args: T.untyped, args: T.untyped).void}
|
sig { params(name: Symbol, cls_or_args: T.untyped, args: T.untyped).void }
|
||||||
def const(name, cls_or_args, **args)
|
def const(name, cls_or_args, **args)
|
||||||
if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable)
|
if (cls_or_args.is_a?(Hash) && cls_or_args.key?(:immutable)) || args.key?(:immutable)
|
||||||
Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop")
|
Kernel.raise ArgumentError.new("Cannot pass 'immutable' argument when using 'const' keyword to define a prop")
|
@ -15,7 +15,7 @@ module T::Props::Constructor::DecoratorMethods
|
|||||||
# we'll use to check for any unrecognized input.)
|
# we'll use to check for any unrecognized input.)
|
||||||
#
|
#
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {params(instance: T::Props::Constructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
sig { params(instance: T::Props::Constructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never) }
|
||||||
def construct_props_without_defaults(instance, hash)
|
def construct_props_without_defaults(instance, hash)
|
||||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||||
# and therefore allocates for each entry.
|
# and therefore allocates for each entry.
|
@ -39,7 +39,7 @@ module T::Props
|
|||||||
#
|
#
|
||||||
# @param [Object] instance
|
# @param [Object] instance
|
||||||
# @return An instance of one of T::Configuration.scalar_types
|
# @return An instance of one of T::Configuration.scalar_types
|
||||||
sig {abstract.params(instance: T.untyped).returns(T.untyped).checked(:never)}
|
sig { abstract.params(instance: T.untyped).returns(T.untyped).checked(:never) }
|
||||||
def serialize(instance); end
|
def serialize(instance); end
|
||||||
|
|
||||||
# Given the serialized form of your type, this returns an instance
|
# Given the serialized form of your type, this returns an instance
|
||||||
@ -47,17 +47,17 @@ module T::Props
|
|||||||
#
|
#
|
||||||
# @param scalar One of T::Configuration.scalar_types
|
# @param scalar One of T::Configuration.scalar_types
|
||||||
# @return Object
|
# @return Object
|
||||||
sig {abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never)}
|
sig { abstract.params(scalar: T.untyped).returns(T.untyped).checked(:never) }
|
||||||
def deserialize(scalar); end
|
def deserialize(scalar); end
|
||||||
|
|
||||||
sig {override.params(_base: Module).void}
|
sig { override.params(_base: Module).void }
|
||||||
def self.included(_base)
|
def self.included(_base)
|
||||||
super
|
super
|
||||||
|
|
||||||
raise 'Please use "extend", not "include" to attach this module'
|
raise 'Please use "extend", not "include" to attach this module'
|
||||||
end
|
end
|
||||||
|
|
||||||
sig(:final) {params(val: T.untyped).returns(T::Boolean).checked(:never)}
|
sig(:final) { params(val: T.untyped).returns(T::Boolean).checked(:never) }
|
||||||
def self.scalar_type?(val)
|
def self.scalar_type?(val)
|
||||||
# We don't need to check for val's included modules in
|
# We don't need to check for val's included modules in
|
||||||
# T::Configuration.scalar_types, because T::Configuration.scalar_types
|
# T::Configuration.scalar_types, because T::Configuration.scalar_types
|
||||||
@ -74,7 +74,7 @@ module T::Props
|
|||||||
# implement set-like fields that store a unique-array, but forbid
|
# implement set-like fields that store a unique-array, but forbid
|
||||||
# hashes; Custom hash types should be implemented via an emebdded
|
# hashes; Custom hash types should be implemented via an emebdded
|
||||||
# T::Struct (or a subclass like Chalk::ODM::Document) or via T.
|
# T::Struct (or a subclass like Chalk::ODM::Document) or via T.
|
||||||
sig(:final) {params(val: Object).returns(T::Boolean).checked(:never)}
|
sig(:final) { params(val: Object).returns(T::Boolean).checked(:never) }
|
||||||
def self.valid_serialization?(val)
|
def self.valid_serialization?(val)
|
||||||
case val
|
case val
|
||||||
when Array
|
when Array
|
@ -10,17 +10,17 @@
|
|||||||
class T::Props::Decorator
|
class T::Props::Decorator
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
Rules = T.type_alias {T::Hash[Symbol, T.untyped]}
|
Rules = T.type_alias { T::Hash[Symbol, T.untyped] }
|
||||||
DecoratedInstance = T.type_alias {Object} # Would be T::Props, but that produces circular reference errors in some circumstances
|
DecoratedInstance = T.type_alias { Object } # Would be T::Props, but that produces circular reference errors in some circumstances
|
||||||
PropType = T.type_alias {T::Types::Base}
|
PropType = T.type_alias { T::Types::Base }
|
||||||
PropTypeOrClass = T.type_alias {T.any(PropType, Module)}
|
PropTypeOrClass = T.type_alias { T.any(PropType, Module) }
|
||||||
|
|
||||||
class NoRulesError < StandardError; end
|
class NoRulesError < StandardError; end
|
||||||
|
|
||||||
EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules], checked: false)
|
EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules], checked: false)
|
||||||
private_constant :EMPTY_PROPS
|
private_constant :EMPTY_PROPS
|
||||||
|
|
||||||
sig {params(klass: T.untyped).void.checked(:never)}
|
sig { params(klass: T.untyped).void.checked(:never) }
|
||||||
def initialize(klass)
|
def initialize(klass)
|
||||||
@class = T.let(klass, T.all(Module, T::Props::ClassMethods))
|
@class = T.let(klass, T.all(Module, T::Props::ClassMethods))
|
||||||
@class.plugins.each do |mod|
|
@class.plugins.each do |mod|
|
||||||
@ -30,22 +30,22 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(prop accesses)
|
# checked(:never) - O(prop accesses)
|
||||||
sig {returns(T::Hash[Symbol, Rules]).checked(:never)}
|
sig { returns(T::Hash[Symbol, Rules]).checked(:never) }
|
||||||
attr_reader :props
|
attr_reader :props
|
||||||
|
|
||||||
sig {returns(T::Array[Symbol])}
|
sig { returns(T::Array[Symbol]) }
|
||||||
def all_props
|
def all_props
|
||||||
props.keys
|
props.keys
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(prop accesses)
|
# checked(:never) - O(prop accesses)
|
||||||
sig {params(prop: T.any(Symbol, String)).returns(Rules).checked(:never)}
|
sig { params(prop: T.any(Symbol, String)).returns(Rules).checked(:never) }
|
||||||
def prop_rules(prop)
|
def prop_rules(prop)
|
||||||
props[prop.to_sym] || raise("No such prop: #{prop.inspect}")
|
props[prop.to_sym] || raise("No such prop: #{prop.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - Rules hash is expensive to check
|
# checked(:never) - Rules hash is expensive to check
|
||||||
sig {params(prop: Symbol, rules: Rules).void.checked(:never)}
|
sig { params(prop: Symbol, rules: Rules).void.checked(:never) }
|
||||||
def add_prop_definition(prop, rules)
|
def add_prop_definition(prop, rules)
|
||||||
override = rules.delete(:override)
|
override = rules.delete(:override)
|
||||||
|
|
||||||
@ -79,16 +79,16 @@ class T::Props::Decorator
|
|||||||
extra
|
extra
|
||||||
setter_validate
|
setter_validate
|
||||||
_tnilable
|
_tnilable
|
||||||
].to_h {|k| [k, true]}.freeze, T::Hash[Symbol, T::Boolean], checked: false)
|
].to_h { |k| [k, true] }.freeze, T::Hash[Symbol, T::Boolean], checked: false)
|
||||||
private_constant :VALID_RULE_KEYS
|
private_constant :VALID_RULE_KEYS
|
||||||
|
|
||||||
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
sig { params(key: Symbol).returns(T::Boolean).checked(:never) }
|
||||||
def valid_rule_key?(key)
|
def valid_rule_key?(key)
|
||||||
!!VALID_RULE_KEYS[key]
|
!!VALID_RULE_KEYS[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(prop accesses)
|
# checked(:never) - O(prop accesses)
|
||||||
sig {returns(T.all(Module, T::Props::ClassMethods)).checked(:never)}
|
sig { returns(T.all(Module, T::Props::ClassMethods)).checked(:never) }
|
||||||
def decorated_class
|
def decorated_class
|
||||||
@class
|
@class
|
||||||
end
|
end
|
||||||
@ -98,7 +98,7 @@ class T::Props::Decorator
|
|||||||
# Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it.
|
# Use this to validate that a value will validate for a given prop. Useful for knowing whether a value can be set on a model without setting it.
|
||||||
#
|
#
|
||||||
# checked(:never) - potentially O(prop accesses) depending on usage pattern
|
# checked(:never) - potentially O(prop accesses) depending on usage pattern
|
||||||
sig {params(prop: Symbol, val: T.untyped).void.checked(:never)}
|
sig { params(prop: Symbol, val: T.untyped).void.checked(:never) }
|
||||||
def validate_prop_value(prop, val)
|
def validate_prop_value(prop, val)
|
||||||
prop_rules(prop).fetch(:value_validate_proc).call(val)
|
prop_rules(prop).fetch(:value_validate_proc).call(val)
|
||||||
end
|
end
|
||||||
@ -202,7 +202,7 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
|
|
||||||
# TODO: we should really be checking all the methods on `cls`, not just Object
|
# TODO: we should really be checking all the methods on `cls`, not just Object
|
||||||
BANNED_METHOD_NAMES = T.let(Object.instance_methods.each_with_object({}) {|x, acc| acc[x] = true}.freeze, T::Hash[Symbol, TrueClass], checked: false)
|
BANNED_METHOD_NAMES = T.let(Object.instance_methods.each_with_object({}) { |x, acc| acc[x] = true }.freeze, T::Hash[Symbol, TrueClass], checked: false)
|
||||||
|
|
||||||
# checked(:never) - Rules hash is expensive to check
|
# checked(:never) - Rules hash is expensive to check
|
||||||
sig do
|
sig do
|
||||||
@ -223,7 +223,7 @@ class T::Props::Decorator
|
|||||||
"to 'sensitivity:' (in prop #{@class.name}.#{name})")
|
"to 'sensitivity:' (in prop #{@class.name}.#{name})")
|
||||||
end
|
end
|
||||||
|
|
||||||
if rules.keys.any? {|k| !valid_rule_key?(k)}
|
if rules.keys.any? { |k| !valid_rule_key?(k) }
|
||||||
raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
|
raise ArgumentError.new("At least one invalid prop arg supplied in #{self}: #{rules.keys.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ class T::Props::Decorator
|
|||||||
SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp, checked: false)
|
SAFE_NAME = T.let(/\A[A-Za-z_][A-Za-z0-9_-]*\z/.freeze, Regexp, checked: false)
|
||||||
|
|
||||||
# Used to validate both prop names and serialized forms
|
# Used to validate both prop names and serialized forms
|
||||||
sig {params(name: T.any(Symbol, String)).void.checked(:never)}
|
sig { params(name: T.any(Symbol, String)).void.checked(:never) }
|
||||||
private def validate_prop_name(name)
|
private def validate_prop_name(name)
|
||||||
if !name.match?(SAFE_NAME)
|
if !name.match?(SAFE_NAME)
|
||||||
raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}")
|
raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}")
|
||||||
@ -255,7 +255,7 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
|
|
||||||
# This converts the type from a T::Type to a regular old ruby class.
|
# This converts the type from a T::Type to a regular old ruby class.
|
||||||
sig {params(type: T::Types::Base).returns(Module).checked(:never)}
|
sig { params(type: T::Types::Base).returns(Module).checked(:never) }
|
||||||
private def convert_type_to_class(type)
|
private def convert_type_to_class(type)
|
||||||
case type
|
case type
|
||||||
when T::Types::TypedArray, T::Types::FixedArray
|
when T::Types::TypedArray, T::Types::FixedArray
|
||||||
@ -392,7 +392,7 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - Rules hash is expensive to check
|
# checked(:never) - Rules hash is expensive to check
|
||||||
sig {params(name: Symbol, rules: Rules).void.checked(:never)}
|
sig { params(name: Symbol, rules: Rules).void.checked(:never) }
|
||||||
private def define_getter_and_setter(name, rules)
|
private def define_getter_and_setter(name, rules)
|
||||||
T::Configuration.without_ruby_warnings do
|
T::Configuration.without_ruby_warnings do
|
||||||
if !rules[:immutable]
|
if !rules[:immutable]
|
||||||
@ -440,7 +440,7 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - Rules hash is expensive to check
|
# checked(:never) - Rules hash is expensive to check
|
||||||
sig {params(prop_name: Symbol, rules: Rules).void.checked(:never)}
|
sig { params(prop_name: Symbol, rules: Rules).void.checked(:never) }
|
||||||
private def validate_not_missing_sensitivity(prop_name, rules)
|
private def validate_not_missing_sensitivity(prop_name, rules)
|
||||||
if rules[:sensitivity].nil?
|
if rules[:sensitivity].nil?
|
||||||
if rules[:redaction]
|
if rules[:redaction]
|
||||||
@ -612,7 +612,7 @@ class T::Props::Decorator
|
|||||||
#
|
#
|
||||||
# This gets called when a module or class that extends T::Props gets included, extended,
|
# This gets called when a module or class that extends T::Props gets included, extended,
|
||||||
# prepended, or inherited.
|
# prepended, or inherited.
|
||||||
sig {params(child: Module).void.checked(:never)}
|
sig { params(child: Module).void.checked(:never) }
|
||||||
def model_inherited(child)
|
def model_inherited(child)
|
||||||
child.extend(T::Props::ClassMethods)
|
child.extend(T::Props::ClassMethods)
|
||||||
child = T.cast(child, T.all(Module, T::Props::ClassMethods))
|
child = T.cast(child, T.all(Module, T::Props::ClassMethods))
|
||||||
@ -656,19 +656,19 @@ class T::Props::Decorator
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)}
|
sig { params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never) }
|
||||||
private def clobber_getter?(child, prop)
|
private def clobber_getter?(child, prop)
|
||||||
!!(child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
|
!!(child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
|
||||||
child.instance_method(prop).source_location&.first == __FILE__)
|
child.instance_method(prop).source_location&.first == __FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never)}
|
sig { params(child: T.all(Module, T::Props::ClassMethods), prop: Symbol).returns(T::Boolean).checked(:never) }
|
||||||
private def clobber_setter?(child, prop)
|
private def clobber_setter?(child, prop)
|
||||||
!!(child.decorator.method(:prop_set).owner != method(:prop_set).owner &&
|
!!(child.decorator.method(:prop_set).owner != method(:prop_set).owner &&
|
||||||
child.instance_method("#{prop}=").source_location&.first == __FILE__)
|
child.instance_method("#{prop}=").source_location&.first == __FILE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(mod: Module).void.checked(:never)}
|
sig { params(mod: Module).void.checked(:never) }
|
||||||
def plugin(mod)
|
def plugin(mod)
|
||||||
decorated_class.plugins << mod
|
decorated_class.plugins << mod
|
||||||
T::Props::Plugin::Private.apply_class_methods(mod, decorated_class)
|
T::Props::Plugin::Private.apply_class_methods(mod, decorated_class)
|
@ -159,7 +159,7 @@ module T::Props
|
|||||||
assert_equal(:resbody, rescue_body.type)
|
assert_equal(:resbody, rescue_body.type)
|
||||||
exceptions, assignment, handler = rescue_body.children
|
exceptions, assignment, handler = rescue_body.children
|
||||||
assert_equal(:array, exceptions.type)
|
assert_equal(:array, exceptions.type)
|
||||||
exceptions.children.each {|c| assert_equal(:const, c.type)}
|
exceptions.children.each { |c| assert_equal(:const, c.type) }
|
||||||
assert_equal(:lvasgn, assignment.type)
|
assert_equal(:lvasgn, assignment.type)
|
||||||
assert_equal([:e], assignment.children)
|
assert_equal([:e], assignment.children)
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ module T::Props
|
|||||||
receiver, method, *args = deserialization_error.children
|
receiver, method, *args = deserialization_error.children
|
||||||
assert_equal(nil, receiver)
|
assert_equal(nil, receiver)
|
||||||
assert_equal(:raise_deserialization_error, method)
|
assert_equal(:raise_deserialization_error, method)
|
||||||
args.each {|a| validate_lack_of_side_effects(a, whitelisted_methods_for_deserialize)}
|
args.each { |a| validate_lack_of_side_effects(a, whitelisted_methods_for_deserialize) }
|
||||||
|
|
||||||
validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize)
|
validate_lack_of_side_effects(val_return, whitelisted_methods_for_deserialize)
|
||||||
else
|
else
|
||||||
@ -222,12 +222,12 @@ module T::Props
|
|||||||
# Primitives & self are ok
|
# Primitives & self are ok
|
||||||
when :lvar, :arg, :ivar
|
when :lvar, :arg, :ivar
|
||||||
# Reading local & instance variables & arguments is ok
|
# Reading local & instance variables & arguments is ok
|
||||||
unless node.children.all? {|c| c.is_a?(Symbol)}
|
unless node.children.all? { |c| c.is_a?(Symbol) }
|
||||||
raise ValidationError.new("Unexpected child for #{node.type}: #{node.inspect}")
|
raise ValidationError.new("Unexpected child for #{node.type}: #{node.inspect}")
|
||||||
end
|
end
|
||||||
when :args, :mlhs, :block, :begin, :if
|
when :args, :mlhs, :block, :begin, :if
|
||||||
# Blocks etc are read-only if their contents are read-only
|
# Blocks etc are read-only if their contents are read-only
|
||||||
node.children.each {|c| validate_lack_of_side_effects(c, whitelisted_methods_by_receiver_type) if c}
|
node.children.each { |c| validate_lack_of_side_effects(c, whitelisted_methods_by_receiver_type) if c }
|
||||||
when :send
|
when :send
|
||||||
# Sends are riskier so check a whitelist
|
# Sends are riskier so check a whitelist
|
||||||
receiver, method, *args = node.children
|
receiver, method, *args = node.children
|
@ -30,12 +30,12 @@ module T::Props
|
|||||||
#
|
#
|
||||||
# Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!`
|
# Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!`
|
||||||
# from working.
|
# from working.
|
||||||
sig {void}
|
sig { void }
|
||||||
def self.disable_lazy_evaluation!
|
def self.disable_lazy_evaluation!
|
||||||
@lazy_evaluation_disabled ||= true
|
@lazy_evaluation_disabled ||= true
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(T::Boolean)}
|
sig { returns(T::Boolean) }
|
||||||
def self.lazy_evaluation_enabled?
|
def self.lazy_evaluation_enabled?
|
||||||
!defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled
|
!defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled
|
||||||
end
|
end
|
||||||
@ -43,17 +43,17 @@ module T::Props
|
|||||||
module DecoratorMethods
|
module DecoratorMethods
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
sig {returns(T::Hash[Symbol, T.proc.returns(String)]).checked(:never)}
|
sig { returns(T::Hash[Symbol, T.proc.returns(String)]).checked(:never) }
|
||||||
private def lazily_defined_methods
|
private def lazily_defined_methods
|
||||||
@lazily_defined_methods ||= {}
|
@lazily_defined_methods ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {returns(T::Hash[Symbol, T.untyped]).checked(:never)}
|
sig { returns(T::Hash[Symbol, T.untyped]).checked(:never) }
|
||||||
private def lazily_defined_vm_methods
|
private def lazily_defined_vm_methods
|
||||||
@lazily_defined_vm_methods ||= {}
|
@lazily_defined_vm_methods ||= {}
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(name: Symbol).void}
|
sig { params(name: Symbol).void }
|
||||||
private def eval_lazily_defined_method!(name)
|
private def eval_lazily_defined_method!(name)
|
||||||
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
||||||
raise SourceEvaluationDisabled.new
|
raise SourceEvaluationDisabled.new
|
||||||
@ -68,7 +68,7 @@ module T::Props
|
|||||||
cls.send(:private, name)
|
cls.send(:private, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(name: Symbol).void}
|
sig { params(name: Symbol).void }
|
||||||
private def eval_lazily_defined_vm_method!(name)
|
private def eval_lazily_defined_vm_method!(name)
|
||||||
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
||||||
raise SourceEvaluationDisabled.new
|
raise SourceEvaluationDisabled.new
|
||||||
@ -80,7 +80,7 @@ module T::Props
|
|||||||
cls.send(:private, name)
|
cls.send(:private, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(name: Symbol, blk: T.proc.returns(String)).void}
|
sig { params(name: Symbol, blk: T.proc.returns(String)).void }
|
||||||
private def enqueue_lazy_method_definition!(name, &blk)
|
private def enqueue_lazy_method_definition!(name, &blk)
|
||||||
lazily_defined_methods[name] = blk
|
lazily_defined_methods[name] = blk
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ module T::Props
|
|||||||
cls.send(:private, name)
|
cls.send(:private, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(name: Symbol, blk: T.untyped).void}
|
sig { params(name: Symbol, blk: T.untyped).void }
|
||||||
private def enqueue_lazy_vm_method_definition!(name, &blk)
|
private def enqueue_lazy_vm_method_definition!(name, &blk)
|
||||||
lazily_defined_vm_methods[name] = blk
|
lazily_defined_vm_methods[name] = blk
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ module T::Props
|
|||||||
cls.send(:private, name)
|
cls.send(:private, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {void}
|
sig { void }
|
||||||
def eagerly_define_lazy_methods!
|
def eagerly_define_lazy_methods!
|
||||||
return if lazily_defined_methods.empty?
|
return if lazily_defined_methods.empty?
|
||||||
|
|
||||||
@ -125,18 +125,18 @@ module T::Props
|
|||||||
|
|
||||||
cls = decorated_class
|
cls = decorated_class
|
||||||
cls.class_eval(source)
|
cls.class_eval(source)
|
||||||
lazily_defined_methods.each_key {|name| cls.send(:private, name)}
|
lazily_defined_methods.each_key { |name| cls.send(:private, name) }
|
||||||
lazily_defined_methods.clear
|
lazily_defined_methods.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {void}
|
sig { void }
|
||||||
def eagerly_define_lazy_vm_methods!
|
def eagerly_define_lazy_vm_methods!
|
||||||
return if lazily_defined_vm_methods.empty?
|
return if lazily_defined_vm_methods.empty?
|
||||||
|
|
||||||
lazily_defined_vm_methods.values.map(&:call)
|
lazily_defined_vm_methods.values.map(&:call)
|
||||||
|
|
||||||
cls = decorated_class
|
cls = decorated_class
|
||||||
lazily_defined_vm_methods.each_key {|name| cls.send(:private, name)}
|
lazily_defined_vm_methods.each_key { |name| cls.send(:private, name) }
|
||||||
lazily_defined_vm_methods.clear
|
lazily_defined_vm_methods.clear
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -43,11 +43,11 @@ module T::Props::Optional::DecoratorMethods
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {returns(T::Hash[Symbol, T::Props::Private::ApplyDefault]).checked(:never)}
|
sig { returns(T::Hash[Symbol, T::Props::Private::ApplyDefault]).checked(:never) }
|
||||||
attr_reader :props_with_defaults
|
attr_reader :props_with_defaults
|
||||||
|
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {returns(T::Hash[Symbol, T::Props::Private::SetterFactory::SetterProc]).checked(:never)}
|
sig { returns(T::Hash[Symbol, T::Props::Private::SetterFactory::SetterProc]).checked(:never) }
|
||||||
attr_reader :props_without_defaults
|
attr_reader :props_without_defaults
|
||||||
|
|
||||||
def add_prop_definition(prop, rules)
|
def add_prop_definition(prop, rules)
|
@ -49,21 +49,21 @@ module T::Props::PrettyPrintable
|
|||||||
module DecoratorMethods
|
module DecoratorMethods
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
sig { params(key: Symbol).returns(T::Boolean).checked(:never) }
|
||||||
def valid_rule_key?(key)
|
def valid_rule_key?(key)
|
||||||
super || key == :inspect
|
super || key == :inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
# Overridable method to specify how the first part of a `pretty_print`d object's class should look like
|
# Overridable method to specify how the first part of a `pretty_print`d object's class should look like
|
||||||
# NOTE: This is just to support Stripe's `PrettyPrintableModel` case, and not recommended to be overridden
|
# NOTE: This is just to support Stripe's `PrettyPrintableModel` case, and not recommended to be overridden
|
||||||
sig {params(instance: T::Props::PrettyPrintable).returns(String)}
|
sig { params(instance: T::Props::PrettyPrintable).returns(String) }
|
||||||
def inspect_class_with_decoration(instance)
|
def inspect_class_with_decoration(instance)
|
||||||
T.unsafe(instance).class.to_s
|
T.unsafe(instance).class.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Overridable method to add anything that is not a prop
|
# Overridable method to add anything that is not a prop
|
||||||
# NOTE: This is to support cases like Serializable's `@_extra_props`, and Stripe's `PrettyPrintableModel#@_deleted`
|
# NOTE: This is to support cases like Serializable's `@_extra_props`, and Stripe's `PrettyPrintableModel#@_deleted`
|
||||||
sig {params(instance: T::Props::PrettyPrintable, pp: T.any(PrettyPrint, PP::SingleLine)).void}
|
sig { params(instance: T::Props::PrettyPrintable, pp: T.any(PrettyPrint, PP::SingleLine)).void }
|
||||||
def pretty_print_extra(instance, pp); end
|
def pretty_print_extra(instance, pp); end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -9,28 +9,28 @@ module T::Props
|
|||||||
abstract!
|
abstract!
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {returns(SetterFactory::SetterProc).checked(:never)}
|
sig { returns(SetterFactory::SetterProc).checked(:never) }
|
||||||
attr_reader :setter_proc
|
attr_reader :setter_proc
|
||||||
|
|
||||||
# checked(:never) - We do this with `T.let` instead
|
# checked(:never) - We do this with `T.let` instead
|
||||||
sig {params(accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)}
|
sig { params(accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never) }
|
||||||
def initialize(accessor_key, setter_proc)
|
def initialize(accessor_key, setter_proc)
|
||||||
@accessor_key = T.let(accessor_key, Symbol)
|
@accessor_key = T.let(accessor_key, Symbol)
|
||||||
@setter_proc = T.let(setter_proc, SetterFactory::SetterProc)
|
@setter_proc = T.let(setter_proc, SetterFactory::SetterProc)
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {abstract.returns(T.untyped).checked(:never)}
|
sig { abstract.returns(T.untyped).checked(:never) }
|
||||||
def default; end
|
def default; end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {abstract.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
sig { abstract.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never) }
|
||||||
def set_default(instance); end
|
def set_default(instance); end
|
||||||
|
|
||||||
NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module])
|
NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module])
|
||||||
|
|
||||||
# checked(:never) - Rules hash is expensive to check
|
# checked(:never) - Rules hash is expensive to check
|
||||||
sig {params(cls: Module, rules: T::Hash[Symbol, T.untyped]).returns(T.nilable(ApplyDefault)).checked(:never)}
|
sig { params(cls: Module, rules: T::Hash[Symbol, T.untyped]).returns(T.nilable(ApplyDefault)).checked(:never) }
|
||||||
def self.for(cls, rules)
|
def self.for(cls, rules)
|
||||||
accessor_key = rules.fetch(:accessor_key)
|
accessor_key = rules.fetch(:accessor_key)
|
||||||
setter = rules.fetch(:setter_proc)
|
setter = rules.fetch(:setter_proc)
|
||||||
@ -67,7 +67,7 @@ module T::Props
|
|||||||
abstract!
|
abstract!
|
||||||
|
|
||||||
# checked(:never) - We do this with `T.let` instead
|
# checked(:never) - We do this with `T.let` instead
|
||||||
sig {params(default: BasicObject, accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never)}
|
sig { params(default: BasicObject, accessor_key: Symbol, setter_proc: SetterFactory::SetterProc).void.checked(:never) }
|
||||||
def initialize(default, accessor_key, setter_proc)
|
def initialize(default, accessor_key, setter_proc)
|
||||||
# FIXME: Ideally we'd check here that the default is actually a valid
|
# FIXME: Ideally we'd check here that the default is actually a valid
|
||||||
# value for this field, but existing code relies on the fact that we don't.
|
# value for this field, but existing code relies on the fact that we don't.
|
||||||
@ -80,7 +80,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
sig { override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never) }
|
||||||
def set_default(instance)
|
def set_default(instance)
|
||||||
instance.instance_variable_set(@accessor_key, default)
|
instance.instance_variable_set(@accessor_key, default)
|
||||||
end
|
end
|
||||||
@ -88,13 +88,13 @@ module T::Props
|
|||||||
|
|
||||||
class ApplyPrimitiveDefault < ApplyFixedDefault
|
class ApplyPrimitiveDefault < ApplyFixedDefault
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.returns(T.untyped).checked(:never)}
|
sig { override.returns(T.untyped).checked(:never) }
|
||||||
attr_reader :default
|
attr_reader :default
|
||||||
end
|
end
|
||||||
|
|
||||||
class ApplyComplexDefault < ApplyFixedDefault
|
class ApplyComplexDefault < ApplyFixedDefault
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.returns(T.untyped).checked(:never)}
|
sig { override.returns(T.untyped).checked(:never) }
|
||||||
def default
|
def default
|
||||||
T::Props::Utils.deep_clone_object(@default)
|
T::Props::Utils.deep_clone_object(@default)
|
||||||
end
|
end
|
||||||
@ -105,13 +105,13 @@ module T::Props
|
|||||||
# `some_empty_array.dup`
|
# `some_empty_array.dup`
|
||||||
class ApplyEmptyArrayDefault < ApplyDefault
|
class ApplyEmptyArrayDefault < ApplyDefault
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
sig { override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never) }
|
||||||
def set_default(instance)
|
def set_default(instance)
|
||||||
instance.instance_variable_set(@accessor_key, [])
|
instance.instance_variable_set(@accessor_key, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.returns(T::Array[T.untyped]).checked(:never)}
|
sig { override.returns(T::Array[T.untyped]).checked(:never) }
|
||||||
def default
|
def default
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
@ -122,13 +122,13 @@ module T::Props
|
|||||||
# `some_empty_hash.dup`
|
# `some_empty_hash.dup`
|
||||||
class ApplyEmptyHashDefault < ApplyDefault
|
class ApplyEmptyHashDefault < ApplyDefault
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
sig { override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never) }
|
||||||
def set_default(instance)
|
def set_default(instance)
|
||||||
instance.instance_variable_set(@accessor_key, {})
|
instance.instance_variable_set(@accessor_key, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.returns(T::Hash[T.untyped, T.untyped]).checked(:never)}
|
sig { override.returns(T::Hash[T.untyped, T.untyped]).checked(:never) }
|
||||||
def default
|
def default
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
@ -153,7 +153,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never)}
|
sig { override.params(instance: T.all(T::Props::Optional, Object)).void.checked(:never) }
|
||||||
def set_default(instance)
|
def set_default(instance)
|
||||||
# Use the actual setter to validate the factory returns a legitimate
|
# Use the actual setter to validate the factory returns a legitimate
|
||||||
# value every time
|
# value every time
|
||||||
@ -161,7 +161,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
|
|
||||||
# checked(:never) - O(object construction x prop count)
|
# checked(:never) - O(object construction x prop count)
|
||||||
sig {override.returns(T.untyped).checked(:never)}
|
sig { override.returns(T.untyped).checked(:never) }
|
||||||
def default
|
def default
|
||||||
@class.class_exec(&@factory)
|
@class.class_exec(&@factory)
|
||||||
end
|
end
|
@ -29,7 +29,7 @@ module T::Props
|
|||||||
.checked(:never)
|
.checked(:never)
|
||||||
end
|
end
|
||||||
def self.generate(props, defaults)
|
def self.generate(props, defaults)
|
||||||
stored_props = props.reject {|_, rules| rules[:dont_store]}
|
stored_props = props.reject { |_, rules| rules[:dont_store] }
|
||||||
parts = stored_props.map do |prop, rules|
|
parts = stored_props.map do |prop, rules|
|
||||||
# All of these strings should already be validated (directly or
|
# All of these strings should already be validated (directly or
|
||||||
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
@ -10,7 +10,7 @@ module T::Props
|
|||||||
private_constant :Serialize
|
private_constant :Serialize
|
||||||
class Deserialize; end
|
class Deserialize; end
|
||||||
private_constant :Deserialize
|
private_constant :Deserialize
|
||||||
ModeType = T.type_alias {T.any(Serialize, Deserialize)}
|
ModeType = T.type_alias { T.any(Serialize, Deserialize) }
|
||||||
private_constant :ModeType
|
private_constant :ModeType
|
||||||
|
|
||||||
module Mode
|
module Mode
|
||||||
@ -63,7 +63,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
when T::Types::Simple
|
when T::Types::Simple
|
||||||
raw = type.raw_type
|
raw = type.raw_type
|
||||||
if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls}
|
if NO_TRANSFORM_TYPES.any? { |cls| raw <= cls }
|
||||||
nil
|
nil
|
||||||
elsif raw <= Float
|
elsif raw <= Float
|
||||||
case mode
|
case mode
|
||||||
@ -99,7 +99,7 @@ module T::Props
|
|||||||
else
|
else
|
||||||
"#{varname}.nil? ? nil : #{inner}"
|
"#{varname}.nil? ? nil : #{inner}"
|
||||||
end
|
end
|
||||||
elsif type.types.all? {|t| generate(t, mode, varname).nil?}
|
elsif type.types.all? { |t| generate(t, mode, varname).nil? }
|
||||||
# Handle, e.g., T::Boolean
|
# Handle, e.g., T::Boolean
|
||||||
nil
|
nil
|
||||||
else
|
else
|
||||||
@ -122,8 +122,8 @@ module T::Props
|
|||||||
# NB: This deliberately does include `nil`, which means we know we
|
# NB: This deliberately does include `nil`, which means we know we
|
||||||
# don't need to do any transforming.
|
# don't need to do any transforming.
|
||||||
inner_known = type.types
|
inner_known = type.types
|
||||||
.map {|t| generate(t, mode, varname)}
|
.map { |t| generate(t, mode, varname) }
|
||||||
.reject {|t| t == dynamic_fallback}
|
.reject { |t| t == dynamic_fallback }
|
||||||
.uniq
|
.uniq
|
||||||
|
|
||||||
if inner_known.size != 1
|
if inner_known.size != 1
|
||||||
@ -151,7 +151,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)}
|
sig { params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never) }
|
||||||
private_class_method def self.handle_serializable_subtype(varname, type, mode)
|
private_class_method def self.handle_serializable_subtype(varname, type, mode)
|
||||||
case mode
|
case mode
|
||||||
when Serialize
|
when Serialize
|
||||||
@ -164,7 +164,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never)}
|
sig { params(varname: String, type: Module, mode: ModeType).returns(String).checked(:never) }
|
||||||
private_class_method def self.handle_custom_type(varname, type, mode)
|
private_class_method def self.handle_custom_type(varname, type, mode)
|
||||||
case mode
|
case mode
|
||||||
when Serialize
|
when Serialize
|
||||||
@ -177,7 +177,7 @@ module T::Props
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sig {params(type: Module).returns(T.nilable(String)).checked(:never)}
|
sig { params(type: Module).returns(T.nilable(String)).checked(:never) }
|
||||||
private_class_method def self.module_name(type)
|
private_class_method def self.module_name(type)
|
||||||
T::Configuration.module_name_mangler.call(type)
|
T::Configuration.module_name_mangler.call(type)
|
||||||
end
|
end
|
@ -24,7 +24,7 @@ module T::Props
|
|||||||
.checked(:never)
|
.checked(:never)
|
||||||
end
|
end
|
||||||
def self.generate(props)
|
def self.generate(props)
|
||||||
stored_props = props.reject {|_, rules| rules[:dont_store]}
|
stored_props = props.reject { |_, rules| rules[:dont_store] }
|
||||||
parts = stored_props.map do |prop, rules|
|
parts = stored_props.map do |prop, rules|
|
||||||
# All of these strings should already be validated (directly or
|
# All of these strings should already be validated (directly or
|
||||||
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
@ -6,9 +6,9 @@ module T::Props
|
|||||||
module SetterFactory
|
module SetterFactory
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
SetterProc = T.type_alias {T.proc.params(val: T.untyped).void}
|
SetterProc = T.type_alias { T.proc.params(val: T.untyped).void }
|
||||||
ValueValidationProc = T.type_alias {T.proc.params(val: T.untyped).void}
|
ValueValidationProc = T.type_alias { T.proc.params(val: T.untyped).void }
|
||||||
ValidateProc = T.type_alias {T.proc.params(prop: Symbol, value: T.untyped).void}
|
ValidateProc = T.type_alias { T.proc.params(prop: Symbol, value: T.untyped).void }
|
||||||
|
|
||||||
sig do
|
sig do
|
||||||
params(
|
params(
|
||||||
@ -236,7 +236,7 @@ module T::Props
|
|||||||
base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}"
|
base_message = "Can't set #{klass.name}.#{prop} to #{val.inspect} (instance of #{val.class}) - need a #{type}"
|
||||||
|
|
||||||
pretty_message = "Parameter '#{prop}': #{base_message}\n"
|
pretty_message = "Parameter '#{prop}': #{base_message}\n"
|
||||||
caller_loc = caller_locations.find {|l| !l.to_s.include?('sorbet-runtime/lib/types/props')}
|
caller_loc = caller_locations.find { |l| !l.to_s.include?('sorbet-runtime/lib/types/props') }
|
||||||
if caller_loc
|
if caller_loc
|
||||||
pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
||||||
end
|
end
|
@ -78,7 +78,7 @@ module T::Props::Serializable
|
|||||||
|
|
||||||
if hash.size > hash_keys_matching_props
|
if hash.size > hash_keys_matching_props
|
||||||
serialized_forms = self.class.decorator.prop_by_serialized_forms
|
serialized_forms = self.class.decorator.prop_by_serialized_forms
|
||||||
extra = hash.reject {|k, _| serialized_forms.key?(k)}
|
extra = hash.reject { |k, _| serialized_forms.key?(k) }
|
||||||
|
|
||||||
# `extra` could still be empty here if the input matches a `dont_store` prop;
|
# `extra` could still be empty here if the input matches a `dont_store` prop;
|
||||||
# historically, we just ignore those
|
# historically, we just ignore those
|
||||||
@ -111,7 +111,7 @@ module T::Props::Serializable
|
|||||||
new_obj[k.to_s] = recursive_stringify_keys(v)
|
new_obj[k.to_s] = recursive_stringify_keys(v)
|
||||||
end
|
end
|
||||||
elsif obj.is_a?(Array)
|
elsif obj.is_a?(Array)
|
||||||
new_obj = obj.map {|v| recursive_stringify_keys(v)}
|
new_obj = obj.map { |v| recursive_stringify_keys(v) }
|
||||||
else
|
else
|
||||||
new_obj = obj
|
new_obj = obj
|
||||||
end
|
end
|
||||||
@ -126,7 +126,7 @@ module T::Props::Serializable
|
|||||||
if old_extra != new_extra
|
if old_extra != new_extra
|
||||||
difference =
|
difference =
|
||||||
if old_extra
|
if old_extra
|
||||||
new_extra.reject {|k, v| old_extra[k] == v}
|
new_extra.reject { |k, v| old_extra[k] == v }
|
||||||
else
|
else
|
||||||
new_extra
|
new_extra
|
||||||
end
|
end
|
||||||
@ -195,7 +195,7 @@ module T::Props::Serializable::DecoratorMethods
|
|||||||
end
|
end
|
||||||
|
|
||||||
def required_props
|
def required_props
|
||||||
@class.props.select {|_, v| T::Props::Utils.required_prop?(v)}.keys
|
@class.props.select { |_, v| T::Props::Utils.required_prop?(v) }.keys
|
||||||
end
|
end
|
||||||
|
|
||||||
def prop_dont_store?(prop)
|
def prop_dont_store?(prop)
|
||||||
@ -228,11 +228,11 @@ module T::Props::Serializable::DecoratorMethods
|
|||||||
res = super
|
res = super
|
||||||
prop_by_serialized_forms[serialized_form] = prop
|
prop_by_serialized_forms[serialized_form] = prop
|
||||||
if T::Configuration.use_vm_prop_serde?
|
if T::Configuration.use_vm_prop_serde?
|
||||||
enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) {generate_serialize2}
|
enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) { generate_serialize2 }
|
||||||
enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) {generate_deserialize2}
|
enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) { generate_deserialize2 }
|
||||||
else
|
else
|
||||||
enqueue_lazy_method_definition!(:__t_props_generated_serialize) {generate_serialize_source}
|
enqueue_lazy_method_definition!(:__t_props_generated_serialize) { generate_serialize_source }
|
||||||
enqueue_lazy_method_definition!(:__t_props_generated_deserialize) {generate_deserialize_source}
|
enqueue_lazy_method_definition!(:__t_props_generated_deserialize) { generate_deserialize_source }
|
||||||
end
|
end
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
@ -263,7 +263,7 @@ module T::Props::Serializable::DecoratorMethods
|
|||||||
def message_with_generated_source_context(error, generated_method, generate_source_method)
|
def message_with_generated_source_context(error, generated_method, generate_source_method)
|
||||||
generated_method = generated_method.to_s
|
generated_method = generated_method.to_s
|
||||||
if error.backtrace_locations
|
if error.backtrace_locations
|
||||||
line_loc = error.backtrace_locations.find {|l| l.base_label == generated_method}
|
line_loc = error.backtrace_locations.find { |l| l.base_label == generated_method }
|
||||||
return unless line_loc
|
return unless line_loc
|
||||||
|
|
||||||
line_num = line_loc.lineno
|
line_num = line_loc.lineno
|
||||||
@ -275,7 +275,7 @@ module T::Props::Serializable::DecoratorMethods
|
|||||||
# in `__t_props_generated_serialize'"
|
# in `__t_props_generated_serialize'"
|
||||||
"in `#{generated_method}'"
|
"in `#{generated_method}'"
|
||||||
end
|
end
|
||||||
line_label = error.backtrace.find {|l| l.end_with?(label)}
|
line_label = error.backtrace.find { |l| l.end_with?(label) }
|
||||||
return unless line_label
|
return unless line_label
|
||||||
|
|
||||||
line_num = if line_label.start_with?("(eval)")
|
line_num = if line_label.start_with?("(eval)")
|
@ -11,7 +11,7 @@ module T::Props::TypeValidation
|
|||||||
module DecoratorMethods
|
module DecoratorMethods
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
sig { params(key: Symbol).returns(T::Boolean).checked(:never) }
|
||||||
def valid_rule_key?(key)
|
def valid_rule_key?(key)
|
||||||
super || key == :DEPRECATED_underspecified_type
|
super || key == :DEPRECATED_underspecified_type
|
||||||
end
|
end
|
||||||
@ -58,19 +58,19 @@ module T::Props::TypeValidation
|
|||||||
# If the type is fully valid, returns nil.
|
# If the type is fully valid, returns nil.
|
||||||
#
|
#
|
||||||
# checked(:never) - called potentially many times recursively
|
# checked(:never) - called potentially many times recursively
|
||||||
sig {params(type: T::Types::Base).returns(T.nilable(T::Types::Base)).checked(:never)}
|
sig { params(type: T::Types::Base).returns(T.nilable(T::Types::Base)).checked(:never) }
|
||||||
private def find_invalid_subtype(type)
|
private def find_invalid_subtype(type)
|
||||||
case type
|
case type
|
||||||
when T::Types::TypedEnumerable
|
when T::Types::TypedEnumerable
|
||||||
find_invalid_subtype(type.type)
|
find_invalid_subtype(type.type)
|
||||||
when T::Types::FixedHash
|
when T::Types::FixedHash
|
||||||
type.types.values.map {|subtype| find_invalid_subtype(subtype)}.compact.first
|
type.types.values.map { |subtype| find_invalid_subtype(subtype) }.compact.first
|
||||||
when T::Types::Union, T::Types::FixedArray
|
when T::Types::Union, T::Types::FixedArray
|
||||||
# `T.any` is valid if all of the members are valid
|
# `T.any` is valid if all of the members are valid
|
||||||
type.types.map {|subtype| find_invalid_subtype(subtype)}.compact.first
|
type.types.map { |subtype| find_invalid_subtype(subtype) }.compact.first
|
||||||
when T::Types::Intersection
|
when T::Types::Intersection
|
||||||
# `T.all` is valid if at least one of the members is valid
|
# `T.all` is valid if at least one of the members is valid
|
||||||
invalid = type.types.map {|subtype| find_invalid_subtype(subtype)}.compact
|
invalid = type.types.map { |subtype| find_invalid_subtype(subtype) }.compact
|
||||||
if invalid.length == type.types.length
|
if invalid.length == type.types.length
|
||||||
invalid.first
|
invalid.first
|
||||||
else
|
else
|
@ -13,7 +13,7 @@ module T::Props::Utils
|
|||||||
when Symbol, NilClass, Numeric
|
when Symbol, NilClass, Numeric
|
||||||
what
|
what
|
||||||
when Array
|
when Array
|
||||||
what.map {|v| deep_clone_object(v, freeze: freeze)}
|
what.map { |v| deep_clone_object(v, freeze: freeze) }
|
||||||
when Hash
|
when Hash
|
||||||
h = what.class.new
|
h = what.class.new
|
||||||
what.each do |k, v|
|
what.each do |k, v|
|
@ -6,7 +6,7 @@ module T::Props::WeakConstructor
|
|||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)}
|
sig { params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never) }
|
||||||
def initialize(hash={})
|
def initialize(hash={})
|
||||||
decorator = self.class.decorator
|
decorator = self.class.decorator
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ module T::Props::WeakConstructor::DecoratorMethods
|
|||||||
# we'll use to check for any unrecognized input.)
|
# we'll use to check for any unrecognized input.)
|
||||||
#
|
#
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
sig { params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never) }
|
||||||
def construct_props_without_defaults(instance, hash)
|
def construct_props_without_defaults(instance, hash)
|
||||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||||
# and therefore allocates for each entry.
|
# and therefore allocates for each entry.
|
||||||
@ -49,7 +49,7 @@ module T::Props::WeakConstructor::DecoratorMethods
|
|||||||
# we'll use to check for any unrecognized input.)
|
# we'll use to check for any unrecognized input.)
|
||||||
#
|
#
|
||||||
# checked(:never) - O(runtime object construction)
|
# checked(:never) - O(runtime object construction)
|
||||||
sig {params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never)}
|
sig { params(instance: T::Props::WeakConstructor, hash: T::Hash[Symbol, T.untyped]).returns(Integer).checked(:never) }
|
||||||
def construct_props_with_defaults(instance, hash)
|
def construct_props_with_defaults(instance, hash)
|
||||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||||
# and therefore allocates for each entry.
|
# and therefore allocates for each entry.
|
@ -14,7 +14,7 @@ module T::Sig
|
|||||||
|
|
||||||
# At runtime, does nothing, but statically it is treated exactly the same
|
# At runtime, does nothing, but statically it is treated exactly the same
|
||||||
# as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig.
|
# as T::Sig#sig. Only use it in cases where you can't use T::Sig#sig.
|
||||||
T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void}
|
T::Sig::WithoutRuntime.sig { params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void }
|
||||||
def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods
|
def self.sig(arg0=nil, &blk); end # rubocop:disable Lint/DuplicateMethods
|
||||||
|
|
||||||
$VERBOSE = original_verbose
|
$VERBOSE = original_verbose
|
||||||
@ -23,7 +23,7 @@ module T::Sig
|
|||||||
# Declares a method with type signatures and/or
|
# Declares a method with type signatures and/or
|
||||||
# abstract/override/... helpers. See the documentation URL on
|
# abstract/override/... helpers. See the documentation URL on
|
||||||
# {T::Helpers}
|
# {T::Helpers}
|
||||||
T::Sig::WithoutRuntime.sig {params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void}
|
T::Sig::WithoutRuntime.sig { params(arg0: T.nilable(Symbol), blk: T.proc.bind(T::Private::Methods::DeclBuilder).void).void }
|
||||||
def sig(arg0=nil, &blk)
|
def sig(arg0=nil, &blk)
|
||||||
T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk)
|
T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk)
|
||||||
end
|
end
|
@ -30,7 +30,7 @@ class T::ImmutableStruct < T::InexactStruct
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Matches the one in WeakConstructor, but freezes the object
|
# Matches the one in WeakConstructor, but freezes the object
|
||||||
sig {params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never)}
|
sig { params(hash: T::Hash[Symbol, T.untyped]).void.checked(:never) }
|
||||||
def initialize(hash={})
|
def initialize(hash={})
|
||||||
super
|
super
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class T::ImmutableStruct < T::InexactStruct
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Matches the signature in Props, but raises since this is an immutable struct and only const is allowed
|
# Matches the signature in Props, but raises since this is an immutable struct and only const is allowed
|
||||||
sig {params(name: Symbol, cls: T.untyped, rules: T.untyped).void}
|
sig { params(name: Symbol, cls: T.untyped, rules: T.untyped).void }
|
||||||
def self.prop(name, cls, **rules)
|
def self.prop(name, cls, **rules)
|
||||||
return super if (cls.is_a?(Hash) && cls[:immutable]) || rules[:immutable]
|
return super if (cls.is_a?(Hash) && cls[:immutable]) || rules[:immutable]
|
||||||
|
|
@ -83,27 +83,27 @@ module T::Types
|
|||||||
# Note: order of cases here matters!
|
# Note: order of cases here matters!
|
||||||
if t1.is_a?(T::Types::Union) # 7, 8, 9
|
if t1.is_a?(T::Types::Union) # 7, 8, 9
|
||||||
# this will be incorrect if/when we have Type members
|
# this will be incorrect if/when we have Type members
|
||||||
return t1.types.all? {|t1_member| t1_member.subtype_of?(t2)}
|
return t1.types.all? { |t1_member| t1_member.subtype_of?(t2) }
|
||||||
end
|
end
|
||||||
|
|
||||||
if t2.is_a?(T::Types::Intersection) # 2, 5
|
if t2.is_a?(T::Types::Intersection) # 2, 5
|
||||||
# this will be incorrect if/when we have Type members
|
# this will be incorrect if/when we have Type members
|
||||||
return t2.types.all? {|t2_member| t1.subtype_of?(t2_member)}
|
return t2.types.all? { |t2_member| t1.subtype_of?(t2_member) }
|
||||||
end
|
end
|
||||||
|
|
||||||
if t2.is_a?(T::Types::Union)
|
if t2.is_a?(T::Types::Union)
|
||||||
if t1.is_a?(T::Types::Intersection) # 6
|
if t1.is_a?(T::Types::Intersection) # 6
|
||||||
# dropping either of parts eagerly make subtype test be too strict.
|
# dropping either of parts eagerly make subtype test be too strict.
|
||||||
# we have to try both cases, when we normally try only one
|
# we have to try both cases, when we normally try only one
|
||||||
return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} ||
|
return t2.types.any? { |t2_member| t1.subtype_of?(t2_member) } ||
|
||||||
t1.types.any? {|t1_member| t1_member.subtype_of?(t2)}
|
t1.types.any? { |t1_member| t1_member.subtype_of?(t2) }
|
||||||
end
|
end
|
||||||
return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} # 3
|
return t2.types.any? { |t2_member| t1.subtype_of?(t2_member) } # 3
|
||||||
end
|
end
|
||||||
|
|
||||||
if t1.is_a?(T::Types::Intersection) # 4
|
if t1.is_a?(T::Types::Intersection) # 4
|
||||||
# this will be incorrect if/when we have Type members
|
# this will be incorrect if/when we have Type members
|
||||||
return t1.types.any? {|t1_member| t1_member.subtype_of?(t2)}
|
return t1.types.any? { |t1_member| t1_member.subtype_of?(t2) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# 1; Start with some special cases
|
# 1; Start with some special cases
|
@ -11,7 +11,7 @@ module T::Types
|
|||||||
end
|
end
|
||||||
|
|
||||||
def types
|
def types
|
||||||
@types ||= @inner_types.map {|type| T::Utils.coerce(type)}
|
@types ||= @inner_types.map { |type| T::Utils.coerce(type) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_type
|
def build_type
|
@ -10,7 +10,7 @@ module T::Types
|
|||||||
end
|
end
|
||||||
|
|
||||||
def types
|
def types
|
||||||
@types ||= @inner_types.transform_values {|v| T::Utils.coerce(v)}
|
@types ||= @inner_types.transform_values { |v| T::Utils.coerce(v) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_type
|
def build_type
|
||||||
@ -26,16 +26,16 @@ module T::Types
|
|||||||
# overrides Base
|
# overrides Base
|
||||||
def recursively_valid?(obj)
|
def recursively_valid?(obj)
|
||||||
return false unless obj.is_a?(Hash)
|
return false unless obj.is_a?(Hash)
|
||||||
return false if types.any? {|key, type| !type.recursively_valid?(obj[key])}
|
return false if types.any? { |key, type| !type.recursively_valid?(obj[key]) }
|
||||||
return false if obj.any? {|key, _| !types[key]}
|
return false if obj.any? { |key, _| !types[key] }
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
def valid?(obj)
|
def valid?(obj)
|
||||||
return false unless obj.is_a?(Hash)
|
return false unless obj.is_a?(Hash)
|
||||||
return false if types.any? {|key, type| !type.valid?(obj[key])}
|
return false if types.any? { |key, type| !type.valid?(obj[key]) }
|
||||||
return false if obj.any? {|key, _| !types[key]}
|
return false if obj.any? { |key, _| !types[key] }
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ module T::Types
|
|||||||
when TypedHash
|
when TypedHash
|
||||||
# warning: covariant hashes
|
# warning: covariant hashes
|
||||||
|
|
||||||
key1, key2, *keys_rest = types.keys.map {|key| T::Utils.coerce(key.class)}
|
key1, key2, *keys_rest = types.keys.map { |key| T::Utils.coerce(key.class) }
|
||||||
key_type = if !key2.nil?
|
key_type = if !key2.nil?
|
||||||
T::Types::Union::Private::Pool.union_of_types(key1, key2, keys_rest)
|
T::Types::Union::Private::Pool.union_of_types(key1, key2, keys_rest)
|
||||||
elsif key1.nil?
|
elsif key1.nil?
|
@ -32,12 +32,12 @@ module T::Types
|
|||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
def recursively_valid?(obj)
|
def recursively_valid?(obj)
|
||||||
types.all? {|type| type.recursively_valid?(obj)}
|
types.all? { |type| type.recursively_valid?(obj) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
def valid?(obj)
|
def valid?(obj)
|
||||||
types.all? {|type| type.valid?(obj)}
|
types.all? { |type| type.valid?(obj) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
@ -44,11 +44,11 @@ module T::Types
|
|||||||
nilable = T::Utils.coerce(NilClass)
|
nilable = T::Utils.coerce(NilClass)
|
||||||
trueclass = T::Utils.coerce(TrueClass)
|
trueclass = T::Utils.coerce(TrueClass)
|
||||||
falseclass = T::Utils.coerce(FalseClass)
|
falseclass = T::Utils.coerce(FalseClass)
|
||||||
if types.any? {|t| t == nilable}
|
if types.any? { |t| t == nilable }
|
||||||
remaining_types = types.reject {|t| t == nilable}
|
remaining_types = types.reject { |t| t == nilable }
|
||||||
"T.nilable(#{type_shortcuts(remaining_types)})"
|
"T.nilable(#{type_shortcuts(remaining_types)})"
|
||||||
elsif types.any? {|t| t == trueclass} && types.any? {|t| t == falseclass}
|
elsif types.any? { |t| t == trueclass } && types.any? { |t| t == falseclass }
|
||||||
remaining_types = types.reject {|t| t == trueclass || t == falseclass}
|
remaining_types = types.reject { |t| t == trueclass || t == falseclass }
|
||||||
type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types)
|
type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types)
|
||||||
else
|
else
|
||||||
names = types.map(&:name).compact.sort
|
names = types.map(&:name).compact.sort
|
||||||
@ -58,12 +58,12 @@ module T::Types
|
|||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
def recursively_valid?(obj)
|
def recursively_valid?(obj)
|
||||||
types.any? {|type| type.recursively_valid?(obj)}
|
types.any? { |type| type.recursively_valid?(obj) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
def valid?(obj)
|
def valid?(obj)
|
||||||
types.any? {|type| type.valid?(obj)}
|
types.any? { |type| type.valid?(obj) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# overrides Base
|
# overrides Base
|
||||||
@ -72,7 +72,7 @@ module T::Types
|
|||||||
end
|
end
|
||||||
|
|
||||||
def unwrap_nilable
|
def unwrap_nilable
|
||||||
non_nil_types = types.reject {|t| t == T::Utils::Nilable::NIL_TYPE}
|
non_nil_types = types.reject { |t| t == T::Utils::Nilable::NIL_TYPE }
|
||||||
return nil if types.length == non_nil_types.length
|
return nil if types.length == non_nil_types.length
|
||||||
case non_nil_types.length
|
case non_nil_types.length
|
||||||
when 0 then nil
|
when 0 then nil
|
Loading…
x
Reference in New Issue
Block a user