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
|
||||
aarch64-linux
|
||||
arm-linux
|
||||
arm64-darwin
|
||||
x86_64-darwin
|
||||
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/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/base64-0.2.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}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/bigdecimal-3.1.9")
|
||||
$:.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/base64-0.3.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.2.2")
|
||||
$:.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/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/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/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/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}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/json-2.12.0")
|
||||
$:.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}/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.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/simpleidn-0.2.3/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/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_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}/gems/racc-1.8.1/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}/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}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/rbs-3.9.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/sorbet-runtime-0.5.12117/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}/rbs-4.0.0.dev.4")
|
||||
$:.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/rbi-0.3.6/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}/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/rspec-core-3.13.3/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-mocks-3.13.4/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/require-hooks-0.2.2/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-core-3.13.5/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-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-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_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/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/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-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-sorbet-0.10.0/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/rubocop-sorbet-0.10.5/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}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/ruby-prof-1.7.1")
|
||||
$:.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}/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.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_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-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-0.5.12117/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-0.5.12222-universal-darwin/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.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/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}/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-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}/extensions/arm64-darwin-20/#{Gem.extension_api_version}/vernier-1.7.1")
|
||||
$:.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/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.8.0")
|
||||
$:.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")
|
||||
|
@ -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:
|
||||
#
|
||||
# - Encoding a binary string (containing non-ASCII characters)
|
||||
# - \Encoding a binary string (containing non-ASCII characters)
|
||||
# as a string of printable ASCII characters.
|
||||
# - Decoding such an encoded string.
|
||||
#
|
||||
@ -27,7 +27,7 @@
|
||||
#
|
||||
# require 'base64'
|
||||
#
|
||||
# == Encoding Character Sets
|
||||
# == \Encoding Character Sets
|
||||
#
|
||||
# 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==") # 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:
|
||||
# see {Padding}[Base64.html#module-Base64-label-Padding], above:
|
||||
#
|
||||
@ -183,11 +183,14 @@
|
||||
#
|
||||
module Base64
|
||||
|
||||
VERSION = "0.2.0"
|
||||
VERSION = "0.3.0"
|
||||
|
||||
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
|
||||
# <tt>+</tt> or <tt>/</tt>;
|
||||
@ -220,19 +223,22 @@ module Base64
|
||||
[bin].pack("m")
|
||||
end
|
||||
|
||||
# :call-seq:
|
||||
# Base64.decode(encoded_string) -> decoded_string
|
||||
#
|
||||
# Returns a string containing the decoding of an RFC-2045-compliant
|
||||
# \Base64-encoded string +str+:
|
||||
# \Base64-encoded string +encoded_string+:
|
||||
#
|
||||
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\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:
|
||||
# these include newline characters and characters <tt>-</tt> and <tt>/</tt>:
|
||||
#
|
||||
# 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"
|
||||
@ -242,7 +248,10 @@ module Base64
|
||||
str.unpack1("m")
|
||||
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
|
||||
# <tt>+</tt> or <tt>/</tt>;
|
||||
@ -274,13 +283,16 @@ module Base64
|
||||
[bin].pack("m0")
|
||||
end
|
||||
|
||||
# :call-seq:
|
||||
# Base64.strict_decode64(encoded_string) -> decoded_string
|
||||
#
|
||||
# Returns a string containing the decoding of an RFC-2045-compliant
|
||||
# \Base64-encoded string +str+:
|
||||
# \Base64-encoded string +encoded_string+:
|
||||
#
|
||||
# s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
|
||||
# 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:
|
||||
# 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
|
||||
#
|
||||
# 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=") # => "01234567"
|
||||
@ -298,7 +310,10 @@ module Base64
|
||||
str.unpack1("m0")
|
||||
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
|
||||
# <tt>+</tt> or <tt>/</tt>,
|
||||
@ -332,16 +347,19 @@ module Base64
|
||||
str
|
||||
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:
|
||||
#
|
||||
# Base64.urlsafe_decode64('+') # Raises ArgumentError.
|
||||
# Base64.urlsafe_decode64('/') # 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:
|
||||
#
|
||||
# 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)
|
||||
type_a = T::Utils.coerce(type_a)
|
||||
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)
|
||||
end
|
||||
|
@ -4,5 +4,5 @@
|
||||
module T
|
||||
# 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.
|
||||
Boolean = T.type_alias {T.any(TrueClass, FalseClass)}
|
||||
Boolean = T.type_alias { T.any(TrueClass, FalseClass) }
|
||||
end
|
@ -419,12 +419,12 @@ module T::Configuration
|
||||
if values.nil?
|
||||
@scalar_types = values
|
||||
else
|
||||
bad_values = values.reject {|v| v.class == String}
|
||||
bad_values = values.reject { |v| v.class == String }
|
||||
unless bad_values.empty?
|
||||
raise ArgumentError.new("Provided values must all be class name strings.")
|
||||
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
|
||||
|
||||
@ -449,9 +449,9 @@ module T::Configuration
|
||||
private_constant :MODULE_NAME
|
||||
|
||||
@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
|
||||
->(type) {MODULE_NAME.bind(type).call} # rubocop:disable Performance/BindCall
|
||||
->(type) { MODULE_NAME.bind(type).call } # rubocop:disable Performance/BindCall
|
||||
end
|
||||
|
||||
@module_name_mangler = nil
|
@ -44,11 +44,11 @@ class T::Enum
|
||||
extend T::Props::CustomType
|
||||
|
||||
# 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
|
||||
|
||||
### Enum class methods ###
|
||||
sig {returns(T::Array[T.attached_class])}
|
||||
sig { returns(T::Array[T.attached_class]) }
|
||||
def self.values
|
||||
if @values.nil?
|
||||
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
|
||||
# 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)
|
||||
if 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: 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)
|
||||
if @mapping.nil?
|
||||
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
||||
@ -88,7 +88,7 @@ class T::Enum
|
||||
#
|
||||
# @return [self]
|
||||
# @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)
|
||||
res = try_deserialize(serialized_val)
|
||||
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.
|
||||
# @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)
|
||||
if @mapping.nil?
|
||||
raise "Attempting to access serialization map of #{self.class} before it has been initialized." \
|
||||
@ -109,7 +109,7 @@ class T::Enum
|
||||
end
|
||||
|
||||
# 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)
|
||||
# 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
|
||||
@ -126,7 +126,7 @@ class T::Enum
|
||||
end
|
||||
|
||||
# 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)
|
||||
if self == T::Enum
|
||||
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 ###
|
||||
|
||||
sig {returns(T.self_type)}
|
||||
sig { returns(T.self_type) }
|
||||
def dup
|
||||
self
|
||||
end
|
||||
|
||||
sig {returns(T.self_type).checked(:tests)}
|
||||
sig { returns(T.self_type).checked(:tests) }
|
||||
def clone
|
||||
self
|
||||
end
|
||||
|
||||
# Note: Failed CriticalMethodsNoRuntimeTypingTest
|
||||
sig {returns(SerializedVal).checked(:never)}
|
||||
sig { returns(SerializedVal).checked(:never) }
|
||||
def serialize
|
||||
assert_bound!
|
||||
@serialized_val
|
||||
end
|
||||
|
||||
sig {params(args: T.untyped).returns(T.untyped)}
|
||||
sig { params(args: T.untyped).returns(T.untyped) }
|
||||
def to_json(*args)
|
||||
serialize.to_json(*args)
|
||||
end
|
||||
|
||||
sig {params(args: T.untyped).returns(T.untyped)}
|
||||
sig { params(args: T.untyped).returns(T.untyped) }
|
||||
def as_json(*args)
|
||||
serialized_val = serialize
|
||||
return serialized_val unless serialized_val.respond_to?(:as_json)
|
||||
serialized_val.as_json(*args)
|
||||
end
|
||||
|
||||
sig {returns(String)}
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
inspect
|
||||
end
|
||||
|
||||
sig {returns(String)}
|
||||
sig { returns(String) }
|
||||
def inspect
|
||||
"#<#{self.class.name}::#{@const_name || '__UNINITIALIZED__'}>"
|
||||
end
|
||||
|
||||
sig {params(other: BasicObject).returns(T.nilable(Integer))}
|
||||
sig { params(other: BasicObject).returns(T.nilable(Integer)) }
|
||||
def <=>(other)
|
||||
case other
|
||||
when self.class
|
||||
@ -192,7 +192,7 @@ class T::Enum
|
||||
# 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
|
||||
T::Sig::WithoutRuntime.sig {returns(String)}
|
||||
T::Sig::WithoutRuntime.sig { returns(String) }
|
||||
def to_str
|
||||
msg = 'Implicit conversion of Enum instances to strings is not allowed. Call #serialize instead.'
|
||||
if T::Configuration.legacy_t_enum_migration_mode?
|
||||
@ -200,7 +200,7 @@ class T::Enum
|
||||
msg,
|
||||
storytime: {
|
||||
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
|
||||
@ -217,12 +217,12 @@ class T::Enum
|
||||
if T.unsafe(false)
|
||||
# Declare to the type system that the `serialize` method for sure exists
|
||||
# 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
|
||||
end
|
||||
|
||||
# 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)
|
||||
case other
|
||||
when String
|
||||
@ -238,7 +238,7 @@ class T::Enum
|
||||
end
|
||||
|
||||
# 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)
|
||||
case other
|
||||
when String
|
||||
@ -255,7 +255,7 @@ class T::Enum
|
||||
|
||||
# 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.)
|
||||
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)
|
||||
T::Configuration.soft_assert_handler(
|
||||
'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_class: other.class.name,
|
||||
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
|
||||
@ -276,7 +276,7 @@ class T::Enum
|
||||
UNSET = T.let(Module.new.freeze, Module)
|
||||
private_constant :UNSET
|
||||
|
||||
sig {params(serialized_val: SerializedVal).void}
|
||||
sig { params(serialized_val: SerializedVal).void }
|
||||
def initialize(serialized_val=UNSET)
|
||||
raise 'T::Enum is abstract' if self.class == T::Enum
|
||||
if !self.class.started_initializing?
|
||||
@ -292,7 +292,7 @@ class T::Enum
|
||||
self.class._register_instance(self)
|
||||
end
|
||||
|
||||
sig {returns(NilClass).checked(:never)}
|
||||
sig { returns(NilClass).checked(:never) }
|
||||
private def assert_bound!
|
||||
if @const_name.nil?
|
||||
raise "Attempting to access Enum value on #{self.class} before it has been initialized." \
|
||||
@ -300,14 +300,14 @@ class T::Enum
|
||||
end
|
||||
end
|
||||
|
||||
sig {params(const_name: Symbol).void}
|
||||
sig { params(const_name: Symbol).void }
|
||||
def _bind_name(const_name)
|
||||
@const_name = const_name
|
||||
@serialized_val = const_to_serialized_val(const_name) if @serialized_val.equal?(UNSET)
|
||||
freeze
|
||||
end
|
||||
|
||||
sig {params(const_name: Symbol).returns(String)}
|
||||
sig { params(const_name: Symbol).returns(String) }
|
||||
private def const_to_serialized_val(const_name)
|
||||
# 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
|
||||
@ -315,7 +315,7 @@ class T::Enum
|
||||
-const_name.to_s.downcase.freeze
|
||||
end
|
||||
|
||||
sig {returns(T::Boolean)}
|
||||
sig { returns(T::Boolean) }
|
||||
def self.started_initializing?
|
||||
unless defined?(@started_initializing)
|
||||
@started_initializing = T.let(false, T.nilable(T::Boolean))
|
||||
@ -323,7 +323,7 @@ class T::Enum
|
||||
T.must(@started_initializing)
|
||||
end
|
||||
|
||||
sig {returns(T::Boolean)}
|
||||
sig { returns(T::Boolean) }
|
||||
def self.fully_initialized?
|
||||
unless defined?(@fully_initialized)
|
||||
@fully_initialized = T.let(false, T.nilable(T::Boolean))
|
||||
@ -332,7 +332,7 @@ class T::Enum
|
||||
end
|
||||
|
||||
# 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)
|
||||
@values ||= []
|
||||
@values << T.cast(instance, T.attached_class)
|
||||
@ -340,7 +340,7 @@ class T::Enum
|
||||
|
||||
# Entrypoint for allowing people to register new enum values.
|
||||
# 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)
|
||||
raise "enums cannot be defined for T::Enum" if self == T::Enum
|
||||
raise "Enum #{self} was already initialized" if fully_initialized?
|
||||
@ -375,13 +375,13 @@ class T::Enum
|
||||
|
||||
orphaned_instances = T.must(@values) - @mapping.values
|
||||
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
|
||||
|
||||
@fully_initialized = true
|
||||
end
|
||||
|
||||
sig {params(child_class: T::Class[T.anything]).void}
|
||||
sig { params(child_class: T::Class[T.anything]).void }
|
||||
def self.inherited(child_class)
|
||||
super
|
||||
|
||||
@ -394,12 +394,12 @@ class T::Enum
|
||||
end
|
||||
|
||||
# Marshal support
|
||||
sig {params(_level: Integer).returns(String)}
|
||||
sig { params(_level: Integer).returns(String) }
|
||||
def _dump(_level)
|
||||
Marshal.dump(serialize)
|
||||
end
|
||||
|
||||
sig {params(args: String).returns(T.attached_class)}
|
||||
sig { params(args: String).returns(T.attached_class) }
|
||||
def self._load(args)
|
||||
deserialize(Marshal.load(args)) # rubocop:disable Security/MarshalLoad
|
||||
end
|
@ -4,7 +4,7 @@
|
||||
module T::NonForcingConstants
|
||||
# NOTE: This method is documented on the RBI in Sorbet's payload, so that it
|
||||
# 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)
|
||||
method_name = "T::NonForcingConstants.non_forcing_is_a?"
|
||||
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
|
||||
# cleaner with a single table.
|
||||
# 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
|
||||
# enabling final checks for when those hooks are called. the 'hooks' here don't have anything to do with the '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
|
||||
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"
|
||||
if caller_loc
|
||||
extra_info = (is_redefined ? "Redefined" : "Overridden") + " here: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
||||
@ -471,7 +471,7 @@ module T::Private::Methods
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
# 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)
|
||||
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.
|
||||
private_class_method def self.method_owner_and_name_to_key(owner, name)
|
||||
"#{owner.object_id}##{name}"
|
@ -12,7 +12,7 @@ module T::Private::Methods::CallValidation
|
||||
# @param method_sig [T::Private::Methods::Signature]
|
||||
# @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)
|
||||
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
|
||||
create_abstract_wrapper(mod, method_sig, original_method, original_visibility)
|
||||
# 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)
|
||||
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)
|
||||
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_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
|
||||
)
|
||||
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
|
||||
|
||||
if T::Configuration::AT_LEAST_RUBY_2_7
|
@ -154,7 +154,12 @@ module T::Private::Methods
|
||||
case decl.mode
|
||||
when Modes.standard
|
||||
decl.mode = Modes.override
|
||||
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
|
||||
raise BuilderError.new(".override cannot be repeated in a single signature")
|
||||
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] == "="
|
||||
# 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
|
||||
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
|
||||
param_names = parameters.map {|_, name| name}
|
||||
param_names = parameters.map { |_, name| name }
|
||||
missing_names = param_names - raw_arg_types.keys
|
||||
raise "The declaration for `#{method.name}` is missing parameter(s): #{missing_names.join(', ')}"
|
||||
elsif parameters.length != raw_arg_types.size
|
||||
param_names = parameters.map {|_, name| name}
|
||||
has_extra_names = parameters.count {|_, name| raw_arg_types.key?(name)} < raw_arg_types.size
|
||||
param_names = parameters.map { |_, name| name }
|
||||
has_extra_names = parameters.count { |_, name| raw_arg_types.key?(name) } < raw_arg_types.size
|
||||
if has_extra_names
|
||||
extra_names = raw_arg_types.keys - param_names
|
||||
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
|
||||
# whether the culprit is the Ruby reordering or user error, so
|
||||
# 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 " \
|
||||
"arguments. If your method declaration matches your `def`, try reordering any " \
|
||||
"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 " \
|
||||
"#{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
|
||||
|
||||
type = T::Utils.coerce(raw_type)
|
||||
@ -245,8 +245,8 @@ class T::Private::Methods::Signature
|
||||
end
|
||||
|
||||
def force_type_init
|
||||
@arg_types.each {|_, type| type.build_type}
|
||||
@kwarg_types.each {|_, type| type.build_type}
|
||||
@arg_types.each { |_, type| type.build_type }
|
||||
@kwarg_types.each { |_, type| type.build_type }
|
||||
@block_type&.build_type
|
||||
@rest_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
|
||||
# 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
|
||||
else
|
||||
# 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_shape(signature, super_signature)
|
||||
validate_override_types(signature, super_signature)
|
||||
validate_override_visibility(signature, super_signature)
|
||||
end
|
||||
else
|
||||
validate_non_override_mode(signature)
|
||||
@ -175,7 +176,7 @@ module T::Private::Methods::SignatureValidation
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
method_name = signature.method_name
|
||||
@ -231,7 +232,7 @@ module T::Private::Methods::SignatureValidation
|
||||
end
|
||||
|
||||
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 unless [signature, super_signature].all? do |sig|
|
||||
sig.check_level == :always || (sig.check_level == :tests && T::Private::RuntimeLevels.check_tests?)
|
||||
@ -276,6 +277,38 @@ module T::Private::Methods::SignatureValidation
|
||||
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)
|
||||
mode_noun = super_signature.mode == Modes.abstract ? 'Implementation' : 'Override'
|
||||
"\n * Base definition: in #{method_loc_str(super_signature.method)}" \
|
@ -5,7 +5,7 @@ module T::Private
|
||||
module MixesInClassMethods
|
||||
def included(other)
|
||||
mods = Abstract::Data.get(self, :class_methods_mixins)
|
||||
mods.each {|mod| other.extend(mod)}
|
||||
mods.each { |mod| other.extend(mod) }
|
||||
super
|
||||
end
|
||||
end
|
@ -32,7 +32,7 @@ module T::Private::RuntimeLevels
|
||||
def self.enable_checking_in_tests
|
||||
if !@check_tests && @wrapped_tests_with_validation
|
||||
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. " \
|
||||
"There are already some methods wrapped with `sig.checked(:tests)`:\n" \
|
||||
"- #{locations}"
|
@ -5,7 +5,7 @@ module T::Private::Sealed
|
||||
module NoInherit
|
||||
def inherited(child)
|
||||
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')
|
||||
@sorbet_sealed_module_all_subclasses << child
|
||||
end
|
||||
@ -22,14 +22,14 @@ module T::Private::Sealed
|
||||
module NoIncludeExtend
|
||||
def included(child)
|
||||
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')
|
||||
@sorbet_sealed_module_all_subclasses << child
|
||||
end
|
||||
|
||||
def extended(child)
|
||||
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')
|
||||
@sorbet_sealed_module_all_subclasses << child
|
||||
end
|
||||
@ -81,7 +81,7 @@ module T::Private::Sealed
|
||||
|
||||
if !this_file.start_with?(decl_file)
|
||||
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
|
||||
end
|
||||
|
@ -109,7 +109,7 @@ module T::Props
|
||||
# form.
|
||||
#
|
||||
# @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)
|
||||
cls = T::Utils.coerce(cls) if !cls.is_a?(Module)
|
||||
decorator.prop_defined(name, cls, rules)
|
||||
@ -132,7 +132,7 @@ module T::Props
|
||||
end
|
||||
|
||||
# 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)
|
||||
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")
|
@ -15,7 +15,7 @@ module T::Props::Constructor::DecoratorMethods
|
||||
# we'll use to check for any unrecognized input.)
|
||||
#
|
||||
# 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)
|
||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||
# and therefore allocates for each entry.
|
@ -39,7 +39,7 @@ module T::Props
|
||||
#
|
||||
# @param [Object] instance
|
||||
# @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
|
||||
|
||||
# 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
|
||||
# @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
|
||||
|
||||
sig {override.params(_base: Module).void}
|
||||
sig { override.params(_base: Module).void }
|
||||
def self.included(_base)
|
||||
super
|
||||
|
||||
raise 'Please use "extend", not "include" to attach this module'
|
||||
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)
|
||||
# We don't need to check for val's included modules in
|
||||
# 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
|
||||
# hashes; Custom hash types should be implemented via an emebdded
|
||||
# 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)
|
||||
case val
|
||||
when Array
|
@ -10,17 +10,17 @@
|
||||
class T::Props::Decorator
|
||||
extend T::Sig
|
||||
|
||||
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
|
||||
PropType = T.type_alias {T::Types::Base}
|
||||
PropTypeOrClass = T.type_alias {T.any(PropType, Module)}
|
||||
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
|
||||
PropType = T.type_alias { T::Types::Base }
|
||||
PropTypeOrClass = T.type_alias { T.any(PropType, Module) }
|
||||
|
||||
class NoRulesError < StandardError; end
|
||||
|
||||
EMPTY_PROPS = T.let({}.freeze, T::Hash[Symbol, Rules], checked: false)
|
||||
private_constant :EMPTY_PROPS
|
||||
|
||||
sig {params(klass: T.untyped).void.checked(:never)}
|
||||
sig { params(klass: T.untyped).void.checked(:never) }
|
||||
def initialize(klass)
|
||||
@class = T.let(klass, T.all(Module, T::Props::ClassMethods))
|
||||
@class.plugins.each do |mod|
|
||||
@ -30,22 +30,22 @@ class T::Props::Decorator
|
||||
end
|
||||
|
||||
# checked(:never) - O(prop accesses)
|
||||
sig {returns(T::Hash[Symbol, Rules]).checked(:never)}
|
||||
sig { returns(T::Hash[Symbol, Rules]).checked(:never) }
|
||||
attr_reader :props
|
||||
|
||||
sig {returns(T::Array[Symbol])}
|
||||
sig { returns(T::Array[Symbol]) }
|
||||
def all_props
|
||||
props.keys
|
||||
end
|
||||
|
||||
# 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)
|
||||
props[prop.to_sym] || raise("No such prop: #{prop.inspect}")
|
||||
end
|
||||
|
||||
# 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)
|
||||
override = rules.delete(:override)
|
||||
|
||||
@ -79,16 +79,16 @@ class T::Props::Decorator
|
||||
extra
|
||||
setter_validate
|
||||
_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
|
||||
|
||||
sig {params(key: Symbol).returns(T::Boolean).checked(:never)}
|
||||
sig { params(key: Symbol).returns(T::Boolean).checked(:never) }
|
||||
def valid_rule_key?(key)
|
||||
!!VALID_RULE_KEYS[key]
|
||||
end
|
||||
|
||||
# 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
|
||||
@class
|
||||
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.
|
||||
#
|
||||
# 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)
|
||||
prop_rules(prop).fetch(:value_validate_proc).call(val)
|
||||
end
|
||||
@ -202,7 +202,7 @@ class T::Props::Decorator
|
||||
end
|
||||
|
||||
# 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
|
||||
sig do
|
||||
@ -223,7 +223,7 @@ class T::Props::Decorator
|
||||
"to 'sensitivity:' (in prop #{@class.name}.#{name})")
|
||||
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}")
|
||||
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)
|
||||
|
||||
# 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)
|
||||
if !name.match?(SAFE_NAME)
|
||||
raise ArgumentError.new("Invalid prop name in #{@class.name}: #{name}")
|
||||
@ -255,7 +255,7 @@ class T::Props::Decorator
|
||||
end
|
||||
|
||||
# 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)
|
||||
case type
|
||||
when T::Types::TypedArray, T::Types::FixedArray
|
||||
@ -392,7 +392,7 @@ class T::Props::Decorator
|
||||
end
|
||||
|
||||
# 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)
|
||||
T::Configuration.without_ruby_warnings do
|
||||
if !rules[:immutable]
|
||||
@ -440,7 +440,7 @@ class T::Props::Decorator
|
||||
end
|
||||
|
||||
# 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)
|
||||
if rules[:sensitivity].nil?
|
||||
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,
|
||||
# prepended, or inherited.
|
||||
sig {params(child: Module).void.checked(:never)}
|
||||
sig { params(child: Module).void.checked(:never) }
|
||||
def model_inherited(child)
|
||||
child.extend(T::Props::ClassMethods)
|
||||
child = T.cast(child, T.all(Module, T::Props::ClassMethods))
|
||||
@ -656,19 +656,19 @@ class T::Props::Decorator
|
||||
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)
|
||||
!!(child.decorator.method(:prop_get).owner != method(:prop_get).owner &&
|
||||
child.instance_method(prop).source_location&.first == __FILE__)
|
||||
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)
|
||||
!!(child.decorator.method(:prop_set).owner != method(:prop_set).owner &&
|
||||
child.instance_method("#{prop}=").source_location&.first == __FILE__)
|
||||
end
|
||||
|
||||
sig {params(mod: Module).void.checked(:never)}
|
||||
sig { params(mod: Module).void.checked(:never) }
|
||||
def plugin(mod)
|
||||
decorated_class.plugins << mod
|
||||
T::Props::Plugin::Private.apply_class_methods(mod, decorated_class)
|
@ -159,7 +159,7 @@ module T::Props
|
||||
assert_equal(:resbody, rescue_body.type)
|
||||
exceptions, assignment, handler = rescue_body.children
|
||||
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([:e], assignment.children)
|
||||
|
||||
@ -169,7 +169,7 @@ module T::Props
|
||||
receiver, method, *args = deserialization_error.children
|
||||
assert_equal(nil, receiver)
|
||||
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)
|
||||
else
|
||||
@ -222,12 +222,12 @@ module T::Props
|
||||
# Primitives & self are ok
|
||||
when :lvar, :arg, :ivar
|
||||
# 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}")
|
||||
end
|
||||
when :args, :mlhs, :block, :begin, :if
|
||||
# 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
|
||||
# Sends are riskier so check a whitelist
|
||||
receiver, method, *args = node.children
|
@ -30,12 +30,12 @@ module T::Props
|
||||
#
|
||||
# Note it does _not_ prevent explicit calls to `eagerly_define_lazy_methods!`
|
||||
# from working.
|
||||
sig {void}
|
||||
sig { void }
|
||||
def self.disable_lazy_evaluation!
|
||||
@lazy_evaluation_disabled ||= true
|
||||
end
|
||||
|
||||
sig {returns(T::Boolean)}
|
||||
sig { returns(T::Boolean) }
|
||||
def self.lazy_evaluation_enabled?
|
||||
!defined?(@lazy_evaluation_disabled) || !@lazy_evaluation_disabled
|
||||
end
|
||||
@ -43,17 +43,17 @@ module T::Props
|
||||
module DecoratorMethods
|
||||
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
|
||||
@lazily_defined_methods ||= {}
|
||||
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
|
||||
@lazily_defined_vm_methods ||= {}
|
||||
end
|
||||
|
||||
sig {params(name: Symbol).void}
|
||||
sig { params(name: Symbol).void }
|
||||
private def eval_lazily_defined_method!(name)
|
||||
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
||||
raise SourceEvaluationDisabled.new
|
||||
@ -68,7 +68,7 @@ module T::Props
|
||||
cls.send(:private, name)
|
||||
end
|
||||
|
||||
sig {params(name: Symbol).void}
|
||||
sig { params(name: Symbol).void }
|
||||
private def eval_lazily_defined_vm_method!(name)
|
||||
if !HasLazilySpecializedMethods.lazy_evaluation_enabled?
|
||||
raise SourceEvaluationDisabled.new
|
||||
@ -80,7 +80,7 @@ module T::Props
|
||||
cls.send(:private, name)
|
||||
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)
|
||||
lazily_defined_methods[name] = blk
|
||||
|
||||
@ -100,7 +100,7 @@ module T::Props
|
||||
cls.send(:private, name)
|
||||
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)
|
||||
lazily_defined_vm_methods[name] = blk
|
||||
|
||||
@ -115,7 +115,7 @@ module T::Props
|
||||
cls.send(:private, name)
|
||||
end
|
||||
|
||||
sig {void}
|
||||
sig { void }
|
||||
def eagerly_define_lazy_methods!
|
||||
return if lazily_defined_methods.empty?
|
||||
|
||||
@ -125,18 +125,18 @@ module T::Props
|
||||
|
||||
cls = decorated_class
|
||||
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
|
||||
end
|
||||
|
||||
sig {void}
|
||||
sig { void }
|
||||
def eagerly_define_lazy_vm_methods!
|
||||
return if lazily_defined_vm_methods.empty?
|
||||
|
||||
lazily_defined_vm_methods.values.map(&:call)
|
||||
|
||||
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
|
||||
end
|
||||
end
|
@ -43,11 +43,11 @@ module T::Props::Optional::DecoratorMethods
|
||||
end
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
def add_prop_definition(prop, rules)
|
@ -49,21 +49,21 @@ module T::Props::PrettyPrintable
|
||||
module DecoratorMethods
|
||||
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)
|
||||
super || key == :inspect
|
||||
end
|
||||
|
||||
# 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
|
||||
sig {params(instance: T::Props::PrettyPrintable).returns(String)}
|
||||
sig { params(instance: T::Props::PrettyPrintable).returns(String) }
|
||||
def inspect_class_with_decoration(instance)
|
||||
T.unsafe(instance).class.to_s
|
||||
end
|
||||
|
||||
# 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`
|
||||
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
|
||||
end
|
||||
end
|
@ -9,28 +9,28 @@ module T::Props
|
||||
abstract!
|
||||
|
||||
# checked(:never) - O(object construction x prop count)
|
||||
sig {returns(SetterFactory::SetterProc).checked(:never)}
|
||||
sig { returns(SetterFactory::SetterProc).checked(:never) }
|
||||
attr_reader :setter_proc
|
||||
|
||||
# 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)
|
||||
@accessor_key = T.let(accessor_key, Symbol)
|
||||
@setter_proc = T.let(setter_proc, SetterFactory::SetterProc)
|
||||
end
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
NO_CLONE_TYPES = T.let([TrueClass, FalseClass, NilClass, Symbol, Numeric, T::Enum].freeze, T::Array[Module])
|
||||
|
||||
# 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)
|
||||
accessor_key = rules.fetch(:accessor_key)
|
||||
setter = rules.fetch(:setter_proc)
|
||||
@ -67,7 +67,7 @@ module T::Props
|
||||
abstract!
|
||||
|
||||
# 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)
|
||||
# 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.
|
||||
@ -80,7 +80,7 @@ module T::Props
|
||||
end
|
||||
|
||||
# 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)
|
||||
instance.instance_variable_set(@accessor_key, default)
|
||||
end
|
||||
@ -88,13 +88,13 @@ module T::Props
|
||||
|
||||
class ApplyPrimitiveDefault < ApplyFixedDefault
|
||||
# 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
|
||||
end
|
||||
|
||||
class ApplyComplexDefault < ApplyFixedDefault
|
||||
# checked(:never) - O(object construction x prop count)
|
||||
sig {override.returns(T.untyped).checked(:never)}
|
||||
sig { override.returns(T.untyped).checked(:never) }
|
||||
def default
|
||||
T::Props::Utils.deep_clone_object(@default)
|
||||
end
|
||||
@ -105,13 +105,13 @@ module T::Props
|
||||
# `some_empty_array.dup`
|
||||
class ApplyEmptyArrayDefault < ApplyDefault
|
||||
# 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)
|
||||
instance.instance_variable_set(@accessor_key, [])
|
||||
end
|
||||
|
||||
# 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
|
||||
[]
|
||||
end
|
||||
@ -122,13 +122,13 @@ module T::Props
|
||||
# `some_empty_hash.dup`
|
||||
class ApplyEmptyHashDefault < ApplyDefault
|
||||
# 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)
|
||||
instance.instance_variable_set(@accessor_key, {})
|
||||
end
|
||||
|
||||
# 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
|
||||
{}
|
||||
end
|
||||
@ -153,7 +153,7 @@ module T::Props
|
||||
end
|
||||
|
||||
# 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)
|
||||
# Use the actual setter to validate the factory returns a legitimate
|
||||
# value every time
|
||||
@ -161,7 +161,7 @@ module T::Props
|
||||
end
|
||||
|
||||
# checked(:never) - O(object construction x prop count)
|
||||
sig {override.returns(T.untyped).checked(:never)}
|
||||
sig { override.returns(T.untyped).checked(:never) }
|
||||
def default
|
||||
@class.class_exec(&@factory)
|
||||
end
|
@ -29,7 +29,7 @@ module T::Props
|
||||
.checked(:never)
|
||||
end
|
||||
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|
|
||||
# All of these strings should already be validated (directly or
|
||||
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
@ -10,7 +10,7 @@ module T::Props
|
||||
private_constant :Serialize
|
||||
class Deserialize; end
|
||||
private_constant :Deserialize
|
||||
ModeType = T.type_alias {T.any(Serialize, Deserialize)}
|
||||
ModeType = T.type_alias { T.any(Serialize, Deserialize) }
|
||||
private_constant :ModeType
|
||||
|
||||
module Mode
|
||||
@ -63,7 +63,7 @@ module T::Props
|
||||
end
|
||||
when T::Types::Simple
|
||||
raw = type.raw_type
|
||||
if NO_TRANSFORM_TYPES.any? {|cls| raw <= cls}
|
||||
if NO_TRANSFORM_TYPES.any? { |cls| raw <= cls }
|
||||
nil
|
||||
elsif raw <= Float
|
||||
case mode
|
||||
@ -99,7 +99,7 @@ module T::Props
|
||||
else
|
||||
"#{varname}.nil? ? nil : #{inner}"
|
||||
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
|
||||
nil
|
||||
else
|
||||
@ -122,8 +122,8 @@ module T::Props
|
||||
# NB: This deliberately does include `nil`, which means we know we
|
||||
# don't need to do any transforming.
|
||||
inner_known = type.types
|
||||
.map {|t| generate(t, mode, varname)}
|
||||
.reject {|t| t == dynamic_fallback}
|
||||
.map { |t| generate(t, mode, varname) }
|
||||
.reject { |t| t == dynamic_fallback }
|
||||
.uniq
|
||||
|
||||
if inner_known.size != 1
|
||||
@ -151,7 +151,7 @@ module T::Props
|
||||
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)
|
||||
case mode
|
||||
when Serialize
|
||||
@ -164,7 +164,7 @@ module T::Props
|
||||
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)
|
||||
case mode
|
||||
when Serialize
|
||||
@ -177,7 +177,7 @@ module T::Props
|
||||
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)
|
||||
T::Configuration.module_name_mangler.call(type)
|
||||
end
|
@ -24,7 +24,7 @@ module T::Props
|
||||
.checked(:never)
|
||||
end
|
||||
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|
|
||||
# All of these strings should already be validated (directly or
|
||||
# indirectly) in `validate_prop_name`, so we don't bother with a nice
|
@ -6,9 +6,9 @@ module T::Props
|
||||
module SetterFactory
|
||||
extend T::Sig
|
||||
|
||||
SetterProc = 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}
|
||||
SetterProc = 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 }
|
||||
|
||||
sig do
|
||||
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}"
|
||||
|
||||
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
|
||||
pretty_message += "Caller: #{caller_loc.path}:#{caller_loc.lineno}\n"
|
||||
end
|
@ -78,7 +78,7 @@ module T::Props::Serializable
|
||||
|
||||
if hash.size > hash_keys_matching_props
|
||||
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;
|
||||
# historically, we just ignore those
|
||||
@ -111,7 +111,7 @@ module T::Props::Serializable
|
||||
new_obj[k.to_s] = recursive_stringify_keys(v)
|
||||
end
|
||||
elsif obj.is_a?(Array)
|
||||
new_obj = obj.map {|v| recursive_stringify_keys(v)}
|
||||
new_obj = obj.map { |v| recursive_stringify_keys(v) }
|
||||
else
|
||||
new_obj = obj
|
||||
end
|
||||
@ -126,7 +126,7 @@ module T::Props::Serializable
|
||||
if old_extra != new_extra
|
||||
difference =
|
||||
if old_extra
|
||||
new_extra.reject {|k, v| old_extra[k] == v}
|
||||
new_extra.reject { |k, v| old_extra[k] == v }
|
||||
else
|
||||
new_extra
|
||||
end
|
||||
@ -195,7 +195,7 @@ module T::Props::Serializable::DecoratorMethods
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def prop_dont_store?(prop)
|
||||
@ -228,11 +228,11 @@ module T::Props::Serializable::DecoratorMethods
|
||||
res = super
|
||||
prop_by_serialized_forms[serialized_form] = prop
|
||||
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_deserialize) {generate_deserialize2}
|
||||
enqueue_lazy_vm_method_definition!(:__t_props_generated_serialize) { generate_serialize2 }
|
||||
enqueue_lazy_vm_method_definition!(:__t_props_generated_deserialize) { generate_deserialize2 }
|
||||
else
|
||||
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_serialize) { generate_serialize_source }
|
||||
enqueue_lazy_method_definition!(:__t_props_generated_deserialize) { generate_deserialize_source }
|
||||
end
|
||||
res
|
||||
end
|
||||
@ -263,7 +263,7 @@ module T::Props::Serializable::DecoratorMethods
|
||||
def message_with_generated_source_context(error, generated_method, generate_source_method)
|
||||
generated_method = generated_method.to_s
|
||||
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
|
||||
|
||||
line_num = line_loc.lineno
|
||||
@ -275,7 +275,7 @@ module T::Props::Serializable::DecoratorMethods
|
||||
# in `__t_props_generated_serialize'"
|
||||
"in `#{generated_method}'"
|
||||
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
|
||||
|
||||
line_num = if line_label.start_with?("(eval)")
|
@ -11,7 +11,7 @@ module T::Props::TypeValidation
|
||||
module DecoratorMethods
|
||||
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)
|
||||
super || key == :DEPRECATED_underspecified_type
|
||||
end
|
||||
@ -58,19 +58,19 @@ module T::Props::TypeValidation
|
||||
# If the type is fully valid, returns nil.
|
||||
#
|
||||
# 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)
|
||||
case type
|
||||
when T::Types::TypedEnumerable
|
||||
find_invalid_subtype(type.type)
|
||||
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
|
||||
# `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
|
||||
# `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
|
||||
invalid.first
|
||||
else
|
@ -13,7 +13,7 @@ module T::Props::Utils
|
||||
when Symbol, NilClass, Numeric
|
||||
what
|
||||
when Array
|
||||
what.map {|v| deep_clone_object(v, freeze: freeze)}
|
||||
what.map { |v| deep_clone_object(v, freeze: freeze) }
|
||||
when Hash
|
||||
h = what.class.new
|
||||
what.each do |k, v|
|
@ -6,7 +6,7 @@ module T::Props::WeakConstructor
|
||||
extend T::Sig
|
||||
|
||||
# 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={})
|
||||
decorator = self.class.decorator
|
||||
|
||||
@ -28,7 +28,7 @@ module T::Props::WeakConstructor::DecoratorMethods
|
||||
# we'll use to check for any unrecognized input.)
|
||||
#
|
||||
# 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)
|
||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||
# and therefore allocates for each entry.
|
||||
@ -49,7 +49,7 @@ module T::Props::WeakConstructor::DecoratorMethods
|
||||
# we'll use to check for any unrecognized input.)
|
||||
#
|
||||
# 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)
|
||||
# Use `each_pair` rather than `count` because, as of Ruby 2.6, the latter delegates to Enumerator
|
||||
# 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
|
||||
# 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
|
||||
|
||||
$VERBOSE = original_verbose
|
||||
@ -23,7 +23,7 @@ module T::Sig
|
||||
# Declares a method with type signatures and/or
|
||||
# abstract/override/... helpers. See the documentation URL on
|
||||
# {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)
|
||||
T::Private::Methods.declare_sig(self, Kernel.caller_locations(1, 1)&.first, arg0, &blk)
|
||||
end
|
@ -30,7 +30,7 @@ class T::ImmutableStruct < T::InexactStruct
|
||||
end
|
||||
|
||||
# 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={})
|
||||
super
|
||||
|
||||
@ -38,7 +38,7 @@ class T::ImmutableStruct < T::InexactStruct
|
||||
end
|
||||
|
||||
# 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)
|
||||
return super if (cls.is_a?(Hash) && cls[:immutable]) || rules[:immutable]
|
||||
|
@ -83,27 +83,27 @@ module T::Types
|
||||
# Note: order of cases here matters!
|
||||
if t1.is_a?(T::Types::Union) # 7, 8, 9
|
||||
# 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
|
||||
|
||||
if t2.is_a?(T::Types::Intersection) # 2, 5
|
||||
# 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
|
||||
|
||||
if t2.is_a?(T::Types::Union)
|
||||
if t1.is_a?(T::Types::Intersection) # 6
|
||||
# dropping either of parts eagerly make subtype test be too strict.
|
||||
# we have to try both cases, when we normally try only one
|
||||
return t2.types.any? {|t2_member| t1.subtype_of?(t2_member)} ||
|
||||
t1.types.any? {|t1_member| t1_member.subtype_of?(t2)}
|
||||
return t2.types.any? { |t2_member| t1.subtype_of?(t2_member) } ||
|
||||
t1.types.any? { |t1_member| t1_member.subtype_of?(t2) }
|
||||
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
|
||||
|
||||
if t1.is_a?(T::Types::Intersection) # 4
|
||||
# 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
|
||||
|
||||
# 1; Start with some special cases
|
@ -11,7 +11,7 @@ module T::Types
|
||||
end
|
||||
|
||||
def types
|
||||
@types ||= @inner_types.map {|type| T::Utils.coerce(type)}
|
||||
@types ||= @inner_types.map { |type| T::Utils.coerce(type) }
|
||||
end
|
||||
|
||||
def build_type
|
@ -10,7 +10,7 @@ module T::Types
|
||||
end
|
||||
|
||||
def types
|
||||
@types ||= @inner_types.transform_values {|v| T::Utils.coerce(v)}
|
||||
@types ||= @inner_types.transform_values { |v| T::Utils.coerce(v) }
|
||||
end
|
||||
|
||||
def build_type
|
||||
@ -26,16 +26,16 @@ module T::Types
|
||||
# overrides Base
|
||||
def recursively_valid?(obj)
|
||||
return false unless obj.is_a?(Hash)
|
||||
return false if types.any? {|key, type| !type.recursively_valid?(obj[key])}
|
||||
return false if obj.any? {|key, _| !types[key]}
|
||||
return false if types.any? { |key, type| !type.recursively_valid?(obj[key]) }
|
||||
return false if obj.any? { |key, _| !types[key] }
|
||||
true
|
||||
end
|
||||
|
||||
# overrides Base
|
||||
def valid?(obj)
|
||||
return false unless obj.is_a?(Hash)
|
||||
return false if types.any? {|key, type| !type.valid?(obj[key])}
|
||||
return false if obj.any? {|key, _| !types[key]}
|
||||
return false if types.any? { |key, type| !type.valid?(obj[key]) }
|
||||
return false if obj.any? { |key, _| !types[key] }
|
||||
true
|
||||
end
|
||||
|
||||
@ -48,7 +48,7 @@ module T::Types
|
||||
when TypedHash
|
||||
# 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?
|
||||
T::Types::Union::Private::Pool.union_of_types(key1, key2, keys_rest)
|
||||
elsif key1.nil?
|
@ -32,12 +32,12 @@ module T::Types
|
||||
|
||||
# overrides Base
|
||||
def recursively_valid?(obj)
|
||||
types.all? {|type| type.recursively_valid?(obj)}
|
||||
types.all? { |type| type.recursively_valid?(obj) }
|
||||
end
|
||||
|
||||
# overrides Base
|
||||
def valid?(obj)
|
||||
types.all? {|type| type.valid?(obj)}
|
||||
types.all? { |type| type.valid?(obj) }
|
||||
end
|
||||
|
||||
# overrides Base
|
@ -44,11 +44,11 @@ module T::Types
|
||||
nilable = T::Utils.coerce(NilClass)
|
||||
trueclass = T::Utils.coerce(TrueClass)
|
||||
falseclass = T::Utils.coerce(FalseClass)
|
||||
if types.any? {|t| t == nilable}
|
||||
remaining_types = types.reject {|t| t == nilable}
|
||||
if types.any? { |t| t == nilable }
|
||||
remaining_types = types.reject { |t| t == nilable }
|
||||
"T.nilable(#{type_shortcuts(remaining_types)})"
|
||||
elsif types.any? {|t| t == trueclass} && types.any? {|t| t == falseclass}
|
||||
remaining_types = types.reject {|t| t == trueclass || t == falseclass}
|
||||
elsif types.any? { |t| t == trueclass } && types.any? { |t| t == falseclass }
|
||||
remaining_types = types.reject { |t| t == trueclass || t == falseclass }
|
||||
type_shortcuts([T::Private::Types::StringHolder.new("T::Boolean")] + remaining_types)
|
||||
else
|
||||
names = types.map(&:name).compact.sort
|
||||
@ -58,12 +58,12 @@ module T::Types
|
||||
|
||||
# overrides Base
|
||||
def recursively_valid?(obj)
|
||||
types.any? {|type| type.recursively_valid?(obj)}
|
||||
types.any? { |type| type.recursively_valid?(obj) }
|
||||
end
|
||||
|
||||
# overrides Base
|
||||
def valid?(obj)
|
||||
types.any? {|type| type.valid?(obj)}
|
||||
types.any? { |type| type.valid?(obj) }
|
||||
end
|
||||
|
||||
# overrides Base
|
||||
@ -72,7 +72,7 @@ module T::Types
|
||||
end
|
||||
|
||||
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
|
||||
case non_nil_types.length
|
||||
when 0 then nil
|
Loading…
x
Reference in New Issue
Block a user